我知道有很多关于connect 4 check for a win的问题。问题是大多数其他算法使我的程序有运行时错误,因为他们试图访问我的数组之外的索引。我的算法是这样的:
private int checkWin(int[][] gridTable,int rowNum,int colNum, int maxRow, int maxCol)
{
// For checking whether any win or lose condition is reached. Returns 1 if win or lose is reached. else returns 0
// gridTable[][] is the game matrix(can be any number of rows and columns between 4 and 40)
// colNum is the column number where the last token was placed
// rowNum is the row number where the last token was placed
// maxRow is the number of rows in my grid
// maxCol is the number of columns in my grid
int player = gridTable[rowNum][colNum]; //player ID
int count=0;
// Horizontal check
for (int i=0;i<maxCol;i++)
{
if (gridTable[rowNum][i]==player)
count++;
else
count=0;
if (count>=4)
return 1;
}
//Vertical check
for (int i=0;i<maxRow;i++)
{
if (gridTable[i][colNum]==player)
count++;
else
count=0;
if (count>=4)
return 1;
}
count=0;
// 4 in a row diagonally
for(int i=colNum+1,j=rowNum+1;i<maxRow && j<maxCol;i++,j++)
{
if(gridTable[j][i]!=player)
{
count=1;
break;
}
count++;
}
// 4 in a row diagonally
for(int i=colNum-1,j=rowNum-1;i>=0 && j>=0;i--,j--)
{
if(gridTable[j][i]!=player)
{
count=1;
break;
}
count++;
}
// 4 in a row diagonally
for(int i=colNum+1,j=rowNum-1;i<maxRow && j>=0;i++,j--)
{
if(gridTable[j][i]!=player)
{
count=1;
break;
}
count++;
}
for(int i=colNum-1,j=rowNum+1;i>=0 && j<maxCol;i--,j++)
{ // 4 in a row diagonally
if(gridTable[j][i]!=player)
{
count=1;
break;
}
count++;
}
if(count>=4)
return 1;
return 0;
}
count是变量,如果count等于或大于4意味着它们应该是同一玩家的4个或更多个连续代币,则该变量检查获胜。
问题:有时,该方法在没有4个令牌按顺序的情况下检查获胜,而在其他时候,当4个令牌按顺序时不检查获胜。
6条答案
按热度按时间bvpmtnay1#
由于某种原因,我不是那么喜欢计数器,所以我这样做了(它适用于不同大小的电路板)。
igsr9ssn2#
看起来你的代码对于水平和垂直的情况都是正确的。棘手的部分是对角线的情况。
让我们试一幅:
对于绿色线,起始行位置为0... maxRow - 4。列位置为0... startingRow -
伪代码:
你可以对对角线做一些类似的事情,从左下角到右上角。
u5rb5r593#
因此,在深入研究了您的代码之后,似乎对角线检查只能在一个方向上获胜(如果我在最低行和最低列中添加一个标记,会发生什么情况?)
相反,基本的检查算法始终是相同的过程,而不管您从哪个方向签入。
你需要一个起点(x/y)和x/y增量(运动方向)。你可以把这个总结成一个单一的方法...
这将基本上允许您在四个方向上检查,但也可以反向进行
所以,如果我们用...
哪些输出...
现在,你可以把它总结成...
所以,用这样的东西...
它会打印出类似于...
我想补充的是,这种方法只有在你提供了一行4个芯片的正确开始时才有效。例如,didWin(gridTable,1,3,3)将为你的水平检查提供false而不是true,因为循环只能检查一个方向。
它的目的不是提供一个“成熟的,开箱即用”的解决方案,而是一个概念,从这个概念可以开发出一个更广泛的解决方案(我的意思是,我讨厌人们实际上必须思考;))。我还基于OP会知道最后一块放在哪里的想法设计了这个解决方案,即起点;)
通过稍微修改
didWin
方法,可以从任意点检查n
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x所以,我用了...
有时候,答案并不是一个完整的解决方案,而是一个想法的种子,它把一个人带到一个新的地方;)
进一步的增强将包括提供预期的连接片段的数量,但我非常确定这是一个我真的不需要演示的增强;)
yzuktlbb4#
我用C语言做了我自己的版本,我认为用另一种语言重新解释它是很容易的。
8ulbf1ek5#
如果有人还需要这个解决方案,我会用C#编写一个函数,并放入GitHub repo中。
这是回购协议:https://github.com/JoshK2/connect-four-winner
iyfamqjs6#
这就是对我起作用的方法,它也没有花看起来那么长的时间:
这些是对于x和o具有行、列、对角线和反对角的方法;