三子棋游戏

目录

前言

一、设置游戏目录

二、准备

1.设置棋盘

2.玩家下棋

3.电脑下棋

4.游戏结果

三、玩游戏

通过while、continue、break语句实现玩游戏的过程。

四、完整代码

总结

前言

初学C语言,通过数组、函数的调用、随机数的生成可以实现简单的人机三子棋游戏。

一、设置游戏目录

1表示开始游戏,0表示结束游戏,在主函数中通过调用函数实现游戏的开始与结束。

代码如下(示例):

void menu()
{
	printf("************************\n");
	printf("*******1 开始游戏*******\n");
	printf("*******0 结束游戏*******\n");
	printf("************************\n");
	
	return ;
}
int main()
{
	int input=0;
	do
	{
		menu();
		printf("请选择序号:\n");
		scanf("%d",&input);
		switch(input)
		{
			case 1:
				printf("三子棋游戏\n");
				play();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("选择错误,请重新选择\n");
				break;
		}
	}while(input);
	return 0;
}

二、准备

1.设置棋盘

通过宏定义、数组设计打印棋盘的函数。

代码如下(示例):

void print(char board[ROW][COL],int m,int n)
{
	int i,j;
	
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++)
		{
			printf(" %c ",board[i][j]);
			if(j<n-1) printf("|");
		}
		printf("\n");
		if(i<m-1)
		{
			for(j=0;j<n;j++)
			{
				printf("---");
				if(j<n-1) printf("|");
			}
			printf("\n");
		}
	}
}

2.玩家下棋

为程序设计的简便性,规定玩家先下棋。

玩家下棋可以通过以下步骤实现:

①玩家输入两个正整数,分别作为横、纵坐标。

②检验坐标合理性,即是否超出棋盘的范围或者此位置是否已经落子。若合理进行棋盘的打印,否则提示玩家重新输入。显然该过程是一个循环过程,这里采用了continue语句继续循环以及break语句跳出循环。

③打印玩家落子后的棋盘,棋盘上的*代表玩家的棋子。

代码如下(示例):

void PupleMove(char board[ROW][COL])
{
	int a,b;
	
	do
	{
		//玩家输入坐标
		printf("请输入您想下子的位置(横纵坐标都在1-3之间,数字之间以空格间隔)\n");
		scanf("%d %d",&a,&b);
		//检验坐标是否合理
		if(a>3 || b>3)
		{
			printf("输入的坐标不合理,请重新输入\n");
			continue;
		}
		else
		{
			//将玩家输入正确的坐标打印 
			if(board[a-1][b-1]==' ')
			{
				board[a-1][b-1]='*';
				print(board,ROW,COL);
				break;
			}
			else printf("该位置已有棋子,请重新输入\n");
		}
	}while(1);
}

3.电脑下棋

以小编的能力目前只会实现电脑通过随机数下棋,至于算法优化等问题还需要小编进行深入学习。

电脑下棋可以参考“玩家下棋”,通过以下步骤实现:

①因为可以确定随机数生成的范围,所以不需要判断电脑是否落子到棋盘外,只需判断随机数生成的坐标是否被之前的棋子占用。

②打印电脑落子后的棋盘,棋盘上的#代表电脑的棋子。

代码如下(示例):

void ComputerMove(char board[ROW][COL])
{
	do
	{
		srand((unsigned int)time(0)*10);
		int a,b;
		a=rand()%ROW;
		b=rand()%COL;
		if(board[a][b]==' ')
		{
			printf("电脑落子\n");
			board[a][b]='#';
			print(board,ROW,COL);
			break;
		}
	}while(1);
}

4.游戏结果

游戏结束包括三种情况:输、赢、平局。

①输赢的判断标志为任意行、列、对角线都为同一方的棋子即为该方胜利。

②平局的判断标志为该棋盘已经落满棋子但任意行、列、对角线都有双方的棋子。所以小编在判断游戏结束的函数中又调用了判断棋盘是否充满的函数。

代码如下(示例):

bool IsFull(char board[ROW][COL])
{
	int i,j;
	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{
			if(board[i][j]==' ') return false;
		}
	}
	return true;
}

char IfWin(char board[ROW][COL])
{
	char c;
	int i,j;
	int flag=0;
	//判断行
	for(i=0;i<ROW;i++)
	{
		flag=0;
		c=board[i][0];
		for(j=1;j<COL;j++)
		{
			if(c==board[i][j] && board[i][j]!=' ' && c!=' ')
			{
				flag+=1;
			}
		}
		if(flag==ROW-1) return c;
	}
	//判断列 
	for(j=0;j<COL;j++)
	{
		flag=0;
		c=board[0][j];
		for(i=1;i<ROW;i++)
		{
			if(c==board[i][j] && board[i][j]!=' ' && c!=' ')
			{
				flag+=1;
			}
		}
		if(flag==ROW-1) return c;
	}
	//判断对角线
	for(i=1;i<ROW;i++)
	{
		flag=0;
		c=board[0][0];
		for(j=1;j<COL;j++)
		{
			if(c==board[j][j] && board[j][j]!=' ' && c!=' ')
			flag+=1;
		}
		if(flag==ROW-1) return c;
	}
	for(i=1;i<ROW;i++)
	{
		flag=0;
		c=board[0][COL-1];
		for(j=COL-1;j>=0;j--)
		{
			if(c==board[COL-1-j][j] && board[COL-1-j][j]!=' ')
			flag+=1;
		}
		if(flag==ROW) return c;
	}
	//判断棋盘是否满了
	bool judge=false;
	judge=IsFull(board);
	if(judge)
	{
		return 'Q';
	}
} 

三、玩游戏

通过while、continue、break语句实现玩游戏的过程。

代码如下(示例):

void play()
{
	char board[ROW][COL];
	
	//对二维数组进行初始化
	int i,j;
	
	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{
			board[i][j]=' ';
		}
	}
	//打印棋盘 
	print(board,ROW,COL);
	while(1)
	{
		//人下棋
		PupleMove(board);
		//判断是否赢或者平局 
		if(IfWin(board)=='*')
		{
			printf("你赢了!\n");
			break;
		}
		if(IfWin(board)=='Q')
		{
			printf("平局\n");
			break;
		}
		//电脑下棋 
		ComputerMove(board);
		//判断是否赢或者平局 
		if(IfWin(board)=='#')
		{
			printf("电脑赢了!\n");
			break;
		}
		if(IfWin(board)=='Q')
		{
			printf("平局\n");
			break;
		}
	}
}

四、完整代码

代码如下(示例)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>
#define ROW 3
#define COL 3

void menu()
{
	printf("************************\n");
	printf("*******1 开始游戏*******\n");
	printf("*******0 结束游戏*******\n");
	printf("************************\n");
	
	return ;
}

void print(char board[ROW][COL],int m,int n)
{
	int i,j;
	
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++)
		{
			printf(" %c ",board[i][j]);
			if(j<n-1) printf("|");
		}
		printf("\n");
		if(i<m-1)
		{
			for(j=0;j<n;j++)
			{
				printf("---");
				if(j<n-1) printf("|");
			}
			printf("\n");
		}
	}
}

void PupleMove(char board[ROW][COL])
{
	int a,b;
	
	do
	{
		//玩家输入坐标
		printf("请输入您想下子的位置(横纵坐标都在1-3之间,数字之间以空格间隔)\n");
		scanf("%d %d",&a,&b);
		//检验坐标是否合理
		if(a>3 || b>3)
		{
			printf("输入的坐标不合理,请重新输入\n");
			continue;
		}
		else
		{
			//将玩家输入正确的坐标打印 
			if(board[a-1][b-1]==' ')
			{
				board[a-1][b-1]='*';
				print(board,ROW,COL);
				break;
			}
			else printf("该位置已有棋子,请重新输入\n");
		}
	}while(1);
}

void ComputerMove(char board[ROW][COL])
{
	do
	{
		srand((unsigned int)time(0)*10);
		int a,b;
		a=rand()%ROW;
		b=rand()%COL;
		if(board[a][b]==' ')
		{
			printf("电脑落子\n");
			board[a][b]='#';
			print(board,ROW,COL);
			break;
		}
	}while(1);
}

bool IsFull(char board[ROW][COL])
{
	int i,j;
	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{
			if(board[i][j]==' ') return false;
		}
	}
	return true;
}

char IfWin(char board[ROW][COL])
{
	char c;
	int i,j;
	int flag=0;
	//判断行
	for(i=0;i<ROW;i++)
	{
		flag=0;
		c=board[i][0];
		for(j=1;j<COL;j++)
		{
			if(c==board[i][j] && board[i][j]!=' ' && c!=' ')
			{
				flag+=1;
			}
		}
		if(flag==ROW-1) return c;
	}
	//判断列 
	for(j=0;j<COL;j++)
	{
		flag=0;
		c=board[0][j];
		for(i=1;i<ROW;i++)
		{
			if(c==board[i][j] && board[i][j]!=' ' && c!=' ')
			{
				flag+=1;
			}
		}
		if(flag==ROW-1) return c;
	}
	//判断对角线
	for(i=1;i<ROW;i++)
	{
		flag=0;
		c=board[0][0];
		for(j=1;j<COL;j++)
		{
			if(c==board[j][j] && board[j][j]!=' ' && c!=' ')
			flag+=1;
		}
		if(flag==ROW-1) return c;
	}
	for(i=1;i<ROW;i++)
	{
		flag=0;
		c=board[0][COL-1];
		for(j=COL-1;j>=0;j--)
		{
			if(c==board[COL-1-j][j] && board[COL-1-j][j]!=' ')
			flag+=1;
		}
		if(flag==ROW) return c;
	}
	//判断棋盘是否满了
	bool judge=false;
	judge=IsFull(board);
	if(judge)
	{
		return 'Q';
	}
} 

void play()
{
	char board[ROW][COL];
	
	//对二维数组进行初始化
	int i,j;
	
	for(i=0;i<ROW;i++)
	{
		for(j=0;j<COL;j++)
		{
			board[i][j]=' ';
		}
	}
	//打印棋盘 
	print(board,ROW,COL);
	while(1)
	{
		//人下棋
		PupleMove(board);
		//判断是否赢或者平局 
		if(IfWin(board)=='*')
		{
			printf("你赢了!\n");
			break;
		}
		if(IfWin(board)=='Q')
		{
			printf("平局\n");
			break;
		}
		//电脑下棋 
		ComputerMove(board);
		//判断是否赢或者平局 
		if(IfWin(board)=='#')
		{
			printf("电脑赢了!\n");
			break;
		}
		if(IfWin(board)=='Q')
		{
			printf("平局\n");
			break;
		}
	}
}

int main()
{
	int input=0;
	do
	{
		menu();
		printf("请选择序号:\n");
		scanf("%d",&input);
		switch(input)
		{
			case 1:
				printf("三子棋游戏\n");
				play();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("选择错误,请重新选择\n");
				break;
		}
	}while(input);
	return 0;
}

总结

提示:这里对文章进行总结:

通过数组、函数的调用、随机数的生成等可以实现简单的人机三子棋游戏。由于小编能力有限,代码还有许多可以改进的地方,例如:只通过改变宏定义进而实现5*5等更多的棋盘,通过优化算法使机器“更聪明”地下棋,玩家可选择电脑或人先下棋……
小编是一位C语言初学者,如果代码有问题或者有可以改进的地方请大佬们多多指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值