在零和十字架中检测胜利的比赛

时间:2010-04-19 19:32:17

标签: algorithm tic-tac-toe

我需要知道在一场比赛和十字架比赛中发现胜利动作的最佳方法。源代码并不重要,我只需要一个例子或我可以开始的东西。

我唯一能想到的就是使用循环并测试玩家每次移动的每个方向,以便连续搜索五个。有没有更快更有效的方式?

6 个答案:

答案 0 :(得分:7)

真正简单的解决方案就是从最后一步做出检查......很明显,没有先前的动作可以赢得比赛,或者你不会在这里......所以你只需要检查一下是否有在刚刚放置的移动周围的行/列/对角线中有5个(或多个)。

例如,如果电路板看起来像这样,X标记最近的移动:

.............
.............
.............
.............
.....X.......
.............
.............
.............
.............
.............

您无需检查“C”范围之外的任何内容:

.C...C...C...
..C..C..C....
...C.C.C.....
....CCC......
.CCCCXCCCC...
....CCC......
...C.C.C.....
..C..C..C....
.C...C...C...
.............

这有帮助吗? (看起来你可能在原来的问题中提到了这一点,但我不确定。)

除此之外,简单的循环将成为你最好的朋友。你可以做一些微优化,但是(取决于你的实际应用程序在做什么)它可能不值得。

要记住的一件事是你不能从最近一次寻找连续多次的动作中向任何方向跳出5,因为这一举动可能正处于连胜的中间。所以我会做像

这样的事情
From the new move
    left = how many in a row we have to the left of the lastest move
    right = how many in a row we have to the right of the latest move
    if (left + right + 1 >= 5) then you have a winner

    up = how many in a row we have above the latest move
    down = how many in a row we have below the latest move
    if (up + down + 1 >= 5) then you have a winner

    // repeat for both diagonal directions.

答案 1 :(得分:7)

Noughts and crosses是一个简洁的编程挑战,因为你可以使用很多数学技巧来简化问题。

Noughts和crosses通常是3乘3的网格。如果为网格中的每个位置指定一个从1到9的数字(不是按数字顺序排列),则可以排列数字,以便每个水平,垂直和对角线行最多可累加15个

+----+----+----+
| 4  | 3  | 8  |
|    |    |    |
+----+----+----+
| 9  | 5  | 1  |
|    |    |    |
+----+----+----+
| 2  | 7  | 6  |
|    |    |    |
+----+----+----+ 

为什么有用?如果你可以挑选属于“O”或“X”的任意三个方格,并且这三个方格的总和为15,那么你知道该玩家赢得了比赛。

答案 2 :(得分:2)

考虑3X3板

设X = 1 设O = -1 并且空格由零表示。

所以如果顶行看起来像这[X] [X] [X]那么总和就是3,所以这是一场胜利                                   [O] [O] [O]总和为-3,因此这是另一场胜利。

[X] [X] []是2,因此如果是X转,他可以通过移动到空白获胜,或者O必须阻止。

[X] [O] [X]为1,因此没有获胜。

在3x3董事会中,有8个职位需要评估。

在NXN中,数字变大但想法保持不变

如果N = 8并且行或列总和为7,那么您知道该行/列上有X的获胜移动

这种方法在高中时适合我。

祝福

答案 3 :(得分:1)

我不知道一个更好的方法然后循环,但是电路板太小了,这是非常微不足道的。

一个小的Python伪代码:

def get_winner(board):
    if board[0][0] != EMPTY and board[0][0] == board[1][1] == board[2][2]:
        return board[0][0]
    if board[2][0] != EMPTY and board[2][0] == board[1][1] == board[0][2]:
        return board[2][0]
    for i in xrange(3):
        if board[i][0] != EMPTY and board[i][0] == board[i][1] == board[i][2]:
            return board[i][0]
        if board[0][i] != EMPTY and board[0][i] == board[1][i] == board[2][i]:
            return board[0][i]

答案 4 :(得分:0)

有更有效的方法,但是当你为更多更大的电路板配置扩展这个游戏时,它们才真正重要。例如,如果您在方向对象中存储了noughts和十字架的分组(例如,存储对角线配置),则可以按长度为winLength-1的那些进行排序,并仅针对这些分组测试新的移动。您可以保存一些迭代,但必须在内存中保留大量额外信息。

答案 5 :(得分:0)

这是一个代表问题。你如何存储游戏板?现在想一想;如何存储 else ?例如,您可以将电路板表示为一对位图 - 一个用于noughts,一个用于十字架 - 然后进行数字模式匹配以检测获胜条件。