Пролог - Проверьте условия победы в игре X - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть простая игра в крестики-нолики, есть много примеров этого онлайн, которые используют минимальное усиление, но я просто хочу использовать простой пример для моего собственного понимания.Я отобразил доску в окне 3х3, в котором есть система нумерации, из которой пользователи могут выбирать, следующим образом:

:- dynamic o/1.
:- dynamic x/1.

% The computer has made a turn, print O
printBox(N) :- o(N), write('[o]').
% The player makes a turn, print X
printBox(N) :- x(N), write('[x]').
% We just want to print the empty board
printBox(N) :- blankSpace(N), write('[_]').


buildBoard :- printBox(1),printBox(2),printBox(3),nl,
          printBox(4),printBox(5),printBox(6),nl,
          printBox(7),printBox(8),printBox(9),nl.

playersMove :- 
read(X), 
blankSpace(X), 
assert(x(X)).

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

winningLine(1,2,3).
winningLine(4,5,6).
winningLine(7,8,9).
%Winning rows from left to right
winningLine(1,4,7).
winningLine(2,5,8).
winningLine(3,6,9).
%Winning diagnolly
winningLine(7,5,3).
winningLine(9,5,1).

Так что после каждого хода я хочу проверить, была ли сыграна одна из комбинаций выигрышных линий, т.е. содержит ли доска какую-либо из комбинаций выигрышной линии и с игрокомимеет эту комбинацию.Я думал об этом, и здесь можно было бы использовать метод findall, однако я был бы открыт для предложения.

Мой вопрос: Как я могу проверить на доске условия победы?

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

С приведенным выше представлением global state вам, в основном, нужно вызвать winningLine(I, J, K), чтобы получить тройку из индексов , а затем для всех этих индексов либо x(X)X заменяется на I, J и K) должно удерживаться;или для всех индексов o(X) следует провести, например:

xwin :-
    winningLine(I, J, K),
    x(I),
    x(J),
    x(K).
nwin :-
    winningLine(I, J, K),
    o(I),
    o(J),
    o(K).
win :-
    xwin.
win :-
    owin.

Так что здесь xwin/0 выполняется, если у игрока за x есть выигрышная линия, owin/0 удовлетворяется, учитывая игрокадля o есть выигрышная линия, и win/0 удовлетворен, если кто-либо из игроков выиграл.

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

0 голосов
/ 03 декабря 2018

Простой ответ

Поскольку вы работаете с глобальной игровой позицией, мы можем предположить, что существует предикат checked(Player, Square), в котором содержится, если игрок Player проверил квадрат Square.

Тогда все, что вам нужно проверить, чтобы увидеть, выиграл ли игрок в игре, это спросить, есть ли выигрышная линия, где все три квадрата проверены одним и тем же игроком:

is_win(Player) :-
    winning_line(P1,P2,P3),
    checked(Player,P1),
    checked(Player,P2),
    checked(Player,P3).

Вы можете создать checked/2, используя assertz:

:- dynamic checked/2.

player_move(Player, Square) :- assertz(checked(Player, Square)).

Лучший путь

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

initial_state(board([empty, empty, empty],
                    [empty, empty, empty],
                    [empty, empty, empty]).

и соответственно корректирует player_move и checked:

/* Should make a new board from Position0 by adding the move */
player_move(Player, Square, Position0, Position) :- ...  

/* Should check if a player has checked a square inside Position */
checked(Player, Square, Position) :- ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...