《关于c语言实现简易版(非代码)井字棋小游戏这件事》

  • 首先,要考虑如何实现棋盘,如何存放棋子。
  •  C语言中字符数组可以实现存放位置,用三乘三的字符数组作为棋盘的一部分,C语言中其中一个字符 “ ' ' ”可以作为无棋子时状态,字符 ‘X ’可以代表一方棋子,‘O’作为另一方棋子,用三种字符'- ','+', '|'可以实现棋盘。
  • 先用两个循环进行初始化棋盘
	int i,j;
	for(i=0;i<3;i++)                 //初始化棋盘 
	   for(j=0;j<3;j++)
	       a[i][j]=' ';
  • 再用三个字符做边界
  • 代码如下:
	printf("+--+--+--+\n");
	printf("|%c |%c |%c |\n",a[0][0],a[0][1],a[0][2]);
	printf("+--+--+--+\n");
	printf("|%c |%c |%c |\n",a[1][0],a[1][1],a[1][2]);
	printf("+--+--+--+\n");	
	printf("|%c |%c |%c |\n",a[2][0],a[2][1],a[2][2]);
	printf("+--+--+--+\n");
  • 效果如下:

  • 然后就可以加个游戏开始界面(此步骤过于简单,代码随后一同和其它的登场。)
  • 这里最最重要的必然是考虑如何让电脑走棋,我才用的是让电脑进行一个个位置遍历,然后根据哪个位置最重要(能让电脑自己胜利>能阻止让对方胜利>其他情况),并储存。
  • 为了让电脑确定某位置最高分,我采用平时老师讲的评分机制。
  • 得到的代码如下:
  • int score(i,j)//i代表着 'O';j代表着 'X' 
    { 
    	if(j==2&&i==0)   //如果棋格上没有棋子,但棋格所在行、列、或对角线有两个×,则得5分; 
    	  return 5;
    	else if(i==2&&j==0)  //如果棋格上没有棋子,但棋格所在行、列、或对角线有两个○,则得6分;
          return 6;
        else if(i==1&&j==0) //如果棋格上没有棋子,但棋格所在行、列、或对角线其他棋格有一个○和一个没有棋子,则得4分;
          return 4;
        else if(i==0&&j==1) //如果棋格上没有棋子,但棋格所在行、列、或对角线其他棋格有一个×和一个没有棋子,则得4分;
          return 4;
        else if(i==0&&j==0)  //如果棋格上没有棋子,但棋格所在行、列、或对角线没有棋子,则得2分;
          return 2;
        else if(i==1&&j==1)  //如果棋格上没有棋子,但棋格所在行、列、或对角线有一个○和一个×,则得1分
          return 1;
    } 

  • 电脑遍历数组这个是最简单的,代码如下:
void option_2()         //对数组进行遍历 
{
	int i,j;
	int q,p,max=0,m;
	for(i=0;i<3;i++)
	   	for(j=0;j<3;j++)
	   	    {
			if(a[i][j]==' ')
	   	       {
				m=elect(i,j);
	   	        if(max<m)   //找到此时棋盘最高分的位置 
	   	       {
	   	        max=m;	     
	   	        q=i;p=j;	//记住此位置 
			    }}
            }
	a[q][p]='O';            //电脑下棋 
	print();                //打印棋盘 
}
  • 电脑进行每一个位置遍历,就需要通过某种机制来确定某个位置是否是自己最佳选择,我选用的是将每个位置对应的行和列和对角线的情况:有多少个X和多少个O。然后将此位置最多O的情况(即对电脑来说是目前最好等情况) 用m记录下来,接下来会用到。确定了某个位置的最高分的情况后,记录在temp中,返回后记录。
  • 代码如下:
int elect(int i,int j)   //确定某个位置的所在行或所在列或所在对角线的 X,O 的情况,
也包括没有的情况  
{
	int k1=0,k2=0;
	int i1,j1,temp,k;
	for(j1=0;j1<3;j1++) //判断某行有多少个'X','O' 
	   {
		if(a[i][j1]=='X')
			 k2++;
		if(a[i][j1]=='O')
			 k1++;	
		}
	temp=score(k1,k2);   //用来记录所在行有多少分 
	k1=0;k2=0;
	for(i1=0;i1<3;i1++)  //判断某列有多少个'X','O' 
	   {
		if(a[i1][j]=='X')
			 k2++;
		if(a[i1][j]=='O')
			 k1++;	
	    }
	k=score(k1,k2);     //用来记录所在列有多少分 
	temp=temp>k?temp:k; //判断所在行所在列最高分 
	k1=0;k2=0;
	if(i==2&&j==0||i==0&&j==2||i==1&&j==1) //判断特殊点(右上角和左下角及中间位置
)所在的对角线又多少个 'X','O' 
	{
	   for(i1=2;i1>=0;i1--)
	    {
	    	j1=2-i1;
	    	if(a[i1][j1]=='X')
	    	   k2++;
	    	if(a[i1][j1]=='O')
	    	   k1++;
		} 
    k=score(k1,k2);      
	temp=temp>k?temp:k;
	k1=0;k2=0;
	}
	if(i==j) //判断特殊点(左上角或右下角及中间位置)所在的对角线又多少个 'X','O' 
	{
		for(i1=2;i1>=0;i1--)
	    {
	    	j1=i1;
	    	if(a[i1][j1]=='X')
	    	   k2++;
	    	if(a[i1][j1]=='O')
	    	   k1++;
	    }
	k=score(k1,k2);
	temp=temp>k?temp:k;
    }
    return temp;
}
  • 如何让电脑走棋,基本上已经解决了,接下来就需要进行胜利或平局的判定了,判断方法基本上玩过井字棋的都知道,就不再叙述了。这个我选择了用代码堆出判定(此方法被老师上课吐槽过):
void judge()                //判断此时是否有一方赢了 
{
	int temp=0;
	if(a[0][0]==a[0][1]&&a[0][1]==a[0][2]&&a[0][0]!=' ')    //第一行 
	  {
	  	if(a[0][0]=='X')                                    //如果全为'X'则标记 temp=1  
	  	   temp=1;
	  	else
	  	   temp=2;                                          //如果全为'O'则标记 temp=2 
	  }
	else if(a[1][0]==a[1][1]&&a[1][1]==a[1][2]&&a[1][0]!=' ') //第二行 
	  {
	  	if(a[1][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	else if(a[2][0]==a[2][1]&&a[2][1]==a[2][2]&&a[2][0]!=' ') //第三行 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	else if(a[0][0]==a[1][0]&&a[1][0]==a[2][0]&&a[0][0]!=' ') //第一列 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][1]==a[1][1]&&a[1][1]==a[2][1]&&a[0][1]!=' ') //第二列 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][2]==a[1][2]&&a[1][2]==a[2][2]&&a[0][2]!=' ') //第三列 
	   {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][0]==a[1][1]&&a[1][1]==a[2][2]&&a[0][0]!=' ') //主对角线 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][2]==a[1][1]&&a[1][1]==a[2][0]&&a[2][0]!=' ') //副对角线 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  if(temp==1)                           //如果temp==1,则说明此时玩家胜利,若为temp==2,则说明电脑胜利 
	  {
	  	printf("GAME OVER\n");
		printf("YOU WIN!");
	  	exit(0);
	  }
	  if(temp==2)
	  {
	  	printf("GAME OVER\n");
		printf("THE COMPUTER WIN!");
	  	exit(0);
	  }
}
  • 人机对战,由于第一步比较特殊,我就将它单独隔离了:它需要由人决定谁先走。
  • 代码如下(包含游戏初始页面(超简陋版)):
void menu()  //输出游戏开始页面 
{ 
                void option_1(c1);
	printf("\t\t------------------------------------------\n");
	printf("\t\t                 井字棋\n");
	printf("\t\t              玩家棋子为:X\n");       
	printf("\t\t              电脑棋子为:O\n");
	printf("\t\t------------------------------------------\n");
	printf("是否先走?\n");
	printf("是:y  否:n\n");
	scanf("%c",&c1);
	if(c1!='y'&&c1!='n') //如果输入的字符不是y或者n,则终止程序  
	   {
	   	printf("输入错误,程序终止!");  
	    exit(0);                   
	   }
	option_1(c1);
}
void option_1(c1) //第一步不同情况 
{
   void Py();           //Py函数在次函数后面,先声明才能够调用 
   int i,j;
   srand(time(NULL));   //用来防止电脑每次用rand函数都取同样值,具体作用请自行去网上查找 
   if(c1=='y')          //如果玩家要选择自己先走 
   {
   	printf("请输入你要下的位置的坐标(x,y):");
	scanf("%d,%d",&i,&j);
	a[i][j]='X';    
   }
   else                //电脑先走,电脑通过rand函数来确定自己第一步走在哪里 
   {
     i=rand()%3;       //随机选取0~2之间的数字作为横坐标 
	 j=rand()%3;       //随机选取0~2之间的数字作为纵坐标
   	a[i][j]='O';
   }
   print(a);           //输出棋盘情况 
   Py();	           //调用Py函数,进行博弈 
}
  • 所有的基本上都已经解决了,就剩下用一个循环来控制人与电脑的对弈过程了,根据玩家选择的谁先走,来决定接下来的顺序,代码如下(其中包含着平局判定):
void Py()                              //控制对弈次数以及是否为平局 
{
	int i,j,step=1;                    //temp代表已走几步棋,最多走九步 
	while(step<=9)
	{
		if(c1=='n'||step>1)           //如果玩家选择电脑先走或者轮到玩家,则玩家开始下子 
		{
		 printf("轮到你了:");
		 scanf("%d,%d",&i,&j);
		 a[i][j]='X';
		 step++;                      //两个函数分别打印棋盘,并判断此时是否有一方已经胜利 
		 print();
		 judge(); 
		 if(step>=9)
		   break;	
		}
		printf("轮到电脑了:\n");     //轮到电脑的回合 
		option_2();                   //引用函数,确定电脑要放棋子的位置上 
		step++;
		judge();
		if(step>=9)
		   break;
	}
	printf("TIE GAME!\n");            //如果走完九步,则说明双方平局 
	printf("GAME OVER!");
}

  • 主函数是必不可缺的:
int main()                           
{
	int i,j;
	for(i=0;i<3;i++)                 //初始化棋盘 
	   for(j=0;j<3;j++)
	       a[i][j]=' ';
                menu();                          //调用函数,打印游戏开始页面 
	getchar();
	getchar();                       //目前可有可无的函数 
	return 0;
} 
  •  完整代码如下:
// 井字棋
 
#include"stdio.h"
#include"stdlib.h"
#include"time.h"

char a[3][3];  //用来储存棋盘各个位置的情况 
char c1;       //用来储存玩家选择第一步是否为自己先走,且在函数间传递信息 

void menu()  //输出游戏开始页面 
{ 
                void option_1(c1);
	printf("\t\t------------------------------------------\n");
	printf("\t\t                 井字棋\n");
	printf("\t\t              玩家棋子为:X\n");       
	printf("\t\t              玩家棋子为:O\n");
	printf("\t\t------------------------------------------\n");
	printf("是否先走?\n");
	printf("是:y  否:n\n");
	scanf("%c",&c1);
	if(c1!='y'&&c1!='n') //如果输入的字符不是y或者n,则终止程序  
	   {
	   	printf("输入错误,程序终止!");  
	    exit(0);                   
	   }
	option_1(c1);
}

void print()    //输出棋盘的情况 
{
	printf("+--+--+--+\n");
	printf("|%c |%c |%c |\n",a[0][0],a[0][1],a[0][2]);
	printf("+--+--+--+\n");
	printf("|%c |%c |%c |\n",a[1][0],a[1][1],a[1][2]);
	printf("+--+--+--+\n");	
	printf("|%c |%c |%c |\n",a[2][0],a[2][1],a[2][2]);
	printf("+--+--+--+\n");
}

void option_1(c1) //第一步不同情况 
{
   void Py();           //Py函数在次函数后面,先声明才能够调用 
   int i,j;
   srand(time(NULL));   //用来防止电脑每次用rand函数都取同样值,具体作用请自行去网上查找 
   if(c1=='y')          //如果玩家要选择自己先走 
   {
   	printf("请输入你要下的位置的坐标(x,y):");
	scanf("%d,%d",&i,&j);
	a[i][j]='X';    
   }
   else                //电脑先走,电脑通过rand函数来确定自己第一步走在哪里 
   {
     i=rand()%3;       //随机选取0~2之间的数字作为横坐标 
	 j=rand()%3;       //随机选取0~2之间的数字作为纵坐标
   	a[i][j]='O';
   }
   print(a);           //输出棋盘情况 
   Py();	           //调用Py函数,进行博弈 
}

int score(i,j)//i代表着 'O';j代表着 'X' 
{ 
	if(j==2&&i==0)   //如果棋格上没有棋子,但棋格所在行、列、或对角线有两个×,则得5分; 
	  return 5;
	else if(i==2&&j==0)  //如果棋格上没有棋子,但棋格所在行、列、或对角线有两个○,则得6分;
      return 6;
    else if(i==1&&j==0) //如果棋格上没有棋子,但棋格所在行、列、或对角线其他棋格有一个○和一个没有棋子,则得4分;
      return 4;
    else if(i==0&&j==1) //如果棋格上没有棋子,但棋格所在行、列、或对角线其他棋格有一个×和一个没有棋子,则得4分;
      return 4;
    else if(i==0&&j==0)  //如果棋格上没有棋子,但棋格所在行、列、或对角线没有棋子,则得2分;
      return 2;
    else if(i==1&&j==1)  //如果棋格上没有棋子,但棋格所在行、列、或对角线有一个○和一个×,则得1分
      return 1;
} 

int elect(int i,int j)   //确定某个位置的所在行或所在列或所在对角线的 X,O 的情况,也包括没有的情况  
{
	int k1=0,k2=0;
	int i1,j1,temp,k;
	for(j1=0;j1<3;j1++) //判断某行有多少个'X','O' 
	   {
		if(a[i][j1]=='X')
			 k2++;
		if(a[i][j1]=='O')
			 k1++;	
		}
	temp=score(k1,k2);   //用来记录所在行有多少分 
	k1=0;k2=0;
	for(i1=0;i1<3;i1++)  //判断某列有多少个'X','O' 
	   {
		if(a[i1][j]=='X')
			 k2++;
		if(a[i1][j]=='O')
			 k1++;	
	    }
	k=score(k1,k2);     //用来记录所在列有多少分 
	temp=temp>k?temp:k; //判断所在行所在列最高分 
	k1=0;k2=0;
	if(i==2&&j==0||i==0&&j==2||i==1&&j==1) //判断特殊点(右上角和左下角及中间位置)所在的对角线又多少个 'X','O' 
	{
	   for(i1=2;i1>=0;i1--)
	    {
	    	j1=2-i1;
	    	if(a[i1][j1]=='X')
	    	   k2++;
	    	if(a[i1][j1]=='O')
	    	   k1++;
		} 
    k=score(k1,k2);      
	temp=temp>k?temp:k;
	k1=0;k2=0;
	}
	if(i==j) //判断特殊点(左上角或右下角及中间位置)所在的对角线又多少个 'X','O' 
	{
		for(i1=2;i1>=0;i1--)
	    {
	    	j1=i1;
	    	if(a[i1][j1]=='X')
	    	   k2++;
	    	if(a[i1][j1]=='O')
	    	   k1++;
	    }
	k=score(k1,k2);
	temp=temp>k?temp:k;
    }
    return temp;
}

void option_2()         //对数组进行遍历 
{
	int i,j;
	int q,p,max=0,m;
	for(i=0;i<3;i++)
	   	for(j=0;j<3;j++)
	   	    {
			if(a[i][j]==' ')
	   	       {
				m=elect(i,j);
	   	        if(max<m)   //找到此时棋盘最高分的位置 
	   	       {
	   	        max=m;	     
	   	        q=i;p=j;	//记住此位置 
			    }}
            }
	a[q][p]='O';            //电脑下棋 
	print();                //打印棋盘 
}

void judge()                //判断此时是否有一方赢了 
{
	int temp=0;
	if(a[0][0]==a[0][1]&&a[0][1]==a[0][2]&&a[0][0]!=' ')    //第一行 
	  {
	  	if(a[0][0]=='X')                                    //如果全为'X'则标记 temp=1  
	  	   temp=1;
	  	else
	  	   temp=2;                                          //如果全为'O'则标记 temp=2 
	  }
	else if(a[1][0]==a[1][1]&&a[1][1]==a[1][2]&&a[1][0]!=' ') //第二行 
	  {
	  	if(a[1][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	else if(a[2][0]==a[2][1]&&a[2][1]==a[2][2]&&a[2][0]!=' ') //第三行 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	else if(a[0][0]==a[1][0]&&a[1][0]==a[2][0]&&a[0][0]!=' ') //第一列 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][1]==a[1][1]&&a[1][1]==a[2][1]&&a[0][1]!=' ') //第二列 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][2]==a[1][2]&&a[1][2]==a[2][2]&&a[0][2]!=' ') //第三列 
	   {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][0]==a[1][1]&&a[1][1]==a[2][2]&&a[0][0]!=' ') //主对角线 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  	else if(a[0][2]==a[1][1]&&a[1][1]==a[2][0]&&a[2][0]!=' ') //副对角线 
	  {
	  	if(a[0][0]=='X')
	  	   temp=1;
	  	else
	  	   temp=2;
	  }
	  if(temp==1)                           //如果temp==1,则说明此时玩家胜利,若为temp==2,则说明电脑胜利 
	  {
	  	printf("GAME OVER\n");
		printf("YOU WIN!");
	  	exit(0);
	  }
	  if(temp==2)
	  {
	  	printf("GAME OVER\n");
		printf("THE COMPUTER WIN!");
	  	exit(0);
	  }
}

void Py()                              //控制对弈次数以及是否为平局 
{
	int i,j,step=1;                    //temp代表已走几步棋,最多走九步 
	while(step<=9)
	{
		if(c1=='n'||step>1)           //如果玩家选择电脑先走或者轮到玩家,则玩家开始下子 
		{
		 printf("轮到你了:");
		 scanf("%d,%d",&i,&j);
		 a[i][j]='X';
		 step++;                      //两个函数分别打印棋盘,并判断此时是否有一方已经胜利 
		 print();
		 judge(); 
		 if(step>=9)
		   break;	
		}
		printf("轮到电脑了:\n");     //轮到电脑的回合 
		option_2();                   //引用函数,确定电脑要放棋子的位置上 
		step++;
		judge();
		if(step>=9)
		   break;
	}
	printf("TIE GAME!\n");            //如果走完九步,则说明双方平局 
	printf("GAME OVER!");
}

int main()                           
{
	int i,j;
	for(i=0;i<3;i++)                 //初始化棋盘 
	   for(j=0;j<3;j++)
	       a[i][j]=' ';
                menu();                          //调用函数,打印游戏开始页面 
	getchar();
	getchar();                       //目前可有可无的函数 
	return 0;
} 

  • 最后附上:此井字棋代码对于经常见几十行代码的人来讲过于长(二百多行),且顺序混乱,不易阅读,代码并不完善,不能够阻止玩家重复下某一位置。
  • 但,应付作业应该是绰绰有余了。
  • 如有时间和精力,且需要这几百行代码,建议自行更改,让代码更加完善。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值