用c语言实现三子棋

这里有完整代码:c语言: 测试仓库 (gitee.com)

1.判断是否要玩游戏

        (1)打印一个游戏菜单,输入1是进入游戏,输入0是退出游戏

2.game()函数

        (1)初始化棋盘,创建Board放置棋子

        (2)创建Print函数打印棋盘

3.通过IsWin( )函数判断是否输赢

        可以使用cheer变量控制输赢的条件

4.创建判断是否平局的函数Isfull( )

        (1)棋子占满返回1,否则则返回0

        (2)如果返回1则退出game()函数

1.判断是否要玩游戏

(1)首先使用menu()函数打印一个菜单,选择1进入游戏,选择0退出游戏

​
void menu()
{
	printf("*****1.play*******\n");
	printf("******************\n");
	printf("*****0.exit*******\n");
}

​

(2)用switch判断是否进入游戏,如果input为1则进入游戏,如果input为0则退出游戏,输入其他则提示重新数输入。为了多次玩游戏,将整个switch语句放在while循环中,当input不为零循环继续。

int main()
{
	srand((unsigned)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请输入>:");
		scanf("%d", &input);
		switch(input)
		{
	     case 1:
			  game();
			  break;
	     case 0:
			  printf("退出游戏>\n");
			  break;
		 default:
			 printf("请重新输入!\n");
			  break;
		}

	} while (input);

	return 0;
}


2.game()函数

(1)首先初始化一个二维字符数组,行为ROW,列为COL,我们用三行三列举例

char Board[ROW][COL];

(2)创建函数InintBoard()初始化棋盘,使用空格初始化数组。

一维数组列元素的下标是从0到COL-1,一维数组行元素的下标是从0到ROW-1,所以使用一个for行循环嵌套一个for列循环

void InintBoard(char Board[ROW][COL])
{
	int i = 0;//行初始化
	for (i = 0; i < ROW; i++)
	{
		int j = 0;//列初始化
		for (j = 0; j < COL; j++)
		{
			Board[i][j] = ' ';
		}
	}
}

(3)创建函数PrintBoard()打印棋盘

这里想要打印二维数组中放置的棋子Board[i][j],需要再次使用一个for行循环嵌套一个for列循环:


void PrintBoard(char Board[ROW][COL])
{
	int i = 0;
	for (i = 0; i < ROW; i++)
	{
		int j = 0;
		for (j = 0; j < COL; j++)
		{
			printf(" %c ", Board[i][j]);
		}

		printf("\n");
	}
}

 想要打印出这样的棋盘 :

我们可以把棋盘分为两部分:

第一部分可以分为Board[0][0]  |   Board[0][1]  |  Board[0][2]     

可以看成 ---------->         数组        |          数组       |        数组        ‘|’   

也就是每个数组隔着一个 | ,但是最后一个带引号的 ‘|’ 不打印,所以要在循环中加限制条件,当循环变量j等于COL就不打印最后一个 | 

		int j = 0;
		for (j = 0; j < COL; j++)
		{
			printf(" %c ", Board[i][j]);
			//每打印一个数组元素就打印一个'|',但最后一个'|'不打印。
			if (j < COL - 1)
			{
				printf("|");
			}
		}

第二个部分和第一个部分非常相似

第二个部分可以分成:---  |  ---  |  ---

可以看成-------------->   ---  |  ---  |  ---  '|'

也就是每个 --- 隔着一个 | ,但是最后一个带引号的 ‘|’ 不打印,所以要在循环中加限制条件,n等于COL就不打印最后一个 | 

			int n = 0;
			for (n = 0; n < COL; n++)
			{
				printf("---");
				//最后一行不打印’----|----‘,和上面同理
				if (n < COL - 1)
				{
					printf("|");
				}
			}

知道了上面的逻辑,现在只要把三个部分的代码拼在一起即可:

//每打印一个元素,后面用’|‘分割
void PrintBoard(char Board[ROW][COL])
{
	int i = 0;
	for (i = 0; i < ROW; i++)
	{
		int j = 0;
		for (j = 0; j < COL; j++)
		{
			printf(" %c ", Board[i][j]);
			//每打印一个数组元素就打印一个'|',但最后一个'|'不打印。
			if (j < COL - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		//每打印一行元素,就打印一行’----|----‘分割
		if(i<ROW-1)
		{
			int n = 0;
			for (n = 0; n < COL; n++)
			{
				printf("---");
				//最后一行不打印’----|----‘,和上面同理
				if (n < COL - 1)
				{
					printf("|");
				}
			}
		}
		printf("\n");
	}
}

(4)在while循环中实现玩家下棋过程,创建PlayerBoard()函数

创建两个变量x,y放置玩家输入的坐标:

玩家输入坐标后,要判断输入坐标是否在棋盘中:(x >= 1 && x <= ROW && y >= 1 && y <= COL))

判断坐标位置是否为空:

如果位置为空则使用 ‘*‘ 落子(由于数组的下标是0到COL-1或者0到ROW-1,所以需要将x-1和y-1)

如果位置已经有棋子,则提示重新输入坐标,直到成功输入

这个部分的完整代码:

void PlayerBoard(char Board[ROW][COL])
{
	while(1)
	{
		printf("请输入坐标,中间使用空格>:");
		int x, y = 0;
		scanf("%d %d", &x, &y);
		//首先判断输入的坐标是否合法
		if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
		{
			//如果坐标处没有棋子,玩家可以用'*'落子
			if (Board[x - 1][y - 1] == ' ')
			{
				Board[x - 1][y - 1] ='*';
				break;
			}
			//输入的坐标已经有棋子
			else
			{
				printf("坐标被占有,不能落子,重新输入坐标\n");
			}
		}
		//输入坐标不合法
		else
		{
			printf("坐标非法,重新输入>:\n");
		}
	}
}

(5)在while循环中实现电脑下棋的过程,创建ComputerBoard()函数

调用rand()函数生成坐标:

注意:调用rand()函数时需要在主函数中调用srand()函数还有time()函数,和引用头文件<stdlib.h>和<time.h>

	srand((unsigned)time(NULL));

 rand() % ROW结果的范围就是0到ROW-1,同理 rand() % COL结果的范围就是0到COL-1

同理:此处需要判断坐标位置是否为空:

由于代码比较短,直接给出这个部分完整代码:

void ComputerBoard(char Board[ROW][COL])
{
	while(1)
	{
		//调用rand函数,生成0到ROW-1的数和0到COL-1的数
		int x = rand() % ROW;
		int y = rand() % COL;
		//如果坐标为空,则落子,循环退出
		if(Board[x][y] == ' ')
		{
			Board[x][y] = '#';
			break;
		}

	}

}

这里再附上game()的主体代码:

void game()
{
	char Board[ROW][COL];
	InintBoard(Board);
	PrintBoard(Board);
	while (1)
	{
		char flag = 0;
		while(1)
		{
			printf("玩家走\n");
			PlayerBoard(Board);
			PrintBoard(Board);
			flag = IsWin(Board);
			if (flag != 'C')
				break;
			printf("电脑走\n");
			ComputerBoard(Board);
			PrintBoard(Board);
			flag = IsWin(Board);
			if (flag != 'C')
				break;
		}

		if (flag == '*')
		{
			printf("恭喜你赢了!\n");
			return 0;
		}
		else if (flag == '#')
		{
			printf("电脑赢了\n");
			return 0;
		}
		else if (flag == 'Q')
		{
			printf("平局\n");
			return 0;
		}
	}
}

3.通过IsWin函数判断是否输赢

(1)创建一个函数IsWin,在人或电脑走完使用flag=IsWin(),对flag的值进行判断:

需要分为三个部分判断,分别是行,列,两个对角线

通过遍历数组,计算挨在一起的棋子的个数,因为首尾棋子无法被计入,所以只要个数count等于cheer-1,就可以判断出输赢

(2)需要在函数末尾用Isfunll()函数判断是否平局-------->4.判断平局的函数Isfunll()

附上完整代码:

char IsWin(char Board[ROW][COL])
{
	int i = 0;
	for (i = 0; i < ROW; i++)
	{
		//创建count判断连在一起的棋子个数,首尾棋子无法判断,所以count==cheer-1即可
		//cheer为所需连在一起的棋子个数
		int count = 0;
		int j = 0;
		for (j = 0; j < COL-1; j++)
		{
			if (Board[i][j] == Board[i][j + 1] && Board[i][j] != ' ')
			{
				count++;
			}
		}
		if (count == cheer-1)
		{
			return Board[i][j];
		}
	}

	for (i = 0; i < COL; i++)
	{
		int count = 0;
		int j = 0;
		for (j = 0; j < ROW-1; j++)
		{
			if (Board[j][i] == Board[j+1][i] && Board[j][i] != ' ')
			{
				count++;
			}
		}
		if (count == cheer-1)
		{
			return Board[j][i];
		}
	}

    //对角线判断
	int count = 0;
	int x = 0;
	int y = 0;
	for (x = 0, y = 0; x < ROW - 1 && y < COL - 1; x++, y++)
	{
		if (Board[x][y] == Board[x + 1][y + 1] && Board[x][y] != ' ')
		{
			count++;
		}
		if (count == cheer - 1)
		{
			return Board[x][y];
		}
	     
	}

    count = 0;
	for (x = ROW, y = 0; x >0 && y < COL - 1; x--, y++)
	{
		int count = 0;
		if (Board[x][y] == Board[x - 1][y + 1] && Board[x][y] != ' ')
		{
			count++;
		}
		if (count == cheer-1)
		{
			return Board[x][y];
		}
	}
	int flag = 0;
	//判断是否平局
	flag = Isfull(Board);
	if (flag == 1)
	{
		return 'Q';
	}
	return 'C';
}

4.判断平局的函数Isfunll()

遍历数组,如果数组元素有一个为空,函数返回0,反之如果数组遍历完毕,都没有一个数组元素为空,函数则返回1

附上完整代码:

int Isfull(char Board[ROW][COL])
{
	//棋子占满返回1,不满返回0
	int i = 0;
	for (i = 0; i < ROW; i++)
	{
		int j = 0;
		for (j = 0; j < COL; j++)
		{
			if (Board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

上面用到的常数和函数定义,也包括头文件的引用:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 3
#define COL 3
#define cheer 3

void game();

void InintBoard(int Board[ROW][COL]);

void PrintBoard(char Board[ROW][COL]);

void PlayerBoard(char Board[ROW][COL]);

void ComputerBoard(char Board[ROW][COL]);

char IsWin(char Board[ROW][COL]);

int Isfull(char Board[ROW][COL]);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值