当前位置 : 主页 > 编程语言 > c语言 >

三子棋(超详细)

来源:互联网 收集:自由互联 发布时间:2023-09-03
引言: 完成一个三子棋游戏,这其实也算一个小项目。因此需要 分文件 书写。 test.c用于测试 game.c用于实现游戏里面的函数。 game.h用于包含所有的头文件。 其余test.c和game.c只需要引用

引言:

完成一个三子棋游戏,这其实也算一个小项目。因此需要分文件书写。

test.c用于测试

game.c用于实现游戏里面的函数。

game.h用于包含所有的头文件。

其余test.c和game.c只需要引用 #include "game.h"  一步到位即可。


一、大致的游戏框架

先是一个菜单,输入1/0,1表示开始游戏,0表示结束游戏。

1/0表达式不仅方便我们等会在switch 语句中放入整数,也便于我们跳出循环while()的判断。

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

二、接着最主要的就是实现game()函数。

我们做的游戏是一个三子棋。所以肯定先有一个空白的棋盘。

1、第一步就是如何实现空白的棋盘

三子棋(超详细)_条件判断

这是我们目标的棋盘。

第一行循环打印空格、字符、空格、|,然后循环最后一下条件判断,不打印 | 即可。

第二行循环打印---|,然后循环最后一下条件判断,不打印 | 即可

最后把这两行放到一个循环里面,最后循环条件判断不打印第二行。

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

2、实现玩家落子

考虑到玩家不是程序员,所以不能用数组的下标去要求,数组就是从0开始。

玩家落子也要防止下标不合法,或者被占用的情况

void PlayerMove(char board[ROW][COL])
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请玩家落子,中间以空格区分\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= ROW && y >= 1 && y <= ROW)
		{
			board[x - 1][y - 1] = '#';
			break;
		}
		else
			printf("输入非法,请重新输入\n");
	}
}

3、实现电脑落子

电脑落子就是一个随机值的体现。注意srand((unsigned int) time(NULL))放到主函数里面,只需要调用一次。

然后在电脑落子里面调用rand()函数即可。

void ComputerMove(char board[ROW][COL])
{
	int x = 0;
	int y = 0;
	printf("电脑落子\n");
	while (1)
	{
		x = rand() % ROW;//x就属于0~ROW-1
		y = rand() % COL;
		if (board[x][y] == ' ')
		{
			board[x][y] = '*';
			break;
		}
	}
}

4、判断输赢

判断输赢主要含有是否连成3个(包含横行、竖行、对角线),然后就是平局,如果都不满足,那就是游戏继续。

注意判断赢时,采用通解的方法,即适用任何棋盘,不仅仅适用于三子。

因为判断输赢,所以需要一个返回值,方便主函数进行判断。

char IsWin(char board[ROW][COL])
{
	//判断行
	for (int i=0;i<ROW;i++)
	{
		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==COL-1)
			return board[i][j-1];//这个返回值非常巧妙
	}
	//判断列
	for (int j=0;j<COL;j++)
	{
		int count = 0;
		int i = 0;
		for (i=0;i<ROW-1;i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i][j] != ' ')
				count++;
		}
		if (count==ROW-1)
			return board[i-1][j];
	}
	//判断正对角线
	int x = 0;
	int y = 0;
	int cnt1 = 0;
	while (x<ROW-1 && y<COL-1)
	{
		if (board[x][y] == board[x + 1][y + 1] && board[x][y] != ' ')
		{
			cnt1++;
		}
		x++;
		y++;
	}
	if (cnt1 == ROW - 1)
		return board[x][y];
	//判断反对角线
	int x_ = 0;
	int y_ = COL - 1;
	int cnt2 = 0;
	while (x_<ROW - 1 && y_>0)
	{
		if (board[x_][y_] == board[x_ + 1][y_ - 1] && board[x_][y_] != ' ')
			cnt2++;
		x_++;
		y_--;
	}
	if (cnt2 == ROW - 1)
		return board[x_][y_];
	//判断是否平局
	int flag = 0;
	for (int i=0;i<ROW;i++)
	{
		for (int j=0;j<COL;j++)
		{
			if (board[i][j] == ' ')
				flag = 1;
		}
	}
	if (flag == 0)
		return 'T';
	return 'C';
}

game1/game1 · 可涵/C语言练习 - 码云 - 开源中国 (gitee.com)

源码已经保存到仓库

上一篇:双向带头循环链表的实现(c语言)
下一篇:没有了
网友评论