人工智能
井字棋的实现
学院:信息工程学院
教师:罗会兰
专业:计算机应用技术
学号:6120160166
姓名:王硕豪
简介
2016年3月9日,李世石与 AlphaGo 的人机大战开始。这将成为写入人类史册的一天。计算机 AI 可以在围棋上战胜人类顶尖棋手的时代已经到来。两个月之后,美国白宫就推动成立了机器学习与人工智能分委会,由其主持和协调撰写了三个关于人工智能发展的报告:《为人工智能的未来做好准备》《国家人工智能研究和发展战略计划》和《人工智能、自动化与经济报告》。欧盟、英国和日本等也相继发布了研发和应用人工智能的报告。显然,中国应当参与到这种战略布局当中,这种布局不仅是国家和民族的需要,而且也是赢得未来的利器。
再厉害的程序员,也是从“hello world”程序开始写起。再“聪明”的机器,也是从
零样本开始“训练”出来的。所以今天就来写一个最简单棋类游戏:
Tic Tac Toe,又叫井字棋,、又称为井字游戏、圈圈叉叉;另外也有打井游戏、OX棋的称呼,多称井字过三关、过三关,是种纸笔游戏。
大致说下井字棋的规则:
1.棋盘为 3*3 共 9 格,类似汉字“井”;
2.一方为 o,一方为 x,轮流落子;
3.任一方先有连成一条线的 3 个棋子(横、竖、斜皆可)则为胜利;
4.棋盘摆满仍没有一方胜利,则为平局。
这种游戏实际上是由第一位玩家所控制,第一位玩家是攻,第二位玩家是守。第一位玩家在角位行第一子的话赢面最大(见图一),第二位玩家若是在边,角位下子,第一位玩家就可以以两粒连线牵制着第二位玩家,然后制造“两头蛇”。
图一
运行
开始的时候,会让你输入你的名字,我则输入我名字的缩写wsh;
接下来,由我们来选择是先下还是后下,1是先下,2是后下;
我们的符号是X,电脑的是O,由于我们选择了先下,我们在3*3的棋盘上先下在第2行第2列;
电脑则下在了第1行第1列,再次由我们决定,如果我们下在了已经有棋子的位置上则会提示你已经下过了;
我们决定下在第1行第3列,电脑则下在第3行第1列,我们需要注意到如果电脑再下到第2行第1列就获得胜利,所以我们需要防守
我们为了防守下在了第2行第1列,电脑又下在了第2行第3列,这时候其实我们可以注意到如果想要胜利只有将第2列连成直线一种方法了;
我们下在了第1行第2列,电脑下在了第3行第2列,这时候已经可以看出是个平局了;
我们把最后一个位置填上,电脑告诉我们这是一个平局,是否还想要再玩;
输入y,电脑让我们再次选择先后手,大家就可以根据自己的想法来试着战胜电脑了。
如果失败了,也会询问你是否再次挑战,如果输入n则会直接跳出;
代码实现
棋盘本身的数据,用int a[3][3]来表示,棋盘中0表示空,1表示我们下的,其余的则是电脑下的;
void print()
{
int i,j;
cout<<\"\\n\";
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(a[i][j]==0)
cout<<\".\\";
else if(a[i][j]==1)
cout<<\"X\\";
else
cout<<\"O\\";
}
cout<}}
检查是否有人获胜,分别是三行,三列,对角线的8种情况
int check()
{
for(int i=0;i<3;i++)
if((a[i][0]!=0&&a[i][0]==a[i][1]&&a[i][1]==a[i][2])||(a[0][i]!=0&&a[0][i]==a[1][i]&&a[1][i]==a[2][i]))
return 1;
if(a[0][0]!=0&&a[0][0]==a[1][1]&&a[1][1]==a[2][2])
return 1;
else if(a[0][2]!=0&&a[0][2]==a[1][1]&&a[1][1]==a[2][0])
return 1;
else
return 0;
}
我们下棋的时候,下第几行第几列,如果输入大于2或者小于0提示输入正确的数字,如果下的位置已经被下过了提示这里已经被下过了;
void pin()
{
int r=0,c=0;
cout<<\"Enter row: \";
cin>>r;
cout<<\"Enter column: \";
cin>>c;
r--;
c--;
if(r>2||c>2||r<0||c<0)
{
strcpy(str,\"Enter correct value \");
strcat(str,name);
strcat(str,\".\\n\");
puts(str);
pin();
}
else if(a[r][c]!=0)
{
cout<<\"It is already filled.\\n\";
pin();
}
else
a[r][c]=t;
}
电脑的防守策略,即我们选择先手时电脑的应对策略
int defend(int c, int p, int b)
{
if(b<3)
return 0;
else if(a[0][0]+a[1][1]+a[2][2]==2*c&&a[0][0]!=p&&a[1][1]!=p&&a[2][2]!=p)
{
for(int i=0;i<3;i++)
{
if(a[i][i]==0)
{
a[i][i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
else if(a[0][2]+a[1][1]+a[2][0]==2*c&&a[0][2]!=p&&a[1][1]!=p&&a[2][0]!=p)
{
for(int i=0;i<3;i++)
{
if(a[i][2-i]==0)
{
a[i][2-i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
else
{
int i,j;
for(i=0;i<3;i++)
{
if(a[i][0]+a[i][1]+a[i][2]==2*c&&a[i][0]!=p&&a[i][1]!=p&&a[i][2]!=p)
{
for(j=0;j<3;j++)
{
if(a[i][j]==0)
{
a[i][j]=y;
cout<<\"Computer turn: \"<return 1; }
}
}
else
if(a[0][i]+a[1][i]+a[2][i]==2*c&&a[0][i]!=p&&a[1][i]!=p&&a[2][i]!=p)
{
for(j=0;j<3;j++)
{
if(a[j][i]==0)
{
a[j][i]=y;
cout<<\"Computer turn: \"<return 1;}
}
}
}
}
return 0;
}
电脑的进攻策略,即我们选择后手时电脑的落子策略
int attack()//takes a move as to win in future.
{
int i,j;
if(a[0][0]+a[0][2]+a[2][0]+a[2][2]==t||a[0][0]+a[0][2]+a[2][0]+a[2][2]==2*t)
{
for(i=0;i<3;i++)
{
if( a[i][0]+a[i][1]+a[i][2]==y && (a[i][0]==y||a[i][1]==y||a[i][2]==y) )
{
if(i==1)
{
for(j=0;j<3;j++)
{
if(a[i][j]==0)
{
a[i][j]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
else
{
for(j=2;j>=0;j--)
{
if(a[i][j]==0)
{
a[i][j]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
}
if(a[0][i]+a[1][i]+a[2][i]==y && (a[0][i]==y||a[1][i]==y||a[2][i]==y))
{
if(i==1)
{
for(j=0;j<3;j++)
{
if(a[j][i]==0)
{
a[j][i]=y;
cout<<\"Computer turn: \"< return 1;}
}
}
else
{
for(j=2;j>=0;j--)
{
if(a[j][i]==0)
{
a[j][i]=y;
cout<<\"Computer turn: \"<return 1; }
}
}
}
}
for(i=2;i>=0;i--)
{
if(a[i][2-i]==0)
{
if((a[i][0]+a[i][1]+a[i][2]==t&&(a[i][0]==t||a[i][1]==t||a[i][2]==t))&&(a[0][2-i]+a[1]
[2-i]+a[2][2-i]==t&&(a[0][2-i]==t||a[1][2-i]==t||a[2][2-i]==t)))
{
a[i][2-i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
for(i=2;i>=0;i--)
{
if(a[i][2-i]==0)
{
a[i][2-i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
}
else
{
if(a[0][0]+a[1][1]+a[2][2]==y && (a[0][0]==y||a[1][1]==y||a[2][2]==y))
{
for(i=2;i>=0;i--)
{
if((a[i][i]==0)&&
((a[i][0]+a[i][1]+a[i][2]==y&&(a[i][0]==y||a[i][1]==y||a[i][2]==y))
||( (a[0][i]+a[1][i]+a[2][i]==y)&&(a[0][i]==y||a[1][i]==y||a[2][i]==y))))
{
a[i][i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
for(i=2;i>=0;i--)
{
if(a[i][i]==0)
{
if((a[i][0]+a[i][1]+a[i][2]==t&&(a[i][0]==t||a[i][1]==t||a[i][2]==t))&&(a[0][i]+a[1][i]+a[2][i]==t&&(a[0][i]==t||a[1][i]==t||a[2][i]==t)))
{
a[i][i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
for(i=2;i>=0;i--)
{
if(a[i][i]==0)
{
a[i][i]=y;
cout<<\"Computer turn: \"< return 1;
}
}
}
else if( a[0][2]+a[1][1]+a[2][0]==y &&
(a[0][2]==y||a[1][1]==y||a[2][0]==y))
{
for(i=2;i>=0;i--)
{
if(a[i][2-i]==0&&((a[i][0]+a[i][1]+a[i][2]==y&&(a[i][0]==y||a[i][1]==y||a[i][2]==y))||( (a[0][2-i]+a[1][2-i]+a[2][2-i]==y)&&(a[0][2-i]==y||a[1][2-i]==y||a[2][2-i]==y))))
{
a[i][2-i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
for(i=2;i>=0;i--)
{
if(a[i][2-i]==0)
{
if((a[i][0]+a[i][1]+a[i][2]==t&&(a[i][0]==t||a[i][1]==t||a[i][2]==t))&&(a[0][2-i]+a[1][2-i]+a[2][2-i]==t&&(a[0][2-i]==t||a[1][2-i]==t||a[2][2-i]==t)))
{
a[i][2-i]=y;
cout<<\"Computer turn: \"< return 1;
}
}
}
for(i=2;i>=0;i--)
{
if(a[i][2-i]==0)
{
a[i][2-i]=y;
cout<<\"Computer turn: \"<return 1;
}
}
}
else
{
for(i=0;i<3;i++)
{
if(
a[i][0]+a[i][1]+a[i][2]==y (a[i][0]==y||a[i][1]==y||a[i][2]==y) )
{
if(i==1)
{
for(int j=0;j<3;j++)
{
&&
if(a[i][j]==0)
{
a[i][j]=y;
\"< cout<<\"Computer return 1;
}
}
}
else{
for(j=2;j>=0;j--)
{
if(a[i][j]==0)
{
turn: \"< a[i][j]=y;
cout<<\"Computer turn: \"<\"<return 1;}
}
}
}
else
if(a[0][i]+a[1][i]+a[2][i]==y (a[0][i]==y||a[1][i]==y||a[2][i]==y))
{
if(i==1)
{
for(j=0;j<3;j++)
&&
{
if(a[j][i]==0)
{
\"<
a[j][i]=y;
cout<<\"Computer return 1;
}
}
}
else
{
for(j=2;j>=0;j--)
{
turn: \"< if(a[j][i]==0){
a[j][i]=y;
\"< }
}
}
}
return 0;
}
}
}
cout<<\"Computer return 1;
turn: \"<}电脑的AI运用进攻和防守策略控制其的落子
void ai(int b)
{
if(!defend(y,t,b))
{
if(!defend(t,y,b))
{
if((a[0][0]+a[0][2]+a[2][0]+a[2][2]==t+y||a[0][0]+a[0][2]+a[2][0]+a[2][2]==t+2*y)&&a[1][1]==0)
{
for(int i=0;i<3;i+=2)
{
for(int j=0;j<3;j+=2)
if(a[i][j]==0)
{
a[i][j]=y;
cout<<\"Computer turn: \"<goto end;
}
}
}
else if(b==2&&a[1][1]==0)
{
a[1][1]=y;
cout<<\"Computer turn: 2 2\\n\";
goto end;
}
if(!attack())
{
if(b==0)
{
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
int i,j;
a[(rand()%2)*2][(rand()%2)*2]=y;
for(i=0;i<3;i+=2)
{
for(j=0;j<3;j+=2)
if(a[i][j]==y)
cout<<\"Computer \"<}}
else if(a[1][1]==0)
{
a[1][1]=y;
cout<<\"Computer turn: 2 2\\n\";
}
else
{
turn: \"<int i,j;
for(i=0;i<3;i++)
{
\"<for(j=0;j<3;j++){
if(a[i][j]==0)
{
a[i][j]=y;
cout<<\"Computer goto end;
}
}
}
turn: \"< }
}
}
}
end:
cout<}