Algorithm 如何在m,n,k-游戏(广义tic-tac-toe)早期有效地检测平局?

Algorithm 如何在m,n,k-游戏(广义tic-tac-toe)早期有效地检测平局?,algorithm,tic-tac-toe,Algorithm,Tic Tac Toe,我正在实现一个,一个tic-tac-toe的通用版本,其中m是行数,n是列数,k是玩家需要放入一行中才能获胜的棋子数。我已经实现了一个胜利检查,但我还没有找到一个令人满意的方法来检查之前,董事会是充满碎片,如果没有球员可以赢得比赛。换句话说,棋盘上可能有空的位置,但它们不能以一个玩家获胜的方式填满 我的问题是,如何有效地检查这一点?下面的算法是我能想到的最好的。它检查两个条件: A.在所有4个方向(从上到下、从右到左以及两个对角线方向)上检查所有板位置。如果说k=5,并且发现4(=k-1)个连续

我正在实现一个,一个tic-tac-toe的通用版本,其中m是行数,n是列数,k是玩家需要放入一行中才能获胜的棋子数。我已经实现了一个胜利检查,但我还没有找到一个令人满意的方法来检查之前,董事会是充满碎片,如果没有球员可以赢得比赛。换句话说,棋盘上可能有空的位置,但它们不能以一个玩家获胜的方式填满

我的问题是,如何有效地检查这一点?下面的算法是我能想到的最好的。它检查两个条件:

A.在所有4个方向(从上到下、从右到左以及两个对角线方向)上检查所有板位置。如果说k=5,并且发现4(=k-1)个连续的空插槽,停止检查并报告“无连接”。例如,这没有考虑以下情况:

OX----XO    (Example 1)
其中a)在两个
X
之间的某处有4个空的连续位置(
-
),b)接下来轮到
O
,c)棋盘上的其他空位置少于4个,没有玩家可以通过向这些位置掷棋子获胜,和d)除了在所示插槽中水平外,不可能在任何其他方向获胜。现在我们知道这是一个平局,因为
O
最终将阻止最后一次获胜的可能性,但错误的是,它还没有被报告,因为有四个连续的空位。那可以(但不是很好)。当检查算法通常很早就发现这种情况时,检查这种情况在开始时会有很好的加速,但随着更多的块被放在电路板上,速度会变慢

B.如果不满足此k-1连续空槽条件,算法将在所有4个方向上再次连续检查槽。假设我们当前正在从左到右检查。如果在某个点遇到
X
,并且前面有
O
-
(空插槽)或电路板边框,则开始计算连续
X
和空插槽的数量,在第一次遇到的
X
中计数。如果一个人能数到5,那么他就知道
X
有可能获胜,并且报告“没有平局”。如果在5个连续的
X
之前遇到前面有
X
O
,则
X
无法在从开始计数的位置开始从左到右的5个插槽中获胜。例如:

X-XXO    (Example 2)
12345
X-X-O    (Example 3)
12345
在这里,我们从位置1开始检查,计数到4,然后遇到一个
O
。在这种情况下,将以相同的方式从遇到的
O
继续,这次尝试查找5个连续的
O
或空插槽。在另一种情况下,当计数
X
或空插槽时,在计数到5之前,会遇到前面有一个或多个空插槽的
O
。例如:

X-XXO    (Example 2)
12345
X-X-O    (Example 3)
12345
在这种情况下,我们将再次从位置5处的
O
继续,但向新计数器(连续
O
或空槽)添加
O
之前的连续空槽数,此处为1,这样我们就不会错过例如这个可能获胜的位置:

X-X-O---X    (Example 4)
这样,在最坏的情况下,必须通过所有位置4次(4个方向,当然可以跳过长度小于k的对角线),给出运行时间O(mn)

我能想到的最好的方法是在一次通过中完成这两个描述的检查,A和B。如果检查算法在所有方向上通过所有位置而未报告“无平局”,则报告平局

知道你只需在最后一块添加了运行时间
O(k)
的区域附近进行检查就可以检查胜利,我想知道是否有更快的方法提前检查平局。不必是渐进的更快。我现在把这些碎片保存在一个二维数组中。是否存在允许有效检查的数据结构?一种方法是:在进行任何平局检查之前,可以等待玩家做出的动作的最高阈值是多少


例如,堆栈溢出有许多相关的问题,但我所能找到的所有讨论要么只是指出了明显的平局条件,即移动的次数等于棋盘的大小(或者他们检查棋盘是否已满),要么只处理棋盘为正方形的特殊情况:m=n。例如,声称在恒定时间内检查接头,但仅在m=n=k时有效。我对尽早报告平局以及m、n和k将军的平局感兴趣。另外,如果算法适用于两个以上的玩家,那就很好了。

实际上,您引用的恒定时间解决方案仅在k=m=n时有效。如果k较小,那么我看不到任何方法来调整解决方案以获得恒定的时间,基本上是因为在每行/列/对角线上有多个位置,其中可能出现连续获胜的k0或1

但是,维护每行/每列/每对角线的辅助信息可以提高速度。对于每一行/列/对角线,您可以将连续出现的1和空格的开始和结束位置存储为玩家1的可能获胜位置,同样,将连续出现的0和空格的开始和结束位置存储为玩家0的可能获胜位置。请注意,对于给定的行/列/对角线,如果播放机0和1包含空格,则它们的间隔可能重叠。对于每一行/列/对角线,将播放器1的间隔按排序顺序存储在自平衡二叉树中(注意,您可以这样做,因为间隔是不相交的)。类似地,将播放器0的间隔存储在树中。当玩家移动时,找到包含移动位置的行/列/对角线,并更新包含移动位置的间隔