игра "пятнашки" !!!

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: игра "пятнашки" !!!

Сообщение ark » 07.10.2012 (Вс) 11:55

Qwertiy писал(а):ark, ты про меня не забыл
Неа, я с коллекцией борюсь - время выгадываю, но так, чтоб код не особо рос. Строки в 2 раза быстрее
Код: Выделить всё
  moves = Array(-1, 1, -4, 4)
Private Sub Shuffle(n)
  t = GetTickCount
  Dim X, Y, md, s As String
  For i = 1 To n
    XY emptyID - 1, X, Y, 1
    s = ""
    If (X > 0) And (md <> 1) Then s = s & 0
    If (X < 3) And (md <> -1) Then s = s & 1
    If (Y > 0) And (md <> 4) Then s = s & 2
    If (Y < 3) And (md <> -4) Then s = s & 3
    md = moves(Mid$(s, Int(Rnd * Len(s)) + 1, 1))
    curID = emptyID + md
    Swap
  Next
  Debug.Print GetTickCount - t
  For i = 1 To 16: PrintCell i: Next
End Sub

Массив с редимом такой же...

burik
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 514
Зарегистрирован: 03.11.2005 (Чт) 22:04
Откуда: Беларусь, Рогачев

Re: игра "пятнашки" !!!

Сообщение burik » 07.10.2012 (Вс) 13:07

ark писал(а):
burik писал(а):без перемешиваний в competition не принимают
Дело в том, что без перемешиваний возможна нерешаемая комбинация.

Угу, их там аж 50%. Но у меня всегда генерится решаемая. Дело в том, что есть мат. выражение, позволяющая определить является ли комбинация решаемой. Достаточно генерировать последовательность чисел, а потом (в зависимости от получившейся последовательности) вставить пустую клетку в правильное место, и комбинация получится решаемой.

P.S. См. http://mathworld.wolfram.com/15Puzzle.html.
Между слухов, сказок, мифов,
просто лжи, легенд сомнений
мы враждуем жарче скифов
за несходство заблуждений
Игорь Губерман

burik
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 514
Зарегистрирован: 03.11.2005 (Чт) 22:04
Откуда: Беларусь, Рогачев

Re: игра "пятнашки" !!!

Сообщение burik » 07.10.2012 (Вс) 13:13

Mikle писал(а):burik, понравилось это:
Код: Выделить всё
    pbGame.Scale (0, 0)-(4, 4)

Так, действительно, проще. Я, почему-то, сразу не допёр так сделать.
Не понравилось отсутствие Option Explicit. Да и вообще, код "тяжеловат".

Согласен, есть немного.

P.S. Давно я не писал на VB, совсем отвык - все на мог понять чего он на необъявленные переменные не ругается. :)

Qwertiy писал(а):Так у меня тоже Scale используется... С другой стороны, если всё считать в пикселях, то можно точно определять границы, благодаря чему не будет пересечения фишек и станет можно перерисовывать две, а не все.

У меня всегда отдна перерисовывается, вроде все ок.
Между слухов, сказок, мифов,
просто лжи, легенд сомнений
мы враждуем жарче скифов
за несходство заблуждений
Игорь Губерман

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: игра "пятнашки" !!!

Сообщение Mikle » 07.10.2012 (Вс) 13:30

Qwertiy писал(а):Я про то, что есть 16 возможных значений, тогда как возможных направлений только 4

У меня MoveBrick() - функция, которая ПЫТАЕТСЯ сдвинуть фишку с указанным индексом. Если двигать некуда - она не двигает. Соответственно по клику вызывается она же без всяких проверок.

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: игра "пятнашки" !!!

Сообщение ark » 09.10.2012 (Вт) 11:14

@burik - спасибо за ссылку! Не понял только, зачем ты в модуле столько нагородил? Вот - без перемешивания, быстро и короче ИМХО некуда :D
New_15.zip
(1.08 Кб) Скачиваний: 95

burik
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 514
Зарегистрирован: 03.11.2005 (Чт) 22:04
Откуда: Беларусь, Рогачев

Re: игра "пятнашки" !!!

Сообщение burik » 09.10.2012 (Вт) 19:27

Я не ставил целью минимизацию кода, да и оптимизацией совсем не занимался, просто написал "в лоб".
Объем кода сопоставим, если учесть разницу в стиле: у меня куча пустых строк, каждая переменная отдельно объявляется и т.д. У тебя же Dim emptyID, i, j, s As String и т.п..
А что касается самого алгоритма, так вы тут так спорили по поводу оптимизации перемешивания, что я хотел обойтись без него (в любом виде), а suffle - тоже мешает :)
Между слухов, сказок, мифов,
просто лжи, легенд сомнений
мы враждуем жарче скифов
за несходство заблуждений
Игорь Губерман

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: игра "пятнашки" !!!

Сообщение Mikle » 10.10.2012 (Ср) 9:06

burik
Тут вопрос не столько минимизации, сколько упрощения, наглядности, понятности без коментариев.
ark писал(а):Вот - без перемешивания, быстро и короче ИМХО некуда

Неплохо! Подумаю ещё об упрощении.

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: игра "пятнашки" !!!

Сообщение ark » 12.10.2012 (Пт) 8:30

burik писал(а):А что касается самого алгоритма, так вы тут так спорили по поводу оптимизации перемешивания, что я хотел обойтись без него (в любом виде), а suffle - тоже мешает
Если смущает название - можно назвать GenerateNew. :D Shuffle в данном случае мешает только один раз - т.е. заполняет массив случайными неповторяющимися числами от 1 до 16. Согласись, это проще и быстрее, чем Do...Loop внутри цикла, как у тебя, причем именно случайными (насколько Rnd может быть случаен), а не j+1 в случае повторения. Далее функция Solveable проверяет массив на "решаемость". На всякий случай алгоритм (может, я чего недопонял):
Согласно ссылки на теорию, задача решаема, если количество "инверсных" фишек и номер ряда пустой ячейки - парные (т.е. обе чёт или нечёт). Инверсными фишками считаются с номерами меньше заданной. Пример из ссылки: первая фишка - 13, т.е. далее идут 12 "инверсных" фишек (1-12). Следующая - 10, за ней 9 инверсных (1-9). Далее - 11 - опять 9 инверсных (десятка стоит раньше) и т.д. Всё делается в двойном цикле (заодно запоминаем номер пустой ячейки):
Код: Выделить всё
  emptyID = 16
  For i = 1 To 15
    For j = i + 1 To 16
      If cells(j) < cells(i) Then Solveable = Not Solveable
    Next
    If cells(i) = 16 Then emptyID = i
  Next
Сумма нам, в принципе, ни к чему, выжно лишь чёт/нечёт - потому прибавление единички заменил на логику - все быстрее, в итоге получаем нечёт == True, чёт == False. Если пустой ряд чётный (If (emptyID \ 4 Mod 2) = 0) - меняем True/False. Далее, если получаем False - достаточно переставить 2 любых непустых ячейки, чтобы изменить чётность. Усё. Итого - 16 операций на инициализацию + 16 перемешивание + 121 на Solveable + 1 если False. Остальное - антураж. Не знаю, может Swap через 3 XOR'а быстрее будет, чем присваивание, по размеру кода - одинаково :D

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: игра "пятнашки" !!!

Сообщение ark » 18.11.2012 (Вс) 9:01

Бонус :D
Сорри, лениво было на VB6 c UInt64 и LShift/RShift возиться, потому на VB.Net
PuzzleSolver.zip
(43.92 Кб) Скачиваний: 263

Пред.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 34

    TopList