Prolog-检查X和O游戏的获胜条件

时间:2018-12-03 17:56:22

标签: prolog

我有一个简单的井字游戏,在线上有很多使用最小最大化的示例,但是我只是想用一个简单的示例进行自己的理解。 我已经在3x3框中显示了木板,该木板具有编号系统,用户可以通过以下方式从中进行选择:

:- 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)中进行选择时,板上将为人类玩家填充X,为计算机填充O。 现在,我也有关于获胜路线的事实:

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).

因此,在每一步之后,我想检查是否已赢过一个获胜线组合,即,棋盘是否包含任何winningLine组合,并且玩家拥有该组合。我一直在考虑,可以在这里使用findall方法,但是我愿意接受建议。

我的问题:如何检查董事会的获胜条件?

2 个答案:

答案 0 :(得分:2)

简单答案

由于您使用的是全球游戏位置,因此我们可以假设存在一个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_movechecked

/* 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) :- ...

答案 1 :(得分:1)

使用上述全局状态表示形式,您基本上必须调用winningLine(I, J, K)以获得三倍的 indices ,然后对于所有这些索引,要么{ {1}}(x(X)XIJ取代)应成立;或对于所有索引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会感到满意。

但是我个人认为使用全局状态并不是解决问题的绝妙方法(实际上,即使不是全部,也都是大多数情况下)。在这里,您不能使用Prolog强大的回溯机制,此外,例如,如果您想搜索是否还有一种方法可以赢得用户,则不能简单地复制棋盘并在复制的棋盘上运行求解器板。