Решил переосмыслить оригинальную идею Александра В. Катапанга младшего (Alexander V. Catapang Jr.), реализованную в шахматном тренажёре «Guess-Chess» из пакета логических игр «eGames» (1997-й год). Получившуюся программу вначале обозвал «Загадочные шахматы» («Riddle chess»), но поскольку не ограничивается только индийскими шахматами, и есть дополнительно тайские макрук (makruk), китайские сянци (xiangqi) и японские сёги (shogi) — стала «Генератором загадок» («Divine generator»).
Игра заключается в угадывании расположения фигур на доске, исходя из количества обозначенных угроз на клетках. В оригинальной версии поддерживаются только классические шахматы. При этом фигуры изначально располагаются на доске, могут конфликтовать и являться препятствиями, что несколько затрудняет разгадку.
Вот задача из оригинальной версии, запускающейся в операционных системах (оболочках ДОС) Windows 3.x:



Все фигуры в задачах являются условно серыми, не белыми и не чёрными. Соответственно убираем те, ход которых зависит от цвета. А именно пешка в шахматах; пешка или ракушка (биа) и слон (кхон) в макрук; пешка в сянци; пешка, токин, копьё, конь, серебряный генерал, золотой генерал в сёги. Заодно убираем также и ту, которой необходима для взятия другая фигура как трамплин, это пушка в сянци. В результате в шахматах, сянци и сёги оказывается по 5, а в макрук 4 действующих фигур.
Были созданы таблицы: 8 × 8 для шахмат и макрук, 9 × 10 для сянци и 9 × 9 для сёги; в которых первая, левая верхняя клетка, получила обозначение в 100, а каждая последующая прибавляла по единице.




Ставим главную фигуру в центр, и подкрашиваем те № полей, откуда доступны угрозы. В данных таблицах красным обозначены кони, зелёным — слоны, синим — ладьи (туры), ферзи совмещают ходы двух последних. Таблицы для шахмат и макрук отличаются только отсутствием слонов, в сёги отсутствуют кони, ходы остальных фигур в целом соответствуют. А вот для сянци, в виду ограничений королей (генералов) и советников крепостями, а слонов реками, и заодно особенностями ходов — алгротим размещает короля (генерала) и советника, ходы которого не обозначены, в разные крепости. Совпадения на клетках и взаимные угрозы главных фигур для простоты принимаем за значения от 0 до 10. После высчитывания разницы между обозначенными клетками и клеткой расположения главной фигуры получается результат:
|
Шахматы |
Макрук |
Сянци |
Сёги |
|
0 |
0 |
0 |
0 |
|
1 |
1 |
1 |
1 |
|
2 |
2 |
2 |
2 |
|
3 |
3 |
3 |
3 |
|
4 |
4 |
4 |
4 |
|
5 |
5 |
5 |
5 |
|
6 |
6 |
6 |
6 |
|
7 |
7 |
7 |
7 |
|
8 |
8 |
8 |
8 |
|
9 |
9 |
9 |
9 |
|
10 |
10 |
10 |
10 |
|
|
|
11 |
11 |
|
14 |
14 |
|
|
|
15 |
15 |
|
|
|
16 |
16 |
16 |
16 |
|
17 |
17 |
17 |
17 |
|
18 |
18 |
18 |
18 |
|
|
|
19 |
19 |
|
|
|
20 |
20 |
|
21 |
21 |
|
|
|
24 |
24 |
24 |
24 |
|
27 |
27 |
27 |
27 |
|
28 |
28 |
|
|
|
|
|
30 |
30 |
|
32 |
32 |
32 |
32 |
|
35 |
35 |
|
|
|
36 |
36 |
36 |
36 |
|
40 |
40 |
40 |
40 |
|
42 |
42 |
|
|
|
45 |
45 |
45 |
45 |
|
48 |
48 |
48 |
48 |
|
49 |
49 |
|
|
|
|
|
50 |
50 |
|
54 |
54 |
54 |
54 |
|
56 |
56 |
56 |
56 |
|
|
|
60 |
60 |
|
63 |
63 |
63 |
63 |
|
|
|
64 |
64 |
|
|
|
70 |
70 |
|
|
|
72 |
72 |
|
|
|
80 |
80 |
|
|
|
81 |
|
Ранний Бейсик, в отличии от современных диалектов, является языком программирования для не являющихся программистами, например инженеров. Далее привожу часть кода, легко адаптируемого к другим видам, для обычных шахмат:
' Объявляем все переменные целыми числами. DefInt A-Z ' Запускаем зависимость генератора случайных чисел от системного времени. Randomize Timer ' Создаём двумерный массив шахматной доски с № клеток. Dim Shared chebo(8, 8) As Integer Let index = 100 For row = 1 To 8: For col = 1 To 8 Let chebo(row, col) = index + 1 Let index = index + 1 ' Создаём одномерный массив со списком угрожающих значений и заполняем значениями. Dim dif(31) Let dif(1) = 0 Let dif(2) = 1 Let dif(3) = 2 Let dif(4) = 3 Let dif(5) = 4 Let dif(6) = 5 Let dif(7) = 6 Let dif(8) = 7 Let dif(9) = 8 Let dif(10) = 9 Let dif(11) = 10 Let dif(12) = 14 Let dif(13) = 15 Let dif(14) = 16 Let dif(15) = 17 Let dif(16) = 18 Let dif(17) = 21 Let dif(18) = 24 Let dif(19) = 27 Let dif(20) = 28 Let dif(21) = 32 Let dif(23) = 35 Let dif(23) = 36 Let dif(24) = 40 Let dif(25) = 42 Let dif(26) = 45 Let dif(27) = 48 Let dif(28) = 49 Let dif(29) = 54 Let dif(30) = 56 Let dif(31) = 63 Next col: Next row ' Генерируем расположение 1-й фигуры (короля) по координатам X и Y. Let dc1x = Int(Rnd * 8 + 1) Let dc1y = Int(Rnd * 8 + 1) ' Получаем № клетки исходя из получившегося расположения 1-й фигуры. Let f1 = chebo(dc1x, dc1y) ' Ставим метку начала генерации. chessgenerate: ' Генерируем расположение 2-й фигуры (ферзя) по координатам X и Y. Let dc2x = Int(Rnd * 8 + 1) Let dc2y = Int(Rnd * 8 + 1) ' Получаем № клетки исходя из получившегося расположения 2-й фигуры. Let f2 = chebo(dc2x, dc2y) ' Проверяем конфликтность между 1-й и 2-й фигурами: For index = 1 To 31 If Abs(f1 - f2) = dif(index) Then GoTo chessgenerate Next index ' Генерируем расположение 3-й фигуры (слона) по координатам X и Y. Let dc3x = Int(Rnd * 8 + 1) Let dc3y = Int(Rnd * 8 + 1) ' Получаем № клетки исходя из получившегося расположения 3-й фигуры. Let f3 = chebo(dc3x, dc3y) ' Проверяем конфликтность между 1-й и 3-й, 2-й и 3-й фигурами: For index = 1 To 31 If Abs(f1 - f3) = dif(index) Then GoTo chessgenerate If Abs(f2 - f3) = dif(index) Then GoTo chessgenerate Next index ' Генерируем расположение 4-й фигуры (коня) по координатам X и Y. Let dc4x = Int(Rnd * 8 + 1) Let dc4y = Int(Rnd * 8 + 1) ' Получаем № клетки исходя из получившегося расположения 4-й фигуры. Let f4 = chebo(dc4x, dc4y) ' Проверяем конфликтность между 1-й и 4-й, 2-й и 4-й, 3-й и 4-й фигурами: For index = 1 To 31 If Abs(f1 - f4) = dif(index) Then GoTo chessgenerate If Abs(f2 - f4) = dif(index) Then GoTo chessgenerate If Abs(f3 - f4) = dif(index) Then GoTo chessgenerate Next index ' Генерируем расположение 5-й фигуры (ладьи) по координатам X и Y. Let dc5x = Int(Rnd * 8 + 1) Let dc5y = Int(Rnd * 8 + 1) ' Получаем № клетки исходя из получившегося расположения 5-й фигуры. Let f5 = chebo(dc5x, dc5y) ' Проверяем конфликтность между 1-й и 5-й, 2-й и 5-й, 3-й и 5-й, 4-й и 5-й фигурами: For index = 1 To 31 If Abs(f1 - f5) = dif(index) Then GoTo chessgenerate If Abs(f2 - f5) = dif(index) Then GoTo chessgenerate If Abs(f3 - f5) = dif(index) Then GoTo chessgenerate If Abs(f4 - f5) = dif(index) Then GoTo chessgenerate Next index ' Контрольная проверка на отсутствие конфликтов между всеми фигурами. For index = 1 To 31 If Abs(f1 - f2) = dif(index) Then GoTo chessgenerate If Abs(f1 - f3) = dif(index) Then GoTo chessgenerate If Abs(f1 - f4) = dif(index) Then GoTo chessgenerate If Abs(f1 - f5) = dif(index) Then GoTo chessgenerate If Abs(f2 - f3) = dif(index) Then GoTo chessgenerate If Abs(f2 - f4) = dif(index) Then GoTo chessgenerate If Abs(f2 - f5) = dif(index) Then GoTo chessgenerate If Abs(f3 - f4) = dif(index) Then GoTo chessgenerate If Abs(f3 - f5) = dif(index) Then GoTo chessgenerate If Abs(f4 - f5) = dif(index) Then GoTo chessgenerate Next index
В общем получаем универсальный ряд из 42 чисел для всех четырёх разновидностей шахмат: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 21, 20, 24, 27, 28, 30, 32, 35, 36, 40, 42, 45, 48, 49, 50, 54, 56, 60, 63, 64, 70, 72, 80, 81.
' Записываем ряд из 42 чисел. Data 0,1,2,3,4,5,6,7,8,9,10,11,14,15,16,17,18,19,21,20,24,27,28,30,32,35,36,40,42,45,48,49,50,54,56,60,63,64,70,72,80,81 ' Объявляем массив соответствующего размера. Dim Shared dif(1 To 42) As Integer ' Заполняем значениями из ряда чисел. For index = 1 To 42 Read dif(index) Next index
Изначально максимальное количество угроз на клетку равняется количеству задействованных фигур. Однако после проверки на конфликтность становится меньше на 1 в макрук и сёги, на 2 в сянци, и лишь шахматы сохраняют 5 в крайне ограниченном количестве расстановок.
Исходный код: http://sf.net/projects/divgen/
Тематический сайт: http://truechess.org/
Спасибо за внимание!
ссылка на оригинал статьи https://habr.com/ru/post/720918/
Добавить комментарий