Главная страница «Первого сентября»Главная страница журнала «Информатика»Содержание №7/2009


В мир информатики
Games.exe

Компьютерная игра “Король на шахматной доске”

В этой статье мы опишем методику разработки программы, моделирующей игру “Король на шахматной доске” (см. анализ этой игры в данном выпуске в рубрике “Задачник”).

Напомним правила. Двое играют на шахматной доске, передвигая по очереди одного короля. Допускаются ходы на одно поле вниз, влево или по диагонали влево и вниз. Исходная позиция — правая верхняя клетка доски (если смотреть на доску сверху). Выигрывает тот, кому удастся поставить короля в левый нижний угол.

Основные этапы моделирования:

1. Формирование и вывод начальной позиции

2.

цикл

Очередной "ход"

Формирование новой позиции на доске

Вывод ее на экран

конец цикла при <король в левом

нижнем углу>

3. Определение результатов игры

Шахматную доску будем моделировать в виде двумерного массива из 8 строк и 8 столбцов, значением элементов которого будут символы “K” для элемента, соответствующего клетке с королем, и “ ” — соответствующего пустой клетке. Имя этого массива — доска.

Выводить этот массив на экран будем в виде, показанном на рис. 1 (цифры внизу обозначают номер столбца, цифры слева — номер строки).

Рис. 1

При выводе на экран начальной и последующих позиций следует учитывать, что массив выводится построчно, начиная с первой строки, в то время как мы пронумеровали строки так, как на рис. 1.

С учетом этого соответствующая процедура Вывод_позиции может быть оформлена в виде:

алг Вывод_позиции

нач цел i, j

|Выводим массив (а также номера строк

|и разделительные черточки)

вывод нс

нц для i от 1 до 8

вывод 8 - i + 1, " |"

нц для j от 1 до 8

вывод доска[i, j], " |"

кц

вывод нс

кц

|Выводим номера столбцов

|(и разделительные черточки)

вывод " "

нц для i от 1 до 7

вывод i, " |"

кц

вывод 8

кон

С использованием этой процедуры3 фрагмент программы, относящийся к этапу 1, может быть оформлен следующим образом:

|Моделируем пустую доску

нц для i от 1 до 8

нц для j от 1 до 8

доска[i, j]:= " "

кц

кц

|Учитываем начальное положение короля

доска[1, 8] := "К"

|Выводим начальную позицию на доске

Вывод_позиции

Перейдем теперь к обсуждению этапа 2.

Ход участников игры будем характеризовать направлением перемещения короля: если влево — числом 1, если вниз — 2, если по диагонали влево и вниз — 3. Примем для такого направления величину целого типа с именем куда. Значение этой величины человек будет вводить в программу, а компьютер — выбирать в соответствии с выигрышной стратегией, которую обсудим позже.

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

ходит := 1 Начинает компьютер

нц повторение ходов

если ходит = 1

то

Определение оптимального хода

Вывод его на экран

ходит := 2

иначе |Ход человека

Ввод направления перемещения

Определение нового положения короля

ходит := 1

все

Изменение ситуации на доске (в массиве)

Вывод новой позиции

кц_при <король в левом нижнем углу>

Текущее положение короля будем определять номером строки (тек_стр) и номером столбца (тек_стол) поля, на котором он находится. В начале игры тек_стр = 8, тек_стол = 8, условие окончания игры — тек_стр = 1 и тек_стол = 1.

Ясно, что выбранное человеком направление перемещения должно быть допустимым. Прежде всего значение соответствующей величины куда должно удовлетворять условию: 0 < куда < 4. Кроме того, даже при таких значениях величины куда выбранное направление может оказаться недопустимым (например, когда король находится на самой нижней строке, ходы вниз и по диагонали невозможны). Проверку допустимости хода будем проводить следующим образом.

В зависимости от значения величины куда определим новое положение короля:

выбор

при куда = 1:

нов_стол := тек_стол - 1

нов_стр := тек_стр

при куда = 2:

нов_стол := тек_стол

нов_стр := тек_стр - 1

при куда = 3:

нов_стол := тек_стол - 1

нов_стр := тек_стр - 1

все

Величины нов_стр и нов_стол характеризуют координаты нового поля согласно выбранному направлению. Значения этих величин должны быть положительными. С учетом всего сказанного фрагмент программы, относящийся к ходу человека, принимает вид:

иначе Ход человека

нц

вывод нс, "Ходите Вы"

вывод нс, "Задайте направление

перемещения "

вывод "(влево - 1, вниз - 2,

по диагонали – 3)"

ввод куда

выбор

при куда = 1:

… (см. выше)

все

если куда <= 0 или куда >= 4 или

нов_стр <= 0 или нов_стол <= 0

то

вывод нс, "Ошибочный ход!"

все

кц_при куда > 0 и куда < 4 и

нов_стр > 0 и нов_стол > 0

ходит := 1

все

Выбор хода компьютером должен проводиться согласно выигрышной стратегии, описанной в рубрике “Задачник”. Нужно только стратегию применительно к расстановке символов “+” и “–” описать с помощью формул. Когда король находится на нижней строке или в левом столбце, то выбор направления не вызывает проблем:

если тек_стр = 1, то куда = 1,

если тек_стол = 1, то куда = 2.

А вот как быть в противном случае? Анализ особенностей расстановки символов “+” и “–” на рис. 3 в статье в только что упомянутой рубрике позволяет сформулировать следующее правило: поле является проигрышным, если оба его номера (номер строки и номер столбца) — нечетные (по нумерации, приведенной на рис. 1 в данной статье). Значит, компьютер должен делать ход на одну из таких клеток. Полностью условие выбора направления хода компьютером можно записать так:

если тек_стр = 1

то

куда := 1

иначе

если тек_стол = 1

то

куда := 2

иначе

|Реализуем выигрышную стратегию

|Если слева внизу поле с нечетными

|номерами

если mod(тек_стол - 1, 2) = 1 и

mod(тек_стр - 1, 2) = 1

то |Идти надо туда

куда := 3

иначе

|Если слева столбец с нечетным

|номером

если mod(тек_стол - 1, 2) = 1

то

куда := 1

иначе

куда := 2

все

все

все

все

После хода любого из участников следует изменить позицию на доске (состояние массива доска) и вывести ее:

|Очищаем поле, где стоял король

доска[8 - тек_стр + 1, тек_стол] := " "

|Меняем текущее положение

выбор

при куда = 1:

тек_стол := тек_стол - 1

при куда = 2:

тек_стр := тек_стр - 1

иначе

тек_стол := тек_стол - 1

тек_стр := тек_стр - 1

все

|Отмечаем новое положение короля

доска[8 - тек_стр + 1, тек_стол] := "К"

|Выводим новую позицию

Вывод_позиции

Фрагмент, относящийся к определению победителя (этап 3), составить достаточно просто:

|Определение победителя

если ходит = 1

то

вывод нс, "Выиграли Вы. Поздравляем!"

иначе

вывод нс, "Выиграл компьютер"

все

Прежде чем представлять всю программу, заметим, что, поскольку состояние массива доска меняется в основной программе, а выводится он на экран в про­цедуре Вывод_позиции, этот массив должен быть описан как глобальный:

сим таб доска[1:8, 1:8]

алг Игра_Король_на_шахматной_доске

нач цел ходит, куда, тек_стр, тек_стол,

нов_стр, нов_стол, i, j

|Формирование и вывод начальной позиции

|Моделируем пустую доску

… (см. выше)

Вывод_позиции

ходит := 1

нц |Ходы участников игры

если ходит = 1

то |Ходит компьютер

если тек_стр = 1

|(см. выше о выборе хода компьютером)

все

вывод нс, "Компьютер выбрал: "

выбор

куда = 1: вывод "ход влево"

куда = 2: вывод "ход вниз"

куда = 3: вывод "ход влево и вниз"

все

вывод "Для продолжения нажмите

любую клавишу"

нц

кц_при inkey <> ""

ходит := 2

иначе

нц

вывод нс, "Ходите Вы"

вывод нс, "Задайте направление

перемещения"

… (см. выше)

все

|Очищаем старое текущее положение

доска[8 - тек_стр + 1, тек_стол] := " "

|Меняем позицию на доске

…(см. выше)

и выводим ее

Вывод_позиции

кц_при тек_стол = 1 и тек_стр = 1

|Определение победителя

… (см. выше)

кон

Задание для самостоятельной работы

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

Конечно, эта игра совершенно несправедливая — побеждать всегда будет компьютер (а значит, вывод сообщения “Выиграли Вы. Поздравляем!” в программе является лишним). Поэтому предлагаем также читателям разработать программы, моделирующие следующие варианты игры:

1) начальное положение короля выбирается случайным образом, исходя из допущения, что он может находиться в одной из клеток с номерами столбца 6–8 и номерами строки 6–8. Если номер столбца и номер строки для начального положения обозначить соответственно нач_стол и нач_стр, то значения этих величин можно определить так:

нач_стол := 6 + 3 * rnd(1)

нач_стр := 6 + 3 * rnd(1)

2) компьютер ходит “наугад” (но допустимым образом);

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

ходит := 1 + 2 * rnd(1)

4) в игре участвуют два человека.

Все приславшие хотя бы один вариант правильной программы будут награждены дипломами.


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

М.. А.. Цайгер

TopList