Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Кубик-рубик


@!!ex ©   (2008-01-11 11:07:00) 

Задача реализовать кубик рубик...
Вопрос в том, как его лучше хранить и как вращать его части...
Пока ничего умнее вот такого:
Cube:array[0..3,0..3,0..5] of byte;
не придумал...
Но тогда вращение нужно реализовывать для 24!(6 сторон, на каждой по 4 вращения) случаев... и каждое отдельно... что мне не очень нравится..


Sha   (2008-01-15 14:52:00) [1]

Сорри, скопипастил объяление :-(
   В последнем случае должно быть TRubik = array[0..19] of byte;


Sha   (2008-01-15 14:49:00) [2]

> @!!ex ©   (11.01.08 11:07)  
> Вопрос в том, как его лучше хранить и как вращать его части...

   Надо сначала определиться, что для тебя значит "лучше" .

   Если надо, чтобы было как можно меньше процедур вращения, то выбираешь 2 противоположных вершины куба и нумеруешь квадратики на каждой грани куба по часовой стрелке от 0 до 7, начиная с квадратика, содержащего вершину.
   Центральный квадратик нумеровать не обязательно, т.к. при вращениях крест не меняет своего положения.
   Объявляешь
TRubik = array[0..1] of array[0..2] of array[0..7] of byte;
или
TRubik = array[0..5] of array[0..7] of byte;
или
TRubik = array[0..1] of array[0..2] of integer;
или даже
TRubik = array[0..5] of integer;
и вперед.
   Вроде должно быть достаточно написать всего 2 процедуры: одну для вращения по часовой стрелке, другую - против.

   Если надо, чтобы процедуры вращения были простыми быстрыми, то
заметь, что в каждой вершине куба может находиться один из 8 различных миникубов-вершин и в каждом ребре - один из 12 различных миникубов-ребер.
   При этом миникуб-вершина может иметь одну из трех возможных ориентаций: правильную, когда его минимальный цвет лежит на грани с минимальным цветом центрального квдратика, или неправильную (повернут на 120 или 240 градусов по часовой стрелке).
   Аналогично, миникуб-ребро может иметь одну из двух возможных ориентаций: правильную, когда его минимальный цвет лежит на грани с минимальным цветом центрального квдратика, или неправильную (повернут на 180 градусов).
   Объявляешь
TRubik = array[0..19] of array[0..7] of byte;
и вперед.
   Потребуется написать 12 процедур: 6 для вращения по часовой стрелке, и 6 - против. Но он того стоит.


KilkennyCat   (2008-01-11 21:46:00) [3]

кстати, могу дать еще головоломную подсказку - кубик можно развернуть на плоскость.


KilkennyCat   (2008-01-11 21:45:00) [4]

а, Рамиль так же предложил, не заметил.


KilkennyCat   (2008-01-11 21:43:00) [5]


> @!!ex ©   (11.01.08 21:32) [14]


берем одну плоскость b[0]
ее вращение - это вращение матрицы а[0..2, 0..2]
к b[0] примыкают b[1], b[2], b[3], b[4]
значит, делаем обмен между их матрицами по первому столбу.

Вся фишка в прописывании каким образом что к чему прилегает. Алгоритм ваще-то максимум часа на четыре работы.

Предлагаю конкурс: кто напишет за эти выходные наиболее простой алгоритм вращения кубика.


@!!ex   (2008-01-11 21:32:00) [6]

> [13] KilkennyCat ©   (11.01.08 20:39)

А вращать как?


KilkennyCat   (2008-01-11 20:39:00) [7]

a : array [0..2, 0..2] of TColor - плоскость
b : array [0..5] of a - все плоскости

Неизящно, но тупо и просто.


Sandman25   (2008-01-11 17:13:00) [8]

@!!ex ©   (11.01.08 13:59) [7]

Центр куба имеет координаты (0,0,0); Верхняя грань - z=1, нижняя грань  - z=-1; левая грань - x=-1; правая грань - x=1; дальняя грань - y=-1, ближняя грань - y=1. Соответственно, нпаример левый дальний угол верхней грани имеет координаты (-1,-1,1). Имеем корординаты 9 красных точек, 9 синих точек и т.д., всего 6 цветов. Повороты будут сводиться к неким линейным преобразованиям координат.
Хотя, возможно, лучше эту же идею использовать для хранения в виде обычного массива, но с координатами [-1..1,-1..1,-1..1], за счет симметрии можно будет уменьшить число вариантов.


@!!ex   (2008-01-11 17:09:00) [9]

> описывающая тип кубика (одно-, двух- или трехцветный) и
> его поворот относительно наблюдателя.

Ууу. гемор.. особенно с поворотом относительно наблюдателя... хотя тоже вариант...


DrPass   (2008-01-11 16:52:00) [10]

Каждый элемент массива [0..2,0..2,0..2] - запись, описывающая тип кубика (одно-, двух- или трехцветный) и его поворот относительно наблюдателя. При повороте грани меняешь в массиве положение кубиков, и пересчитываешь поворот в записи. Этой информации будет достаточно для построения изображения


@!!ex   (2008-01-11 16:43:00) [11]

> Rotate, с двумя входными параметрами: индексом одного из
> 9-ти кубиков, которые надо повернуть, и направление вращения?

Да я все никак не пойму как сделать... Уже весь мозг сломал...


Dib@zol   (2008-01-11 16:06:00) [12]

А почему бы не прописать процедуру, скажем, Rotate, с двумя входными параметрами: индексом одного из 9-ти кубиков, которые надо повернуть, и направление вращения? И 24 случая отдельно расписывать не придётся. Максимум три.


@!!ex   (2008-01-11 13:59:00) [13]

> в виде трехмерной фигуры из 9 точек 6 цветов

Как это?


Sandman25   (2008-01-11 13:50:00) [14]

Можно хранить в виде трехмерной фигуры из 9 точек 6 цветов, тогда все повороты сводятся к стандартным.


@!!ex   (2008-01-11 11:31:00) [15]

> [1] DVM ©   (11.01.08 11:18)

0..2 естственно.


> [4] Рамиль ©   (11.01.08 11:23)

Не понял...
Объясни подробнее?


Рамиль   (2008-01-11 11:23:00) [16]

TCube = array[0..5, 0..2, 0..2] of TColor;
при вращении траспонируем матрицу 0..2, 0..2 соот. стороны и перекидываем ряды за гранью (или как точнее сказать то).
Навскидку както так.


DVM   (2008-01-11 11:22:00) [17]


> и прекрасно описывается массивом [0..2,0..2,0..2]

Причем даже с большим избытком.


DrPass   (2008-01-11 11:20:00) [18]


> Cube:array[0..3,0..3,0..5] of byte

Мне всегда казалось, что кубик Рубика состоит из 26 элементов, и прекрасно описывается массивом [0..2,0..2,0..2] :)


DVM   (2008-01-11 11:18:00) [19]


> Cube:array[0..3,0..3,0..5] of byte;

какой же это кубик?


Наверх

Титульная страница Поиск, карта сайта Написать письмо