![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Кубик-рубик
@!!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;
какой же это кубик?