C语言实现三字棋~步骤详解与代码

三字棋游戏

  • 三子棋是什么?
  • 三子棋实现的具体思路
  • 游戏实现的具体步骤
    • 菜单界面
    • 主函数的构建
    • 三子棋的实现
      • 创建棋盘
      • 初始化棋盘
      • 打印棋盘
      • 玩家落子
      • 电脑落子
      • 判断输赢
      • 主函数判断输赢
      • 总代码
  • 总结


三子棋是什么?

三子棋是一个很古老的民间传统游戏,玩起来也非常便捷。三子棋也叫做OOXX棋,井字棋等,用“井”字分出3×3的格子,双方轮流下棋子(可以用O或者X来区别),只要将自己的棋子连成直线就赢了。C语言实现三字棋~步骤详解与代码_第1张图片

三子棋实现的具体思路

1.创建一个游戏菜单让玩家选择开始or结束游戏
2.创建一个棋盘并初始化
3.将初始化后的棋盘打印
4.玩家落子

游戏实现的具体步骤

菜单界面

菜单界面有两种选择:
1.玩游戏
0.退出游戏

代码实现

void menu()
{
	printf("------三子棋游戏-----\n");
	printf("--------------------\n");
	printf("-------1.play-------\n");
	printf("-------0.exit-------\n");
	printf("---------------------\n");

}

主函数的构建

当我们游戏结束时候,仍想继续玩,即要用到循环 (●—●)

代码实现

int main()
{
	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;
}

三子棋的实现

我们把代码分别放在三个文件,test.c,game.c,game.h
test.c-----测试游戏的逻辑
game.c-----游戏的实现
game.h-----函数的声明和符号的定义

创建棋盘

棋盘:使用3行3列的二维数组来表示,元素类型是char。

void game()
{
	//存放下棋的数据
	char board[ROW][COL]= {0};
}

初始化棋盘

这里使用了宏定义有以下的优点:
1.若要修改棋盘大小,代码的修改会很方便
2.提高的代码的可读性

在game.h头文件中声明这个初始化函数

#define ROW 3
#define COL 3

//初始化棋盘
void initBoard(char board[ROW][COL], int row, int col);

然后在game.c的函数里实现

void initBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

C语言实现三字棋~步骤详解与代码_第2张图片

ps:后面创建的函数也一样,要先在game.h中声明,再到game.c函数中实现

打印棋盘

1)按照上面的代码打印,菜单界面又弹出来了,要注意的是这里棋盘并不是没有打印出来,而是我们用" "来表示空白,所以看到的才是一片黑色,接下来我们尝试美化它。变成下面图片的样子↓
C语言实现三字棋~步骤详解与代码_第3张图片

void DisplayBoard(char board[ROW][COL], int row, int 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)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

玩家落子

1.我们当然知道在二维数组里面,数组的下标是从0开始的,但作为一个小白玩家,他们不知道数组的下标。所以对于玩家来说,行和列都是从1开始的。
2.判断玩家输入的坐标是否合法(即是否超出了棋盘范围)
3.玩家落子前要判断该坐标是否为空坐标。

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入坐标");
		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] = 'X';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入\n");
		}
	}
	
}

电脑落子

我们选择用时间戳来生成一个随机数,并把随机数的范围控制在0~3以内,
生成随机数我在这篇博客里详细讲过,大家可以看到这边来生成随机数 ~详细解析,看完对下面的理解更加深刻哦~

srand((unsigned)time(NULL));
void computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;//0~2
		y = rand() % col;//0~2
		if (board[x][y] == ' ')
		{
			board[x][y] = 'O';
			break;
		}
	}

} 

判断输赢

当玩家或者电脑每下一步棋的时候,我们就定义一个函数is_win,判断一下谁赢了;
·
当双方下的棋遍布棋盘的时候,且双方都没有赢,则为平局;
·
1、玩家赢 —> 返回X
.
2、电脑赢---->返回O
.
3、平局----->返回Q
.
4、继续---->返回C
那怎么样才算赢呢?接下来举个例子
C语言实现三字棋~步骤详解与代码_第4张图片
当三行或者三列,以及两条对角线都落满相同的棋子时,那就就赢了;

如图这条斜线落满了相同的棋子,那我们就可以返回中间的红色框框的值
C语言实现三字棋~步骤详解与代码_第5张图片
如果值为X,那么就是玩家胜利;
如果值为O,那么就是电脑胜利;

int if_full(char board[ROW][COL], int row, int col)
{
	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;//满了
}



char is_win(char board[ROW][COL], int row, int col)
{
	int i =0;
	//判断行
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//判断平局
	if (if_full(board, row, col) == 1)
	{
		return'Q';
	}
	//游戏继续
	return'C';
}

主函数判断输赢

玩家和电脑下棋的思路可以这样理解
当玩家每下一步棋时,就进行输赢判断;
当电脑每下一步棋时,也进行输赢判断;
但玩家和电脑的下棋必须通过循环来实现;
当ret不等于C的时候,则跳出循环;
跳出循环后,将is_win的返回值进行比较

int ret = 0;
	//存放下棋的数据
	char board[ROW][COL]= {0};
	//初始化棋盘全为空格
	initBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);//随机下棋
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == 'X')
	{
		printf("你居然赢了\n");
	}
	else if (ret == 'O')
	{
		printf("不会吧不会吧,不会有人输给电脑吧\n");
	}
	else 
	{
		printf("打成平局啦\n");
	}

总代码

  • game.h
#define _CRT_SECURE_NO_WARNINGS

#include
#include
#include

#define ROW 3
#define COL 3

//初始化棋盘
void initBoard(char board[ROW][COL], int row, int col);

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

//判断输赢
char is_win(char board[ROW][COL], int row, int col);
  • game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void initBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void DisplayBoard(char board[ROW][COL], int row, int 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)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入坐标");
		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] = 'X';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入\n");
		}
	}
	
}

void computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;//0~2
		y = rand() % col;//0~2
		if (board[x][y] == ' ')
		{
			board[x][y] = 'O';
			break;
		}
	}

} 

int if_full(char board[ROW][COL], int row, int col)
{
	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;//满了
}



char is_win(char board[ROW][COL], int row, int col)
{
	int i =0;
	//判断行
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//判断平局
	if (if_full(board, row, col) == 1)
	{
		return'Q';
	}
	//游戏继续
	return'C';
}
  • test.c
#define _CRT_SECURE_NO_WARNINGS

#include"game.h"

void menu()
{
	printf("------三子棋游戏-----\n");
	printf("--------------------\n");
	printf("-------1.play-------\n");
	printf("-------0.exit-------\n");
	printf("---------------------\n");

}
void game()
{
	int ret = 0;
	//存放下棋的数据
	char board[ROW][COL]= {0};
	//初始化棋盘全为空格
	initBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);//随机下棋
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == 'X')
	{
		printf("玩家赢了\n");
	}
	else if (ret == 'O')
	{
		printf("电脑赢了\n");
	}
	else 
	{
		printf("平局\n");
	}
	



	

}

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	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;
}

总结

看一遍不一定会,但自己手打一遍肯定有用,一起打天下吧!

我是Scort,我只知道我一无所知,下期见吧!

你可能感兴趣的:(C语言—展翅计划,c语言,经验分享)