井字棋(C语言实现,可运行玩耍,自行编写)

井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜。

很简单,就是在画一个井图形里面画符号,谁先到3个就赢了.

试想一下,我们第一步肯定是需要读入输入的符号,我们用 X  和  O  代替. 

那记录判断我们是否赢了的方法, 需要用到数组和遍历

然后就是判断结果.就可以了.

 

下面开始实施阶段:

按照我们理想化的步骤来实现

第一步

我们是想要如图的图案,那就输入回车和制表符,很简单,但是不定长的数字就不好控制了,所以我们用

for循环依次输出:

printf("\t 0 \t 1 \t 2 \t\n\n");
	for(int i=0;i<3;i++){
		printf(" %d\t ___\t___\t___\t\n\n",i);
	}

第二步:实现输入字符

 需要我们用数组保存我们输入的坐标地址

定义数组

int board[size][size];

等玩家输入对应坐标后,对二维数组的值进行对应赋值,

printf("玩家一请输入坐标\n");

scanf("%d %d",&i,&j);

board[i][j]=1;

printf("请玩家二输入坐标\n");

scanf("%d %d",&i,&j);

board[i][j]=0;

我们会根据对应的数组的值进行遍历,是我们需要的就赋值对应图形的形状  X   O

遍历的话都是一样的,同样道理,这里列出来一个

for(int i=0; i<size;i++){
	for(int j=0;j<size; j++ )
	{
				
				if(board[i][j]==1){
					printf("_X_");
					ope++;
					if(ope%size==0){
						if(ope/size==size){
							printf("\n\n\n");
						}else if(ope/size<size){
							
							printf("\n\n\n %d\t",ope/size);
						}
					}else{
						printf("\t");
					}	
					
				}else if(board[i][j]==-1){
					printf("___");
					ope++;
					if(ope%size==0){
						if(ope/size==size){
							printf("\n\n\n");
						}else if(ope/size<size){
							
							printf("\n\n\n %d\t",ope/size);
						}
					}else{
						printf("\t");
					}
				}else if(board[i][j] == 0){
					printf("_O_");
					ope++;
					if(ope%size==0){
						if(ope/size==size){
							printf("\n\n\n");
						}else if(ope/size<size){
							
							printf("\n\n\n %d\t",ope/size);
						}
					}else{
						printf("\t");
					}
				}
			}
		}

根据不同的数,进行不同的赋值

然后我们可以根据输入对应的坐标进行游戏了

第三步:判断输赢家. 

那如何让电脑判定谁赢了呢?

接下来,就是遍历,计数每一行,每一列,正对角线,副对角线是否出现同样图案一条线的了,玩家一先划

,接着玩家二画图案.

我们可以根据玩家输入的数字进行对对应的二维数组赋值,然后分三次遍历计数,

第一次,先确定一行,遍历列,这样就把每一行便利判断完了

	//检查行
		for (int i=0; i<size ; i++ )
		{
				numofo=0;
				numofx=0;
				for( j=0; j<size; j++ ){
					if( board[i][j] == 1){
						numofx++;
					//	printf("numofx的值是:%d\n",numofx);
					}else if(board[i][j]==0){
						numofo++;
					//	printf("numofo的值是:%d\n",numofo);
					}else{
					
					}
				}
				if(numofo == size){
					result = 0;
					cnt_o++;
				} else if(numofx == size) {
					result =1;
					cnt_x++;
				} else{
					result =-1;
				}

			}

第二次,和第一次差不多,调换了以下顺序,先确定列,遍历行,逐渐加一,直到把所有的列遍历完

//检查列

			for( j=0; j<size ; j++){
				numofo = numofx = 0;
				for( i=0; i<size; i++){
					if( board[i][j] == 1){
						numofx ++;
					}else if(board[i][j]==0) {
						numofo ++;
					}
				}
				if(numofo == size){
					result = 0;
					cnt_o++;  
				}else if(numofx == size){
					result = 1;
					cnt_x++;
				}
			}

第三次,正对角线

每次的行号和列号是相等的

//正对角线
		numofo = numofx = 0;
		for(i=0; i<size; i++){
			if( board[i][i] == 1){
				numofx ++;
			}else if(board[i][j]==0) {
				numofo ++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if( numofx == size){
			result = 1;
			cnt_x++;
		}
	//	printf("3.检查的正对角线\n cnt_o值是:%d\n cnt_x值是:%d\n",cnt_o,cnt_x);

	//斜对角线
		numofo = numofx = 0;
		for( i=0; i<size; i++ ){
			if( board[i][size-i-1] == 1){
				numofx++;
			}else if( board[i][size-i-1] == 0){
				numofo++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if(numofx == size){
			result = 1;
			cnt_x++;
		}

第四次,斜对角线

和正对角线不同的是, 斜对角线对应数组行列不一样.

具体的话,验算一下,相对于正对角线,加了一个size,但是我们是从0计算坐标的,所以再减去1,对比一下, 就知道了:

board[i][size - i - 1]

numofo = numofx = 0;
		for( i=0; i<size; i++ ){
			if( board[i][size-i-1] == 1){
				numofx++;
			}else if( board[i][size-i-1] == 0){
				numofo++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if(numofx == size){
			result = 1;
			cnt_x++;
		}

检查完了后,如何判断是否够一条线呢?  就是在每次判断同样图案后,加一个计数器

当等于一条线的长度时,就对对应的数加一,这样我们就可以判断, 游戏是否结束, 并且谁获胜,或者是平局了

if( numofo == size){
            result = 0;
            cnt_o++;
        }else if(numofx == size){
            result = 1;
            cnt_x++;
        }

第六步:就是判断游戏结束

当游戏的九个空格输入完前,  判断游戏是否结束,  我们的游戏是否继续,我们使用嵌套

do{

}

while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);

第七步:  根据具体计数器的结果, 判断谁胜谁负

if(cnt_x==1 && cnt_o==0&& count<=(size*size-1)/2){
        printf("恭喜玩家一,你赢啦!\n");
    }else if(cnt_o==1 && cnt_x==0){
        printf("恭喜玩家二,你赢啦!\n");
    }else if(cnt_o==0 &&cnt_x==0 && count==(size*size-1)/2){
        printf("恭喜双方打成平局,以和为贵!");
    }else if(cnt_o==1 &&cnt_x==1 ){
        printf("恭喜你们双赢啦!\n");
        printf("请按回车键继续:\n");
        getchar();getchar();
        printf("开个玩笑,其实是 玩家一 赢了!\n");
    }

第八步,其实现在大概已经实现了

但是还有几个小改进,需要注意一下

①如果我们想要让玩家每次输入对应坐标后,  就可以看见对应符号在数组中的位置,  就需要刚开始第一部输入的表格, 然后我们接着遍历输入对应的符号就可以了.

②因为我们判断游戏结束, 是当两个人都输入完后才判断的,  有一种情况是,  玩家一最后才输入完,

然后格子占满了,  玩家二不用输入了,仍然会出现让玩家二输入的情况.   

我们的解决办法是, 在玩家二输入后边 加了一个计数器,  当 

while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);

 当玩家二输入4次时候,  如果判断没有玩家赢的话,  需要玩家一接着输入一次

所以我们 在玩家二输入四次的时候,  就跳出循环, 给玩家一,  单独来一个套娃,  (这里作者能力有限,只能套娃)  ,就是把前面的重新拷贝一下,  把玩家二的删除救行了.   这里就解决了最后一次不能输入的问题

源代码奉上:

#include <stdio.h>

int main(int argc, char *argv[])
{
	
	const int size = 3;
	int board[size][size];
	int i,j;
	int numofx=0;
	int numofo=0;
	int result=-1; //-1:没人赢,1:x赢, 0:0赢
	int cnt_o=0;
	int cnt_x=0;
	int count=0;
	for( i=0; i<size; i++){
			for( j=0; j<size; j++){
				board[i][j]=-1;
			}
		}
	//	printf("%d",board[2][2]);

	//读入矩阵
	printf("\t 0 \t 1 \t 2 \t\n\n");
	for(int i=0;i<3;i++){
		printf(" %d\t ___\t___\t___\t\n\n",i);
	}
	do  {
		//printf("游戏还未结束,请继续:\n");
		printf("玩家一请输入坐标\n");
		scanf("%d %d",&i,&j);
		
		printf("\n");
		printf("\t");
		for(int k=0;k<size;k++){
			printf("%d \t",k);
			
		}
		
		
	//	printf("\t 0 \t 1 \t 2 \t");
		printf("\n\n");
		printf(" 0 \t");
		board[i][j]=1;
		int ope=0;
		for(int i=0; i<size;i++){
			for(int j=0;j<size; j++ )
			{
				
				if(board[i][j]==1){
					printf("_X_");
					ope++;
					if(ope%size==0){
						if(ope/size==size){
							printf("\n\n\n");
						}else if(ope/size<size){
							
							printf("\n\n\n %d\t",ope/size);
						}
					}else{
						printf("\t");
					}	
					
				}else if(board[i][j]==-1){
					printf("___");
					ope++;
					if(ope%size==0){
						if(ope/size==size){
							printf("\n\n\n");
						}else if(ope/size<size){
							
							printf("\n\n\n %d\t",ope/size);
						}
					}else{
						printf("\t");
					}
				}else if(board[i][j] == 0){
					printf("_O_");
					ope++;
					if(ope%size==0){
						if(ope/size==size){
							printf("\n\n\n");
						}else if(ope/size<size){
							
							printf("\n\n\n %d\t",ope/size);
						}
					}else{
						printf("\t");
					}
				}
			}
		}

	//	printf("board[%d][%d]=%d\n",i,j,board[i][j]);
		printf("请玩家二输入坐标\n");
		
		scanf("%d %d",&i,&j);
		count++;
		printf("\n");
		printf("\t");
		for(int k=0;k<size;k++){
			printf("%d \t",k);
			
		}
		
		
	//	printf("\t 0 \t 1 \t 2 \t");
		printf("\n\n");
		printf(" 0 \t");
		board[i][j]=0;
				int opes=0;
		for(int i=0; i<size;i++){
			for(int j=0;j<size; j++ )
			{
				
				if(board[i][j]==1){
					printf("_X_");
					opes++;
					if(opes%size==0){
						if(opes/size==size){
							printf("\n\n\n");
						}else if(opes/size<size){
							
							printf("\n\n\n %d\t",opes/size);
						}
					}else{
						printf("\t");
					}	
					
				}else if(board[i][j]==-1){
					printf("___");
					opes++;
					if(opes%size==0){
						if(opes/size==size){
							printf("\n\n\n");
						}else if(opes/size<size){
							
							printf("\n\n\n %d\t",opes/size);
						}
					}else{
						printf("\t");
					}
				}else if(board[i][j] == 0){
					printf("_O_");
					opes++;
					if(opes%size==0){
						if(opes/size==size){
							printf("\n\n\n");
						}else if(opes/size<size){
							
							printf("\n\n\n %d\t",opes/size);
						}
					}else{
						printf("\t");
					}
				}
			}
		}
	//	printf("board[%d][%d]=%d\n",i,j,board[i][j]);
	//	printf("%d",board[2][2]);
		
		//检查行
		for (int i=0; i<size ; i++ )
		{
				numofo=0;
				numofx=0;
				for( j=0; j<size; j++ ){
					if( board[i][j] == 1){
						numofx++;
					//	printf("numofx的值是:%d\n",numofx);
					}else if(board[i][j]==0){
						numofo++;
					//	printf("numofo的值是:%d\n",numofo);
					}else{
					
					}
				}
				if(numofo == size){
					result = 0;
					cnt_o++;
				} else if(numofx == size) {
					result =1;
					cnt_x++;
				} else{
					result =-1;
				}

			}

	//	printf("1.检查的行\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);

		//检查列

			for( j=0; j<size ; j++){
				numofo = numofx = 0;
				for( i=0; i<size; i++){
					if( board[i][j] == 1){
						numofx ++;
					}else if(board[i][j]==0) {
						numofo ++;
					}
				}
				if(numofo == size){
					result = 0;
					cnt_o++;  
				}else if(numofx == size){
					result = 1;
					cnt_x++;
				}
			}
	//	printf("2.检查的列\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);
		
	//正对角线
		numofo = numofx = 0;
		for(i=0; i<size; i++){
			if( board[i][i] == 1){
				numofx ++;
			}else if(board[i][j]==0) {
				numofo ++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if( numofx == size){
			result = 1;
			cnt_x++;
		}
	//	printf("3.检查的正对角线\n cnt_o值是:%d\n cnt_x值是:%d\n",cnt_o,cnt_x);

	//斜对角线
		numofo = numofx = 0;
		for( i=0; i<size; i++ ){
			if( board[i][size-i-1] == 1){
				numofx++;
			}else if( board[i][size-i-1] == 0){
				numofo++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if(numofx == size){
			result = 1;
			cnt_x++;
		}
	//	printf("4.检查的斜对角线\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);

	}while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);
	//int count=9;
	if(cnt_x==0 && cnt_o==0 && count==(size*size-1)/2){
			do  {
					//printf("游戏还未结束,请继续:\n");
					printf("玩家一请输入坐标\n");
					scanf("%d %d",&i,&j);
					
					printf("\n");
					printf("\t");
					for(int k=0;k<size;k++){
						printf("%d \t",k);
					
					}
		
		
	//				printf("\t 0 \t 1 \t 2 \t");
					printf("\n\n");
					printf(" 0 \t");
					board[i][j]=1;
					int ope=0;
					for(int i=0; i<size;i++){
						for(int j=0;j<size; j++ )
						{
				
						if(board[i][j]==1){
							printf("_X_");
							ope++;
							if(ope%size==0){
								if(ope/size==size){
									printf("\n\n\n");
								}else if(ope/size<size){
									
									printf("\n\n\n %d\t",ope/size);
								}
							}else{
								printf("\t");
							}	
							
						}else if(board[i][j]==-1){
							printf("___");
							ope++;
							if(ope%size==0){
								if(ope/size==size){
									printf("\n\n\n");
								}else if(ope/size<size){
									
									printf("\n\n\n %d\t",ope/size);
								}
							}else{
								printf("\t");
							}
						}else if(board[i][j] == 0){
							printf("_O_");
							ope++;
							if(ope%size==0){
								if(ope/size==size){
									printf("\n\n\n");
								}else if(ope/size<size){
									
									printf("\n\n\n %d\t",ope/size);
								}
							}else{
								printf("\t");
							}
						}
					}
				}


		
		

		
		//检查行
		for (int i=0; i<size ; i++ )
			{
				numofo=0;
				numofx=0;
				for( j=0; j<size; j++ ){
					if( board[i][j] == 1){
						numofx++;
					//	printf("numofx的值是:%d\n",numofx);
					}else if(board[i][j]==0){
						numofo++;
					//	printf("numofo的值是:%d\n",numofo);
					}else{
					
					}
				}
				if(numofo == size){
					result = 0;
					cnt_o++;
				} else if(numofx == size) {
					result =1;
					cnt_x++;
				} else{
					result =-1;
				}

			}

	//	printf("1.检查的行\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);

		//检查列

			for( j=0; j<size ; j++){
				numofo = numofx = 0;
				for( i=0; i<size; i++){
					if( board[i][j] == 1){
						numofx ++;
					}else if(board[i][j]==0) {
						numofo ++;
					}
				}
				if(numofo == size){
					result = 0;
					cnt_o++;  
				}else if(numofx == size){
					result = 1;
					cnt_x++;
				}
			}
	//	printf("2.检查的列\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);
		
	//正对角线
		numofo = numofx = 0;
		for(i=0; i<size; i++){
			if( board[i][i] == 1){
				numofx ++;
			}else if(board[i][j]==0) {
				numofo ++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if( numofx == size){
			result = 1;
			cnt_x++;
		}
	//	printf("3.检查的正对角线\n cnt_o值是:%d\n cnt_x值是:%d\n",cnt_o,cnt_x);

	//斜对角线
		numofo = numofx = 0;
		for( i=0; i<size; i++ ){
			if( board[i][size-i-1] == 1){
				numofx++;
			}else if( board[i][size-i-1] == 0){
				numofo++;
			}
		}
		if( numofo == size){
			result = 0;
			cnt_o++;
		}else if(numofx == size){
			result = 1;
			cnt_x++;
		}
	//	printf("4.检查的斜对角线\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);

	}while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);
	}
	
	if(cnt_x==1 && cnt_o==0&& count<=(size*size-1)/2){
		printf("恭喜玩家一,你赢啦!\n");
	}else if(cnt_o==1 && cnt_x==0){
		printf("恭喜玩家二,你赢啦!\n");
	}else if(cnt_o==0 &&cnt_x==0 && count==(size*size-1)/2){
		printf("恭喜双方打成平局,以和为贵!");
	}else if(cnt_o==1 &&cnt_x==1 ){
		printf("恭喜你们双赢啦!\n");
		printf("请按回车键继续:\n");
		getchar();getchar();
		printf("开个玩笑,其实是 玩家一 赢了!\n");
	}
	return 0;
}



  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值