Author Topic: Собираем кубик Рубика 3х3 кликерманом.  (Read 4517 times)

0 Members and 1 Guest are viewing this topic.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
На днях нашел у себя старый советский кубик рубика с детства  ;D, Радости было - словами не передать  ;D.

Примерно так я себе представлял свои возможности по сборке  8):


На деле это выглядело где-то так  :( :




Сломал себе мозг в итоге, и решил перенести алгоритм для сборки в кликерман. Кубик онлайн взял отсюда http://www.softholm.com/igra/kubik-rubika/3D-kubik-rubik.html (только там таймер немного тормознутый  :D).
Примерный алгоритм брал вот такой https://kak-sobrat-kubik-rubika-3x3.ru .

При написании все оказалось не так просто как я рассчитывал, но все работает, хоть и не сильно быстро.

Видео сборки - https://youtu.be/foHWvLXU1JQ - 3 мин. 50 сек.

Если кто-то знаком со сборкой более сложных кубов 4х4 или 5х5, или если у кого есть алгоритмы пошустрее - будет интересно вместе порешать  ;).

Код:
Code: (clickermann) [Select]
GETSCREEN
IF_PIXEL_IN(0,0, $_xmax,$_ymax, 16567729)
   $x_win = $_return1
   $y_win = $_return2
   print("окошко с кубиком найдено в координатах ",$_return1,"x", $_return2)
else
   print("окно не найдено")
   halt
END_IF

//выставляем по уровню
SUB(level)
   LDOWN($x_win + 35,$y_win + 326)
   waitms(50)
   LUP($x_win + 35,$y_win + 348)
   waitms(500)
   LDOWN($x_win + 369,$y_win + 574)
   waitms(50)
   LUP($x_win + 333,$y_win + 574)
END_SUB
//все видимые цвета
SUB(scan)
   GETSCREEN
   //up
   $sc[0] = pxl($x_win +395,$y_win +130)
   $sc[1] = pxl($x_win +469,$y_win +153)
   $sc[2] = pxl($x_win +566,$y_win +183)
   $sc[3] = pxl($x_win +326,$y_win +154)
   $sc[4] = pxl($x_win +400,$y_win +186)
   $sc[5] = pxl($x_win +497,$y_win +219)
   $sc[6] = pxl($x_win +239,$y_win +184)
   $sc[7] = pxl($x_win +316,$y_win +218)
   $sc[8] = pxl($x_win +410,$y_win +264)
   //front
   $sc[9] = pxl($x_win + 205,$y_win + 248)
   $sc[10] = pxl($x_win + 276,$y_win + 286)
   $sc[11] = pxl($x_win + 361,$y_win + 332)
   $sc[12] = pxl($x_win + 219,$y_win + 323)
   $sc[13] = pxl($x_win + 289,$y_win + 367)
   $sc[14] = pxl($x_win + 366,$y_win + 420)
   $sc[15] = pxl($x_win + 231,$y_win + 390)
   $sc[16] = pxl($x_win + 295,$y_win + 436)
   $sc[17] = pxl($x_win + 365,$y_win + 489)
   //right
   $sc[18] = pxl($x_win + 456,$y_win + 325)
   $sc[19] = pxl($x_win + 531,$y_win + 280)
   $sc[20] = pxl($x_win + 597,$y_win + 236)
   $sc[21] = pxl($x_win + 445,$y_win + 416)
   $sc[22] = pxl($x_win + 518,$y_win + 360)
   $sc[23] = pxl($x_win + 581,$y_win + 313)
   $sc[24] = pxl($x_win + 444,$y_win + 485)
   $sc[25] = pxl($x_win + 509,$y_win + 428)
   $sc[26] = pxl($x_win + 568,$y_win + 382)
   
   FOR($col=0,$col<27)
      SWITCH($sc[$col])
         CASE(6684723)
            $sc[$col] = 1    //ф
         CASE(16737792)
            $sc[$col] = 2    //c
         CASE(179)
            $sc[$col] = 3    //к
         CASE(18432)
            $sc[$col] = 4    //з
         CASE(15790320)
            $sc[$col] = 7    //б
         CASE(43733)
            $sc[$col] = 6    //ж
      END_SWITCH
   END_CYC
END_SUB


$wait = 500   //задержка после движений грани
//все варианты движений   граней
SUB(F1,$fb)
   IF($fb = 0)
      LDOWN($x_win + 447,$y_win + 325)
      waitms(50)
      LUP($x_win + 448,$y_win + 482)
   ELSE
      LDOWN($x_win + 448,$y_win + 482)
      waitms(50)
      LUP($x_win + 447,$y_win + 325)
   END_IF
   waitms($wait)
END_SUB

SUB(F2,$fb)
   IF($fb = 0)
      LDOWN($x_win + 536,$y_win + 273)
      waitms(50)
      LUP($x_win + 514,$y_win + 423)
   ELSE
      LDOWN($x_win + 514,$y_win + 423)
      waitms(50)
      LUP($x_win + 536,$y_win + 273)
   END_IF
   waitms($wait)
END_SUB


SUB(F3,$fb)
   IF($fb = 0)
      LDOWN($x_win + 596,$y_win + 232)
      waitms(50)
      LUP($x_win + 568,$y_win + 378)
   ELSE
      LDOWN($x_win + 568,$y_win + 378)
      waitms(50)
      LUP($x_win + 596,$y_win + 232)
   END_IF
   waitms($wait)
END_SUB


SUB(R1,$fb)
   IF($fb = 0)
      LDOWN($x_win + 374,$y_win + 495)
      waitms(50)
      LUP($x_win + 367,$y_win + 342)
   ELSE
      LDOWN($x_win + 367,$y_win + 342)
      waitms(50)
      LUP($x_win + 374,$y_win + 495)
   END_IF
   waitms($wait)
END_SUB


SUB(R2,$fb)
   IF($fb = 0)
      LDOWN($x_win + 295,$y_win + 431)
      waitms(50)
      LUP($x_win + 276,$y_win + 288)
   ELSE
      LDOWN($x_win + 276,$y_win + 288)
      waitms(50)
      LUP($x_win + 295,$y_win + 431)
   END_IF
   waitms($wait)
END_SUB

SUB(R3,$fb)
   IF($fb = 0)
      LDOWN($x_win + 237,$y_win + 387)
      waitms(50)
      LUP($x_win + 205,$y_win + 244)
   ELSE
      LDOWN($x_win + 205,$y_win + 244)
      waitms(50)
      LUP($x_win + 237,$y_win + 387)
   END_IF
   waitms($wait)
END_SUB

SUB(U1,$fb)
   IF($fb = 0)
      LDOWN($x_win + 379,$y_win + 337)
      waitms(50)
      LUP($x_win + 202,$y_win + 256)
   ELSE
      LDOWN($x_win + 202,$y_win + 256)
      waitms(50)
      LUP($x_win + 379,$y_win + 337)
   END_IF
   waitms($wait)
END_SUB

SUB(U2,$fb)
   IF($fb = 0)
      LDOWN($x_win + 594,$y_win + 307)
      waitms(50)
      LUP($x_win + 425,$y_win + 438)
   ELSE
      LDOWN($x_win + 425,$y_win + 438)
      waitms(50)
      LUP($x_win + 594,$y_win + 307)
   END_IF
   waitms($wait)
END_SUB

SUB(U3,$fb)
   IF($fb = 0)
      LDOWN($x_win + 583,$y_win + 369)
      waitms(50)
      LUP($x_win + 415,$y_win + 514)
   ELSE
      LDOWN($x_win + 415,$y_win + 514)
      waitms(50)
      LUP($x_win + 583,$y_win + 369)
   END_IF
   waitms($wait)
END_SUB

//небольшие комбинации
SUB(RURU)
   R1(1)
   U3(0)
   R1(0)
   U3(1)
END_SUB

SUB(shot)
   U1(0)
   R1(0)
   U1(1)
   R1(1)
   U1(1)
   F1(1)
   U1(0)
   F1(0)
END_SUB




//////////////

wait(1)
print("ровняем кубик")
level()
wait(1)




FOR($a=0,$a<3)
   scan()
   IF($sc[4] = 6)
      $a = 3
   ELSE
      F2(0)
   END_IF
END_CYC
FOR($a=0,$a<3)
   scan()
   IF($sc[4] = 6)
      $a = 3
   ELSE
      R2(0)
   END_IF
END_CYC

WHILE($sc[13] ! 1)
   U2(0)
   scan()
END_CYC
print("этап 1 - желтый крест на верхней грани")
FOR($kr=1,$kr<5)
   
   $temp = 0
   FOR($a=0,$a<4)
     
      IF(($sc[7]+$sc[10] = $kr+6)&($sc[7]*$sc[10] = $kr*6))
      ELSE
         IF(($sc[14]+$sc[21] = $kr+6)&($sc[14]*$sc[21] = $kr*6))
           
            R1(1)
            U3(0)
            FOR($back=0,$back<$a-1)
               R1(1)
            END_CYC
           
            FOR($back=0,$back<$temp)
               U1(1)
               U2(1)
            END_CYC
           
            F1(0)
            F1(0)
            $a = 4
           
         ELSE
            R1(0)
            IF($a = 3)
               
               U1(0)
               U2(0)
               U3(0)
               $a = -1
               inc($temp)
            END_IF
           
         END_IF
         
      END_IF
      scan()
   END_CYC
   
   scan()
   IF($sc[7] ! 6)
      F1(0)
      U1(1)
      R1(0)
      U1(0)
   END_IF
   
   U1(0)
   U2(0)
   U3(0)
   scan()
   
   
END_CYC

print("этап 2 - верхние углы на свои места")
FOR($kr=1,$kr<5)
   FOR($a=0,$a<4)
      scan()
      $kr1 = $kr+6+$kr+1
      $kr2 = $kr*6*($kr+1)
      IF($kr=4)
         $kr1 = $kr+7
         $kr2 = $kr*6
      END_IF
     
      IF(($sc[8]+$sc[11]+$sc[18]=$kr1)&($sc[8]*$sc[11]*$sc[18]=$kr2))
         
         IF($a > 0)
            RURU()
            FOR($back=0,$back<$a)
               U1(1)
               U2(1)
            END_CYC
            RURU()
         END_IF
         
         
         scan()
         
         WHILE($sc[8] ! 6)
            RURU()
            RURU()
            scan()
         END_CYC
         
         $a = 9
      ELSE
         U1(0)
         U2(0)
         IF($a = 3)
            WHILE((($sc[8]+$sc[11]+$sc[18]=$kr1)&($sc[8]*$sc[11]*$sc[18]=$kr2)) ! 1)
               U3(0)
               R1(0)
               scan()
               R1(1)
               
            END_CYC
            RURU()
            scan()
            $a = -1
         END_IF
      END_IF
      scan()
   END_CYC
   
   U1(0)
   U2(0)
   
END_CYC

print("переворачиваем кубик")
FOR($a=0,$a<2)
   R1(0)
   R2(0)
   R3(0)
END_CYC
U2(0)
U3(0)

print("этап 3 - ребра в среднем ряду")
FOR($kr=1,$kr<5)
   FOR($a=0,$a<4)
      scan()
      $kr1 = $kr+$kr+1
      $kr2 = $kr*($kr+1)
      IF($kr=4)
         $kr1 = $kr+1
         $kr2 = $kr
      END_IF
     
     
      IF(($sc[21] = $kr) & ($sc[14]+$sc[21]=$kr1)&($sc[14]*$sc[21]=$kr2))
         $a = 4
      else
         
         
         IF(($sc[7]+$sc[10]=$kr1)&($sc[7]*$sc[10]=$kr2))
            shot()
            IF($sc[21] ! $kr)
               $a = 2
            else
               $a = 4
            END_IF
           
         else
           
            U1(0)
            IF($a = 3)
               $temp = 0
               WHILE((($sc[14]+$sc[21]=$kr1)&($sc[14]*$sc[21]=$kr2)) ! 1)
                  U2(0)
                  U3(0)
                  inc($temp)
                  scan()
               END_CYC
               
               shot()
               
               FOR($back=0,$back<$temp)
                  U2(1)
                  U3(1)
               END_CYC
               $a= -1
            END_IF
         END_IF
      END_IF
     
   END_CYC
   U2(1)
   U3(1)
   
END_CYC

scan()

print("этап 4 - белый крест на верху")
WHILE(($sc[1]+$sc[3]+$sc[4]+$sc[5]+$sc[7]) ! 35)
   
   IF(($sc[1]+$sc[4]+$sc[7])=21)
      U1(0)
      WHILE(($sc[1]+$sc[3]+$sc[4]+$sc[5]+$sc[7]) ! 35)
         F1(0)
         R1(0)
         U1(0)
         R1(1)
         U1(1)
         F1(1)
         scan()
      END_CYC
   ELSE
      IF(($sc[1]+$sc[4]+$sc[5])=21)
         U1(1)
      ELSE
         IF(($sc[4]+$sc[5]+$sc[7])=21)
            U1(1)
            U1(1)
         ELSE
            IF(($sc[3]+$sc[4]+$sc[7])=21)
               U1(0)
            END_IF
         END_IF
      END_IF
      WHILE(($sc[1]+$sc[4]+$sc[7])!21)
         F1(0)
         R1(0)
         U1(0)
         R1(1)
         U1(1)
         F1(1)
         scan()
      END_CYC
     
   END_IF
   
   
END_CYC

print("этап 5 - верхние ребра на свои места")
scan()
$temp = 0
$temp2 = 0
WHILE(($sc[13] ! $sc[10]) | ($sc[19] ! $sc[22]))
   U1(0)
   U2(0)
   U3(0)
   inc($temp)
   IF($temp = 4)
      $temp = 0
      inc($temp2)
      U1(0)
   END_IF
   scan()
   
   IF($temp2 = 5)
      WHILE($sc[19] ! $sc[22])
         U1(0)
         U2(0)
         U3(0)
         inc($temp)
         IF($temp = 4)
            $temp = 0
            U1(0)
         END_IF
         scan()
         
      END_CYC
      R1(0)
      U1(0)
      R1(1)
      U1(0)
      R1(0)
      U1(0)
      U1(0)
      R1(1)
      $temp2 = 0
      scan()
   END_IF
   
   
END_CYC

U1(1)
U2(1)
U3(1)
scan()
IF(($sc[13] ! $sc[10]))
   R1(0)
   U1(0)
   R1(1)
   U1(0)
   R1(0)
   U1(0)
   U1(0)
   R1(1)
   U1(0)
END_IF


print("этап 6 - углы верхнего слоя на свои места")
scan()
$temp = 0
WHILE(($sc[8]*$sc[11]*$sc[18]) ! ($sc[4]*$sc[13]*$sc[22]) )
   U1(0)
   U2(0)
   U3(0)
   inc($temp)
   IF($temp = 4)
      $temp = 0
      U1(0)
      R1(0)
      U1(1)
      R3(0)
      U1(0)
      R1(1)
      U1(1)
      R3(1)
   END_IF
   scan()
END_CYC


U1(1)
U2(1)
U3(1)
scan()


IF(($sc[8]*$sc[11]*$sc[18]) ! ($sc[4]*$sc[13]*$sc[22]) )
   $mem = ($sc[8]*$sc[11]*$sc[18])
   U1(1)
   U2(1)
   U3(1)
   scan()
   IF($mem = ($sc[4]*$sc[13]*$sc[22]) )
      U1(1)
      U2(1)
      U3(1)
      U1(1)
      R3(0)
      U1(0)
      R1(0)
      U1(1)
      R3(1)
      U1(0)
      R1(1)
     
   else
      FOR($a=0,$a<2)
         U1(1)
         U2(1)
         U3(1)
      END_CYC
     
      U1(0)
      R1(0)
      U1(1)
      R3(0)
      U1(0)
      R1(1)
      U1(1)
      R3(1)
   END_IF
END_IF

print("этап 7 - разворачиваем углы как положено")
scan()
WHILE($sc[13] ! 3)
   U1(1)
   U2(1)
   U3(1)
   scan()
END_CYC


FOR($a=0,$a<4)
   WHILE($sc[8] ! 7)
      RURU()
      RURU()
      scan()
   END_CYC
   U1(0)
   scan()
END_CYC

print("готово")

halt

Кликерман сам определяет положение голубого окошка с кубиком на экране. Важно, чтобы его было видно целиком. А момент запуска и принцип действие видно в том же видео ролике  https://youtu.be/foHWvLXU1JQ
« Last Edit: November 15, 2018, 11:58:04 AM by dramster »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Собираем кубик Рубика 3х3 кликерманом.
« Reply #1 on: November 15, 2018, 02:18:35 PM »
 :-\
Возможно не сработал одно из перемещения, и далее чтото пошло не так. По началу у меня были такие сбои, подкорректировал координаты нажатий и отпусканий кнопки мышки и задержки, вроде сейчас проблемы исчезли.
Еще, как вариант, в какойто момент, задержки на перемещение грани оказалось мало (мало ли, глюк какой) - $wait = 500   //задержка после движений грани

Можно и разделить на отдельные этапы, не проблема... Но не факт, что при старте с какогото определенного этапа, сбой не был допущен где-то ранее.

Скрипт был написан еще вчера, и на моем ПК прошел с пару десятков удачных тестов. Да, замечено, он не идеален, и часто делает лишние движение, которые можно было бы пропустить. Но на конечный результат это не влияет.



Вечером постараюсь раскинуть на отдельно запускаеммые этапы
« Last Edit: November 15, 2018, 02:21:25 PM by dramster »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Собираем кубик Рубика 3х3 кликерманом.
« Reply #2 on: November 15, 2018, 06:37:17 PM »
как я понял стороны нумеруются в таком порядке.
Именно так. Все верно.

понял почему проворачивается кубик.
Если зажать клавишу не на кубике, а на  игровом поле  и переместить, то кубик вертится целиком, получается он теряет ориентацию в случаях промахов по кубику.
Но этот эффект можно использовать и для быстрого поворота всего кубика, например, когда собран первый цвет или чтоб сразу сканировать расположение всех цветов на кубике.

Кубик в самом начале выставляется как нужно level() и далее  стоит на месте. Можно конечно оптимизировать и ворочать его целиком, но мне показалось это уж очень сложно.

И еще, стартовать скрипт нужно именно из первоначального положения кубика (после нажатия кнопки "NORMAL" из главного меню ), либо самому выставить кубик чтоб все грани были одинакового размера с центром в центре (на видео видно) исключив выполнение level(). Чет не подумал, что могут быть затруднения при старте...  :( а это важно для дальнейшей работы.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Собираем кубик Рубика 3х3 кликерманом.
« Reply #3 on: November 16, 2018, 01:12:22 PM »
Неплохо оптимизировал. Особенно выключение зука  ;D . Сейчас не ошибется насчет выравнивания кубика. Ну и насчет остального, тоже все проще стало.

Первый запуск у меня зациклился на первом же этапе  :( . При детальном рассмотрении, заметил, что пп turn() у меня не срабатывала как положено, при обнулении задержки срабатывал только один твист. Убрал обнуления, и также убрал на вертикальном. Вроде пошла работа.
 :-\ и снова чето не то. Первое - ребра в среднем ряду стали в перевернутом состоянии. Второе - два угла в белой грани стали не на свои места. Я понимаю, что основной алгоритм ты вроде не менял, в чем ошибка я пока так и не понял.
Потестил еще, гдето ошибка на третьем этапе, не определяет что ребро стоит не верно

И еще, насчет моего варианта. Иногда (два раза за все испытания) выпадает такая комбинация, что белый крест не хочет собираться, в чем ошибка я также не понимаю :(. А не понимаю, так как не совсем понимаю в какое положение нужно ставить верхние белые кубики первоначально и после последующих выполнений комбинаций. Если вручную ворочить, то я просто наугад крутил верхний рад и выполнял комбинации пока не появится белый крест, а тут... хз.
« Last Edit: November 16, 2018, 01:30:58 PM by dramster »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Собираем кубик Рубика 3х3 кликерманом.
« Reply #4 on: November 16, 2018, 01:51:08 PM »
Нашел ошибку насчет ребер в среднем ряду. Ты с чегото вдруг добавил разворот по горизонту перед переварачиванием куба по вертикали. Убрал, заработало верно. Просто началное положение третьего этапа должно быть - синий/фиолетовый, а становилось чтото другое, не помню что.
Code: (clickermann) [Select]
///....
//........
   U1(0)
   U2(0)
END_CYC
 
U1($par11)  //этого не должно быть
U2($par11)
U3($par11)
 
 
 
print("переворачиваем кубик")
//$waitms= 0  // обнуление задержки
FOR($a=0,$a<2)
   R1(0)
   R2(0)
///....
//.........

, но даже с первым жёлтым случается.
С желтым не замечал, а с белым - только два раза было, поэтому не смог понять изза чего и как исправить  :-\.



Вот бы найти какой онлайн проект типа спидкубинга, где можно было бы проверить кликерман на прочность и скорость  ::) . Немного поискал, ничего толкового не нашел  :(.
С проффессионалами он конечно не сравнится с его примитивным алгоритмом, но любителей будет делать на ура  :D
« Last Edit: November 16, 2018, 01:59:31 PM by dramster »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Собираем кубик Рубика 3х3 кликерманом.
« Reply #5 on: November 16, 2018, 02:31:59 PM »
https://rubiks-cube-solver.com/ru/#
Как оно работает? Вот это я понимаю - алгоритм  ::).

Как бы я не перемешивал кубик, он высчитывает оптимальное решение за пару секунд, и оно не превышает 20 вращений  :o