利用C语言代码实现三子棋游戏

目录

1. 创建test.c文件用以测试三子棋游戏的逻辑

1.1 主函数

1.2 test函数

1.3 menu函数

1.4 game函数

2. 创建game.h头文件进行函数的声明,符号的定义

3. 创建game.c文件实现游戏的运行

3.1 棋盘初始化函数

3.2 棋盘展示函数

3.3 玩家下棋函数

3.4 电脑下棋函数

3.5 判断输赢函数


1. 创建test.c文件用以测试三子棋游戏的逻辑

1.1 主函数

直接写上test函数用以测试

int main()
{
	test();
	return 0;
}

1.2 test函数

1.利用do while结构实现重复进入游戏的功能

2.利用menu函数实现游戏菜单的打印

3.利用game函数实现三子棋游戏的运行

void test()
{
	int input = 0;
	srand((unsigned int)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);
}

1.3 menu函数

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

1.4 game函数

1.建立board数组存放下棋的数据

2.利用InitBoard函数初始化棋盘使其全为空格

3.利用DisplayBoard函数打印棋盘

4.利用while循环,player_move函数、computer_move函数实现玩家与电脑的轮流下棋

5.在玩家或电脑每完成一次下棋后,利用is_win函数返回棋盘状况,若玩家赢则返回 '*',若电脑赢则返回'#',若平局则返回'Q',若棋盘为填满,且未出现赢家,便可继续,返回'C',每次判断后若无法继续便通过break直接退出循环,在循环外判断是玩家还是电脑赢了,亦或者是平局;这样就可以避免在每次下棋后都要进行输赢的判断,避免代码的重复。

void game()
{
	char 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 == '*')
	{
		printf("玩家赢了\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢了\n");
	}
	else
	{
		printf("平局\n");
	}

}

2. 创建game.h头文件进行函数的声明,符号的定义

在头文件中定义棋盘的行与列,后期若想修改,在此处修改ROW,COL的值即可

#include <stdio.h>

#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);

3. 创建game.c文件实现游戏的运行

3.1 棋盘初始化函数

使数组的九个元素均空格‘ ’

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] = ' ';
		}
	}
}

3.2 棋盘展示函数

要求:依次打印3×3的数组元素,同时利用"|"与"---"分割数组的列与行;即利用for循环以此打印每个元素的列分割线,然后打印行分割线,同时最后一列与最后一行无需分割。

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");
		}
	}

}

3.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 > 0 && x <= row && y > 0 && y <= col)
		{
			// 下棋
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标已被占用,请重新输入\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

3.4 电脑下棋函数

要求:此处只是简单使电脑随机下棋即可,利用rang与srand实现随即功能

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

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] = '#';
			break;
		}
	}
}

3.5 判断输赢函数

要求:依次判断各行、各列以及两条对角线,若满足赢的情况,则返回各行、列或者对角线中实际存储的值,避免又要在判断输赢条件后,又要对赢家是玩家或电脑进行判断。平局的情况则是在上述各行、各列以及两条对角线中未能判断出输赢,且棋盘已满的情况,此处可利用if_full函数的返回值判断棋盘是否已满;若经过上述判断后依旧无法返回值,则返回‘C’,游戏继续。

static int if_full(char board[ROW][COL], int row, int col)  // 利用static使该函数在其他源文件无法使用
{
	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';	

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值