三子棋电脑下棋逻辑升级(三子棋程序)

三子棋电脑下棋逻辑升级代码全文可看gitee
三子棋升级版代码
关于基本三子棋算法逻辑,大家都大差不差的,我感觉没什么好谈,主要谈谈我对电脑下棋逻辑进行的优化。 三子棋基本思路具体可看头文件

完整代码可以在gitee上查看

三子棋升级版代码

对于基本的三子棋算法逻辑,每个人都几乎相同。我主要想讲的是优化电脑象棋的下棋逻辑。

三子棋的基本思想在头文件中。

优化下棋逻辑(只考虑三子棋,多了情况就变得很复杂)

1.最容易想到的,下中间

if (arr[COL/2][COL/2]==\’ \’)//碰碰运气,移动到中心

{

arr[COL/2][COL/2]=\’#\’;

休息;

}

添加条件以阻止后续计算机继续下载。

2.关于进攻

为了快速获胜,你需要优先考虑你的攻击。连续两次就够了。

此时需要考虑三种情况

(1)行

整数i=0;

while (i 3)//判断一行中是否有两个相同的#,胜者优先。

{

if (arr[i][0]==\’#\’ || arr[i][1]==\’#\’)

{

if (arr[i][0]==arr[i][1])

{

if (arr[i][2]==\’ \’)

{

arr[i][2]=\’#\’;

出去。

}

}

否则if (arr[i][0]==arr[i][2])

{

if (arr[i][1]==\’ \’)

{

arr[i][1]=\’#\’;

出去。

}

}

否则if (arr[i][1]==arr[i][2])

{

if (arr[i][0]==\’ \’)

{

arr[i][0]=\’#\’;

出去。

}

}

}

我++;

}

我=0;

如果你使用了while 并想稍后使用i,则需要小心清除i。

我们使用goto的原因是如果满足条件就直接跳转到函数的末尾,以防止计算机一遍又一遍地下棋。

如果您不打算使用goto,您还可以创建更多函数。

(2)列

整数j=0;

while (j 3)//判断是否出现两个相同的列#

{

if (arr[0][j]==\’#\’ || arr[1][j]==\’#\’)

{

if (arr[0][j]==arr[1][j])

{

if (arr[2][j]==\’ \’)

{

arr[2][j]=\’#\’;

出去。

}

}

否则if (arr[0][j]==arr[2][j])

{

if (arr[1][j]==\’ \’)

{

arr[1][j]=\’#\’;

出去。

}

}

否则if (arr[1][j]==arr[2][j])

{

if (arr[0][j]==\’ \’)

{

arr[0][j]=\’#\’;

出去。

}

}

}

j++;

}

j=0;

列逻辑与行逻辑类似,但下标差异如下:

(3)对角线

if (arr[1][1]==\’#\’)

{

if (arr[1][1]==arr[0][0])//对角线

{

if (arr[2][2]==\’ \’)

{

arr[2][2]=\’#\’;

出去。

}

}

否则if (arr[1][1]==arr[2][2])

{

if (arr[0][0]==\’ \’)

{

arr[0][0]=\’#\’;

出去。

}

}

否则if (arr[1][1]==arr[0][2])

{

if (arr[2][0]==\’ \’)

{

arr[2][0]=\’#\’;

出去。

}

}

否则if (arr[1][1]==arr[2][0])

{

if (arr[0][2]==\’ \’)

{

arr[0][2]=\’#\’;

出去。

}

}

}

主对角线和次对角线总共有四种情况,但数量并不多,这只是一个详尽的列表。

3.关于防守

防御主要分为两部分。

1.对手有两列,连续的和不连续的,每列有3个小部件。

由于先手不能走中间棋的原则,电脑会先走棋,所以不会出现对角线的情况。

2、对方常见的“迷惑”手段断断续续,让你措手不及。

它大致可分为两种:斜形和菱形。

所谓对角型

与上图的情况类似,一个在对角线上,另一个在对面的中心。如果这个时候你不保护对手,当对手处于(1, 1)位置时,就会出现两种情况,那就是你输了。

有很多方法可以处理这个问题,但我使用对角向下的方法(1, 3)。

所谓的菱形

与上图类似,这是一种常见的不连续性,没有防御措施。这时候,如果你的对手在(1,1),你也输了。

共有三种处理方式,上图是在(1,1)位置。

(1)行与列

while (i 3)//判断是否连续有两个相同的*来阻止你的对手。

{

if (arr[i][0]==\’*\’ || arr[i][1]==\’*\’)

{

if (arr[i][0]==arr[i][1])

{

if (arr[i][2]==\’ \’)

{

arr[i][2]=\’#\’;

出去。

}

}

否则if (arr[i][0]==arr[i][2])

{

if (arr[i][1]==\’ \’)

{

arr[i][1]=\’#\’;

出去。

}

}

否则if (arr[i][1]==arr[i][2])

{

if (arr[i][0]==\’ \’)

{

arr[i][0]=\’#\’;

出去。

}

}

}

我++;

}

while (j 3)//判断列中是否有两个相同的*

{

if (arr[0][j]==\’*\’ || arr[1][j]==\’*\’)

{

if (arr[0][j]==arr[1][j])

{

if (arr[2][j]==\’ \’)

{

arr[2][j]=\’#\’;

出去。

}

}

否则if (arr[0][j]==arr[2][j])

{

if (arr[1][j]==\’ \’)

{

arr[1][j]=\’#\’;

出去。

}

}

否则if (arr[1][j]==arr[2][j])

{

if (arr[0][j]==\’ \’)

{

arr[0][j]=\’#\’;

出去。

}

}

}

j++;

}

逻辑和攻击都是一样的,只是判断方式变了。

我们之所以不将两者结合起来,是因为有时计算机可以通过选择攻击来直接获胜,但采取防御是不明智的。

如果要写多个判断并区分攻击的优先级,就多加一些

使用goto来满足攻击条件会导致后续代码被跳过。三件套中的循环数量不是很多,对执行速度影响不大。

(2)防御对角战术和菱形战术

整数计数=0;

整数像素=0;

整数py=0;

整数pz=0;

int 密码=0;

for (i=0; i row; i++)//对角线和菱形战术

{

for (j=0; j 列; j++)

{

if (arr[i][j]==\’*\’)

{

计数++;

如果(计数==1)

{

像素=我;

py=j;

}

否则如果(计数==2)

{

pz=我;

pw=j;

}

}

}

}

如果(计数==2)

{

if ((px==0 py==0) || (pz==0 pw==0))

{

arr[2][2]=\’#\’;

}

否则if ((px==2 py==2) || (pz==2 pw==2))

{

arr[0][0]=\’#\’;

}

否则if ((px==0 py==2) || (pz==0 pw==2))

{

arr[2][0]=\’#\’;

}

否则if ((px==2 py==0) || (pz==2 pw==0))

{

arr[0][2]=\’#\’;

}

否则如果(px==0 py==1 pz==1 pw==2)

{

arr[0][2]=\’#\’;

}

否则如果(px==0 py==1 pz==1 pw==0)

{

arr[0][0]=\’#\’;

}

否则如果(px==1 py==0 pz==2 pw==1)

{

arr[2][0]=\’#\’;

}

否则如果(px==1 py==2 pz==2 pw==1)

{

arr[2][2]=\’#\’;

}

}

代码实现如上

部分解释一下,这两种情况只有在对手下两步棋时才会出现,所以你需要判断。

把它们放在一起,整个函数看起来像这样

void su_com_move(char(*arr)[COL], int row, intcol)

{

整数i=0;

while (i 3)//判断一行中是否有两个相同的#,胜者优先。

{

if (arr[i][0]==\’#\’ || arr[i][1]==\’#\’)

{

if (arr[i][0]==arr[i][1])

{

if (arr[i][2]==\’ \’)

{

arr[i][2]=\’#\’;

出去。

}

}

否则if (arr[i][0]==arr[i][2])

{

if (arr[i][1]==\’ \’)

{

arr[i][1]=\’#\’;

出去。

}

}

否则if (arr[i][1]==arr[i][2])

{

if (arr[i][0]==\’ \’)

{

arr[i][0]=\’#\’;

出去。

}

}

}

我++;

}

我=0;

整数j=0;

while (j 3)//判断是否出现两个相同的列#

{

if (arr[0][j]==\’#\’ || arr[1][j]==\’#\’)

{

if (arr[0][j]==arr[1][j])

{

if (arr[2][j]==\’ \’)

{

arr[2][j]=\’#\’;

出去。

}

}

否则if (arr[0][j]==arr[2][j])

{

if (arr[1][j]==\’ \’)

{

arr[1][j]=\’#\’;

出去。

}

}

否则if (arr[1][j]==arr[2][j])

{

if (arr[0][j]==\’ \’)

{

arr[0][j]=\’#\’;

出去。

}

}

}

j++;

}

j=0;

if (arr[1][1]==\’#\’)

{

if (arr[1][1]==arr[0][0])//对角线

{

if (arr[2][2]==\’ \’)

{

arr[2][2]=\’#\’;

出去。

}

}

否则if (arr[1][1]==arr[2][2])

{

if (arr[0][0]==\’ \’)

{

arr[0][0]=\’#\’;

出去。

}

}

否则if (arr[1][1]==arr[0][2])

{

if (arr[2][0]==\’ \’)

{

arr[2][0]=\’#\’;

出去。

}

}

否则if (arr[1][1]==arr[2][0])

{

if (arr[0][2]==\’ \’)

{

arr[0][2]=\’#\’;

出去。

}

}

}

while (i 3)//判断是否连续有两个相同的*来阻止你的对手。

{

if (arr[i][0]==\’*\’ || arr[i][1]==\’*\’)

{

if (arr[i][0]==arr[i][1])

{

if (arr[i][2]==\’ \’)

{

arr[i][2]=\’#\’;

出去。

}

}

否则if (arr[i][0]==arr[i][2])

{

if (arr[i][1]==\’ \’)

{

arr[i][1]=\’#\’;

出去。

}

}

否则if (arr[i][1]==arr[i][2])

{

if (arr[i][0]==\’ \’)

{

arr[i][0]=\’#\’;

出去。

}

}

}

我++;

}

while (j 3)//判断列中是否有两个相同的*

{

if (arr[0][j]==\’*\’ || arr[1][j]==\’*\’)

{

if (arr[0][j]==arr[1][j])

{

if (arr[2][j]==\’ \’)

{

arr[2][j]=\’#\’;

出去。

}

}

否则if (arr[0][j]==arr[2][j])

{

if (arr[1][j]==\’ \’)

{

arr[1][j]=\’#\’;

出去。

}

}

否则if (arr[1][j]==arr[2][j])

{

if (arr[0][j]==\’ \’)

{

arr[0][j]=\’#\’;

出去。

}

}

}

j++;

}

整数计数=0;

整数像素=0;

整数py=0;

整数pz=0;

int 密码=0;

for (i=0; i row; i++)//对角线和菱形战术

{

for (j=0; j 列; j++)

{

if (arr[i][j]==\’*\’)

{

计数++;

如果(计数==1)

{

像素=我;

py=j;

}

否则如果(计数==2)

{

pz=我;

pw=j;

}

}

}

}

如果(计数==2)

{

if ((px==0 py==0) || (pz==0 pw==0))

{

arr[2][2]=\’#\’;

}

否则if ((px==2 py==2) || (pz==2 pw==2))

{

arr[0][0]=\’#\’;

}

否则if ((px==0 py==2) || (pz==0 pw==2))

{

arr[2][0]=\’#\’;

}

否则if ((px==2 py==0) || (pz==2 pw==0))

{

arr[0][2]=\’#\’;

}

否则如果(px==0 py==1 pz==1 pw==2)

{

arr[0][2]=\’#\’;

}

否则如果(px==0 py==1 pz==1 pw==0)

{

arr[0][0]=\’#\’;

}

否则如果(px==1 py==0 pz==2 pw==1)

{

arr[2][0]=\’#\’;

}

否则如果(px==1 py==2 pz==2 pw==1)

{

arr[2][2]=\’#\’;

}

}

输出:

}

现在我们的函数已经完成,我们需要在game.h 头文件中声明它。

//升级版三件套电脑象棋逻辑

void su_com_move(char(*arr)[COL], int row, intcol);

声明完成后,对main 函数进行一些更改。

if (行==列行==3)

{

super_com_move(arr, ROW, COL);

}

com_move(arr, 行, 列);

pri_board(arr, ROW, COL);

添加条件。对于三子棋,如果找不到更好的情况,则随机下棋。

在这种情况下,您不能同时玩两个。

因此,通常需要对判断进行一些调整。

void com_move(char(*arr)[COL], int row, intcol)

{

printf(\’电脑下棋:\\n\’);

整数x=0;

整数y=0;

整数i=0;

整数j=0;

另一方面(1)

{

整数计数=0;

if (arr[COL/2][COL/2]==\’ \’)//趁机移动到中心

{

arr[COL/2][COL/2]=\’#\’;

休息;

}

for (i=0; i 行; i++)

{

for (j=0; j 列; j++)

{

if (arr[i][j] !=\’ \’)

{

计数++;

}

}

}

if (计数% 2==1)

{

x=rand() % 行;

y=rand() % 列;

if (arr[x][y]==\’ \’)

{

arr[x][y]=\’#\’;

休息;

}

}

除此之外

{

休息;

}

}

}

仅当棋盘上的数字为奇数时才执行(意味着之前的函数执行没有结果)。

换句话说,这种对棋局逻辑的优化使得玩家几乎不可能获胜。

虽然取决于个人,但由于某些限制或计算机判断,可能会被酌情删除。

比如开局不能打中路、混乱就意味着防守等等。

至于计算机下棋的逻辑是否可以进一步优化,答案是肯定的。

我提供的想法更具防御性。

但国际象棋的游戏是不断变化的,这是一个非常大的项目,所以至少我不会挣扎。

毕竟我在电脑上玩过很多游戏,而且基本上都是中等水平。

如果你必须竭尽全力让计算机打败你,你可能不会满意。

以上#三板电脑象棋逻辑升级相关内容摘自网络,仅供大家参考。相关信息请参见官方公告。

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91660.html

Like (0)
CSDN的头像CSDN
Previous 2024年6月23日
Next 2024年6月23日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注