Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > С/С++
Перезагрузить страницу Создание игры "Шахматы".
Ответ
 
Опции темы Опции просмотра
  (#16 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 04.12.2015, 22:38

Здравствуйте, уважаемые участники форума!

Я занимаюсь разработкой собственной шахматной программы. Хочу обсудить способы реализации алгоритмов, используемых в шахматных программах (материальная и позиционная оценка позиции, выбор сильнейшего хода (полный перебор на фиксированную глубину, альфа-бета отсечение, форсированный вариант), игра в дебюте и в элементарных окончаниях и др. Могу поделиться своими идеями.
Ответить с цитированием
  (#17 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 04.12.2015, 22:54

Вообще-то я математик, а не программист. "Прибамбасы" типа ООП, указателей, компьютерной графики и прочего высшего программистского пилотажа для меня абсолютно непостижимы. Моя программа предназначена для игры человека с компьютером и работает исключительно в консольном режиме: доску она рисует из звездочек, фигуры обозначает первыми буквами их английских названий (K -король, Q - ферзь и т. д.), а цвет фигуры - знаками "плюс" для белых и "минус" для черных (+K - белый король, -R - черная ладья и т. д.). Ходы нужно вводить нотацией (например, e2e4). Свои ходы программа также сообщает в нотации, но в более привычном виде (1. ... e7-e5).

Программа написана на современном Фортране (Compaq Visual Fortran), возможности которого не уступают Паскалю/Delphi и C/C++, а в ряде случаев даже превосходят их: очень высокая точность вычислений (до 10 в минус 25-й степени); свободная возможность вызова подпрограмм и функций независимо от того, выше или ниже текста соответствующей подпрограммы расположен оператор ее вызова; удобная конструкция выбора (select case), позволяющая указывать в одной ветви несколько значений критериального выражения и/или их диапазонов; рекурсивные функции и ряд других возможностей. Правда, сам компилятор Фортрана тоже консольный: для компиляции программы необходимо из-под Far'a (или другой файловой оболочки) запустить команду df <имя файла>. При отсутствии синтаксических ошибок исполнимый файл будет получен в течении нескольких секунд.

P. S. Фортран был самым распространенным языком программирования в эпоху моей молодости (80-е годы прошлого столетия), и я являюсь "фанаткой" этого языка программирования.
Ответить с цитированием
  (#18 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 04.12.2015, 23:11

Немного о уже реализованных алгоритмах моей программы.

Позицию я представляю как одномерный массив целых чисел с индексами от 11 до 88 (еще одно достоинство современного Фортрана - возможность начинать индексы массива не только с единицы (как было в Фортране IV и Фортране-77) или с нуля (как имеет место в современном Си). Десятки индекса соответствует букве горизонтали (точнее, ее порядковому номеру в латинском алфавите), а единицы - цифре вертикали поля (в частности, полю e2 соответствует индекс 52). Значение каждого элемента массива соответствует фигуре, стоящей на соответствующем поле, а именно:

ноль соответствует свободному полю;
положительное число соответствует белой фигуре, а отрицательное - черной;
абсолютная величина числа соответствует виду фигуры, а именно:

1-пешка, 2-король, 3-конь, 4-слон, 5-ладья, 6-ферзь

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

Правда, при такой кодировке массив позиции содержит 14 лишних элементов с индексами, последняя цифра которых - девятка или ноль (19, 20, 29, 30, ..., 79, 80). Все они заполняются нулями. "Поля" с девятками как бы находятся за пределами доски с верхней стороны, а с нулями - с нижней. Для отсечения возможностей ходов фигур на подобные поля я использую логическую функцию InBoard, которая принимает значение истина тогда и только тогда, когда обе цифры аргумента находятся в пределах от единицы до восьми.

Надо сказать, что "поля за пределами доски" оказались полезными для отсечения возможностей ходов фигур за пределы доски при составлении списка возможных ходов.
Ответить с цитированием
  (#19 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 04.12.2015, 23:55

Список возможных ходов одной из сторон в некоторой позиции (MoveList) строится следующим образом:

1. Описывается четыре одномерных целочисленных массива именованных констант, соответствующих лучам коня и дальнобойных фигур и характеризующих изменение номеров полей при ходах соответствующих фигур (для дальнобойных фигур - при самых коротких ходах):

Knight (8) = (/-21, -19, -12, -8, 8, 12, 19, 21/), &
Bishop (4) = (/-11, -9, 9, 11 /), &
Rook (4) = (/-10, - 1, 1, 10 /), &
Queen (8) = (/-11, -10, -9, -1, 1, 9, 10, 11/)

2. Описываются пять одномерных массивов размерности 109 (согласно согласно книге Е. Я. Гика "Шахматы и математика" (М., "Наука", 1983), именно таково максимальное количество возможных ходов одной стороны в позиции):

Move (целочисленный) - массив четырехзначных кодов ходов (первые две цифры соответствуют коду исходного поля фигуры, вторые - конечного). В частности, ходу e2-e4 соответствует код 5254. Изначально массив заполняется нулями.

Attribute (целочисленный) - массив атрибутов ходов, значения которых характеризуют особенности соответствующего хода:

0 - обычный ход; 1 - взятие на проходе; 2 - превращение пешки; 3 - короткая рокировка; 4 - длинная рокировка. Изначально массив заполняется нулями.

Capture (логический) - значение равно true для взятий и false для тихих ходов (начальное значение - false).

Agressor (целочисленный) - содержит абсолютные значения кодов фигур, которые совершают соответствующий ход (начальное значение - 0).

Victime (целочисленный) - для взятий содержит абсолютные значения кодов забираемых фигур, для тихих ходов - нули (начальное значение - 0).

Последние два массива были добавлены недавно для обеспечения последующей сортировки взятий и тихих ходов по алгоритму "Наиболее ценная жертва - наименее ценный нападающий".

3. Начальное значение счетчика количества ходов (скалярная целочисленная переменная N) устанавливается равным нулю.

4. Организуется цикл с параметром - номером поля, изменяющимся от 11 до 88.

5. Если поле расположено на доске и занято своей фигурой (произведение кода поля и значения цвета (+1 - белые, -1 - черные) положительно, то организуем выбор согласно коду поля:

1 (пешка):

а) просматриваем поле перед ней (Field + Color - легко убедиться, что для белых это будет поле, расположенное непосредственно выше пешки, а для черных - ниже). Если оно свободно (код 0), то связываем поле, на котором стоит пешка, и поле перед ней ходом (вызываем подпрограмму, которая записывает в массив Move код данного хода). Увеличиваем на единицу счетчик количества ходов.

Если при этом номер горизонтали конечного поля (остаток от деления его номера на 10) равен 8 для белых или 1 для черных (т. е. номер горизонтали конечного поля равен целой части суммы 4,5 и значения цвета, умноженного на 3,5), то ход пешки сопровождается ее превращением - значение соответствующего элемента массива атрибутов устанавливаем равным двум. Если же номер горизонтали начального поля равен двум для белых или семи для черных - еще раз увеличиваем номер конечного поля на значение цвета. Если новое конечное поле свободно - возможен ход пешки на два поля. Записываем его код в массив Move.
Ответить с цитированием
  (#20 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 05.12.2015, 00:19

б) если номер вертикали отличен от единицы, вычитаем из начального поля 10 и затем прибавляем значение цвета. Результат присваиваем конечному полю. Если оно занято фигурой соперника - возможно взятие. В массив Move записываем код хода, в массив Capture - истину, в массив Agressor - единицу, в массив Victime - абсолютную величину кода забираемой фигуры. Аналогично поступаем при номере вертикали, отличном от восьми (на этот раз для получения кода конечного поля прибавляем 10 к начальному полю и затем прибавляем значение цвета). В обоих случаях, если забираемая фигура стоит на восьмой (первой) горизонтали, атрибут хода равен двум.

в) и, наконец, взятие на проходе:

С этой целью в программе организована глобальная целочисленная переменная Last, помещенная в общую область Common. Значение этой переменной равно коду последнего сделанного хода и обновляется всякий раз, когда человек или компьютер делает ход.

Если выполнена конъюнкция трех условий:

1) на поле, код которого равен числу, образованному двумя последними цифрами текущего значения Last, стоит пешка соперника (т. е. значение поля равно -Color);
2) разность между начальным и конечным полями хода Last равно удвоенному значению цвета (это значит, что белая пешка увеличила на два значение своего поля или черная уменьшила, т. е. пешка сделала двойной шаг; не следует забывать, что значение цвета Color по сравнению с предшествующим ходом было заменено на противоположное);
3) абсолютная величина разности поля, на котором стоит наша пешка, и конечного поля Last, равна десяти (т. е. наша пешка стоит рядом с только что сделавшей ход пешкой соперника),

то возможно взятие на проходе. Соединяем ходом поле, на котором стоит наша пешка, и увеличенное на значение цвета поле, на котором стоит пешка соперника. Взятие - true, атрибут - единица, агрессор и жертвы - единицы.
Ответить с цитированием
Ads.
  (#21 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 05.12.2015, 00:28

2 (король):

а) организуем цикл с параметром Direction, изменяющимся от одного до восьми. Для каждого из восьми направлений, характеризующимися элементами массива Queen с индексом Direction, запускаем подпрограмму KingKnight, определяющую ходы недальнобойных фигур - коня и короля. Использование массива Queen связано с тем, что направления лучей короля совпадает с направлениями лучей ферзя, с той разницей, что король не обладает дальнобойностью.

б) если белый король стоит на e1, а черный на e8

IF (Field .EQ. INT (54.5 - 3.5 * Color))

,то вызываем подпрограмму, определяющую рокировки.

3 (конь)

Для каждого из восьми направлений массива Knight вызываем подпрограмму KingKnight.

Старая версия подпрограммы KingKnight (без использования массивов агрессоров и жертв) очень красива. Хочу полностью привести ее код.

SUBROUTINE KingKnight (Position, Color, N, Field, Direction, Move, Capture)

INTEGER Position (11 : 88), Color, Field, Feld, Figure, Direction
LOGICAL InBoard
PARAMETER (MaxMoves = 109)
INTEGER, DIMENSION (MaxMoves) :: Move
LOGICAL, DIMENSION (MaxMoves) :: Capture

Feld = Field + Direction
IF (.NOT. InBoard (Feld)) RETURN
Figure = Position (Feld) * Color
IF (Figure) 1, 2, 3
1 Capture (N + 1) = .TRUE.
2 CALL Bind (Field, Feld, N, Move)
3 RETURN

END SUBROUTINE KingKnight
Ответить с цитированием
  (#22 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 05.12.2015, 00:41

Код конечного поля равно сумме кодов исходного поля и направления. Если конечное поле за пределами доски - хода нет. В противном случае определяем код фигуры, стоящей на конечном поле, и умножаем этот код на значение цвета. Если произведение отрицательно, то на конечном поле стоит чужая фигура. Возможно взятие - записываем истину в массив Capture, связываем исходное и конечное поля ходом и возвращаемся. Если конечное поле пустое (произведение равно нулю) - возможен тихий ход. Связываем поля ходом и возвращаемся. Если на конечном поле стоит своя фигура (произведение положительно) - нет ни хода, ни взятия. Сразу возвращаемся.

После добавления агрессоров и жертв операторы с метками 1,2,3 уже не следуют непосредственно друг за другом.
Ответить с цитированием
  (#23 (permalink)) Старый
Мария Константиновна Мария Константиновна вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.12.2015
По умолчанию 05.12.2015, 00:50

4 (слон), 5 (ладья), 6 (ферзь)

Для каждого направления, соответствующего лучам данной фигуры, запускаем подпрограмму LongRange, определяющего ходы дальнобойных фигур. Без агрессоров и жертв код подпрограммы выглядит следующим образом:

SUBROUTINE LongRange (Position, Color, N, Field, Direction, Move, Capture)

INTEGER Position (11 : 88), Color, Field, Feld, Figure, Direction
LOGICAL InBoard
PARAMETER (MaxMoves = 109)
INTEGER, DIMENSION (MaxMoves) :: Move
LOGICAL, DIMENSION (MaxMoves) :: Capture

DO 4, Length = 1, 7
Feld = Field + Direction * Length
IF (.NOT. InBoard (Feld)) RETURN
Figure = Position (Feld) * Color
IF (Figure) 1, 3, 2
1 CALL Bind (Field, Feld, N, Move)
Capture (N) = .TRUE.
2 RETURN
3 CALL Bind (Field, Feld, N, Move)
4 END DO
RETURN

END SUBROUTINE LongRange

Длина хода дальнобойной фигуры по каждому направлению может быть от одного до семи. Начинаем с единицы. Прибавляем к исходному полю величину луча, умноженную на длину. Ушли за пределы доски - ходов по данному лучу больше нет. Иначе определяем фигуру, стоящую на конечном поле. Поле занято чужой фигурой - возможно взятие, но дальнейших ходов по лучу нет. Поле занято своей фигурой - ни на данное, ни на дальнейшие поля ходов больше нет. Поле свободно - возможен тихий ход, и необходимо исследовать дальнейшие поля.
Ответить с цитированием
  (#24 (permalink)) Старый
da-nie da-nie вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 15.03.2016
По умолчанию 15.03.2016, 22:28

Подниму тему.
Год назад я написал одну шахматную программу.
В архиве исходный код и версия для QNX и Windows (компилятор - VC6). Так же приложен самостоятельный движок - я назвал его Centurion. Уровень игры должен быть где-то КМС или около того.
Может быть, исходник поможет кому-нибудь написать простейшую программу.
Вложения
Тип файла: zip Chess.zip (1.03 Мб, 301 просмотров)
Ответить с цитированием
Ads
  (#25 (permalink)) Старый
Progermc Progermc вне форума
Новичок
 
Сообщений: 1
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 27.10.2016
По умолчанию 27.10.2016, 14:27

da-nie, а есть какая-то текстовая документация по Вашим шахматам или сохранились ли ссылки - источники информации.
Я надеюсь что мой вопрос не сильно наглый.. Вашу работу хочу изменить и использовать в качестве курсовой работы.
заранее спасибо
Ответить с цитированием
  (#26 (permalink)) Старый
da-nie da-nie вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 15.03.2016
По умолчанию 07.12.2016, 19:46

Можете взять книжку Е.Н. Корнилов "Программирование шахмат и других логических задач". Там почти всё есть.
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Зависание компа "намертво" при просмотре видео на youtube или во время игры Lokos Любые вопросы от новичков 8 10.03.2012 12:55
Ставлю систему "с нуля" после сбоя. Какие "работы" по тестированию железа полезны? russcand Любые вопросы от новичков 14 01.09.2011 00:27
Ошибка при авторизации игры онлайн "Поднебесье" myshkawww Вопросы начинающих программистов 3 11.03.2011 16:05
Создание игры "Эпилогика" St. Jimmy Prolog 9 19.05.2010 01:50
На ноутбуке "тормозят" игры даже при самых минимальных настройках. Микки Размикович Любые вопросы от новичков 2 25.03.2010 23:06
Закрываются игры, появляется ошибка: "0xbe8787ba" или "0x3e89ce89" . ASUSTeK Техническая поддержка 42 19.02.2009 01:38
При установке игры выскакивает ошибка данных "CRC" Дмитрий Техническая поддержка 5 13.04.2008 22:17
С чего начать разработку игры "Сокобан" IIITAK Вопросы начинающих программистов 0 08.01.2008 01:19
Исходник сетевой игры "крестики-нолики" yura_korepin Вопросы начинающих программистов 1 17.12.2007 22:05
Где найти алгоритм хода компьютера игры "Балда" N0RtAn Вопросы начинающих программистов 15 11.05.2005 13:05
Как сделать чтобы вместо кнопок "Да" и "Нет" высвечивалось украинсие "Так" и "Ні" Форсаж Delphi 5 19.07.2003 19:30
Создание программы на С++, "Структура данных и Алгоритм"" Curt Вопросы начинающих программистов 1 30.05.2003 12:17



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов