完整代码可以在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