Иллюстрированный самоучитель по Turbo Pascal

Игра Ним

Обратите внимание: константа ТЕХТ3 = 'Ваш ход: имеет длинный "хвост" из пробелов (их 17), поэтому после вывода этого приглашения курсор возвращается влево на 16 позиций оператором:

GotoXY(WhereX-16,Y+2); {курсор влево на 16 позиций}

(Функция WHEREX возвращает текущую горизонтальную координату курсора, а функция WHEREY – его вертикальную координату). Сделано это для того, чтобы в случае, если игрок ввел неверный ход и программа повторяет вывод приглашения, пробелы в константе ТЕХТ3 затерли бы строку предыдущего ввода.

Чтобы завершить создание процедуры GETPLAYERMOVE, нужно спроектировать процедуру GETCHANGE, в которой осуществляется изменение условий игры. Я привожу текст этой процедуры без пояснений и приглашаю Вас самостоятельно разобраться в том, как она работает:

Procedure GetChange;
{Устанавливает новую настройку игры (количество рядов и количество фишек в каждом ряду}
const
t1='HACTPOЙКA ИГРЫ';
t2 ='(ввод количества рядов и количества '+'фишек в каждом ряду)';
var
correctly: Boolean;
i: Integer; begin {GetChange}
ClrScr;
GotoXY((80 – Length (tl)) div2,l);
Write(tl);
GotoXY((80 – Length (t2)) div2.2);
Write (t2);
repeat
GotoXYd, 3);
Write ('Введите количество рядов (максимум ', MAXROW, '):');
GotoXY(WhereX-6,WhereY);
ReadLn (nrow);
correctly: = (nrow <= MAXROW) and (nrow > 1);
if not correctly then
Write (#7)
until correctly;
for i: = 1 to nrow do
repeat
GotoXY(l,i+3);
Write (' ряд ',i,', количество фишек (максимум ', MAXCOL, '): ');
GotoXY (WhereX – 6, WhereY);
ReadLn (ncol [i]);
correctly: = (ncol [i] <= MAXCOL) and (ncol[i] > 0);
if not correctly then
Write (#7)
until correctly
end; {GetChange}

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

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

Начальный вариант процедуры:

Procedure SetOwnerMove;
{Находит и отображает очередной ход программы}
{-----------------}
Function CheckField: Integer;
{Проверяет состояния игры. Возвращает 0, если нет ни одной фишки (победа игрока),
1 – есть один ряд (победа машины) и – количество непустых рядов в остальных случаях}
begin {CheckField}
end; {CheckField}
{-----------------}
Procedure PlayerVictory;
{Поздравить игрока с победой и усложнить игру}
begin {PlayerVictory}
end; {PlayerVictory}
{-----------------}
Procedure OwnVictory;
{Победа машины}
begin {OwnVictory}
end; {OwnVictory}
{-----------------}
Procedure ChooseMove;
{Выбор очередного хода}
begin {ChooseMove}
end; {ChooseMove}
{-----------------}
begin {SetOwnerMove}
case CheckField of {Проверяем количество непустых рядов}
0: PlayerVictory; {Все ряды пусты – победа игрока}
1: OwnVictory; {Один непустой ряд – победа машины}
else
ChooseMove; {Выбираем очередной ход}
end; {case}
end; {SetOwnerMove}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.