三子棋小游戏

三子棋小游戏

今天接触到了小时候经常玩的一个游戏——三子棋,实现的过程中有好多东西自己根本想不到,或许是代码量太少,经验不够吧,反正觉得挺不容易的。下面放上我的代码以及思路。

1.游戏中定义的一些函数及变量的说明

char ret = 0;//定义一个接收判断谁赢的返回字符变量
char board[3][3] = { 0 };//用二维数组定义表示棋盘
void Menu();//菜单
void Game();//游戏
void InitBoard(char board[][3], int row, int col);//初始化棋盘
void ShowBoard(char board[][3], int row, int col);//显示棋盘
void PlayerMove(char board[][3], int row, int col);//玩家操作
void ComputerMove(char board[][3], int row, int col);//电脑操作
char IsWin(char board[][3], int row, int col);//判断输赢
static int full(char board[][3], int row, int col)//判断棋盘是否放满

ret接收的返回值有四种分别是 空格,大写字母X,大写字母O和P,ret为X则证明玩家获胜,是O则电脑胜利,P则表示平局。
row和col为接收棋盘大小的两个形参。

2.首先定义一个Menu界面~

void Menu()
{
	printf("\t\t\t\t\t**************************\n");
	printf("\t\t\t\t\t**************************\n");
	printf("\t\t\t\t\t*********1.开始***********\n");
	printf("\t\t\t\t\t*********0.退出***********\n");
	printf("\t\t\t\t\t**************************\n");
	printf("\t\t\t\t\t**************************\n");
}

它的样子是这样的,很low但是现阶段我满足了,哈哈哈!
在这里插入图片描述

3.然后我们定义一个Game(),代码如下

void Game()
{
	char ret = 0;//定义一个接收判断谁赢的返回字符
	char board[3][3] = { 0 };//用二维数组定义表示棋盘
	InitBoard(board, 3, 3);//初始化棋盘,让棋盘为空
	ShowBoard(board, 3, 3);//显示棋盘
	while (1)//
	{
		PlayerMove(board, 3, 3);
		ShowBoard(board, 3, 3);
		ret = IsWin(board, 3, 3);
		if (ret != ' ')
		{
			break;
		}
		ComputerMove(board, 3, 3);
		ShowBoard(board, 3, 3);
		ret = IsWin(board, 3, 3);
		if (ret != ' ')
		{
			break;
		}
	}
	if (ret == 'X')
	{
		printf("玩家获胜\n");
	}
	if (ret == 'O')
	{
		printf("电脑获胜\n");
	}
	if (ret == 'P')
	{
		printf("平局\n");
	}
}

每次玩家和电脑进行操作后都要对ret的值进行判断,ret不是空格则游戏结束,跳出while循环判断结果并进行输出。

4.棋盘初始化和显示棋盘

棋盘初始化

void InitBoard(char board[][3], int row, int col)
{
	memset(board, ' ', row*col*sizeof(char));//游戏开始给棋盘的每个空间都置为空
}

memset是一个内存清零的函数它的头文件是#include<string.h>
使用方法:memset(void s, int ch, size_t n);
这里
s表示的是你想要给谁内存清零,ch表示你想把他变成什么,size就很明显是说想要改变多少内存里的东西。

显示棋盘
棋盘的样子
在这里插入图片描述

void ShowBoard(char board[][3], int row, int col)
{
	int  i = 0;
	int j = 0;
	for (i = 0; i < row; i++)//控制行
	{
		for (j = 0; j < col; j++)//控制列
		{
			printf(" %c ", board[i][j]);//打印字符二维数组中存储的符号
			if (j < col - 1)//只需要打两列,所以为col-1,满足条件打印|
			{
				printf("|");
			}
		}
		putchar('\n');//每一行打完后使用putchar进行换行
		if (i < row - 1)//同理对每行的分隔符进行打印
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			putchar('\n');	
		}
	}
}

定义两个变量i和j来控制打印棋盘,i控制行,j控制列。
通过观察棋盘样子我们发现只需要打两个竖行和横行,由于是从0开始,所以控制当i和j分别小于row-1和col-1时进行打印棋盘格子。

5.玩家操作和电脑操作

玩家操作

void PlayerMove(char board[][3], int row, int col)
{
	int x = 0;//定义变量X和Y,玩家输入坐标
	int y = 0;
	while (1)
	{

		printf("请输入你的落子位置(1-3):");//因为棋盘是3*3大小所以是1-3
		scanf("%d%d", &x, &y);
		if (x>=1&&x<=3&&y>=1&&y<=3)//满足棋盘大小条件,准备赋值
		{
			if (board[x - 1][y - 1] == ' ')//当该位置为空,对该格进行赋值
			{
				board[x - 1][y - 1] = 'X';
				break;

			}
			else//当该位置不为空,提示重新输入
			{
				printf("此位置已被占用,请重新输入。\n");
			}
		}
		else//不满足棋盘条件,提示输入不合理
		{
			printf("您输入的位置不合理。\n");
		}
	}
}

我们知道在数组中数组下标是从0开始的,可是现实感官中通常从1开始,所以在对每一格进行赋值是需要i-1和j-1.

电脑操作
电脑操作是随机获取一个空位置进行下棋

void ComputerMove(char board[][3], int row, int col)
{
	int i=0, j=0;
	printf("电脑的选择:\n\n");
	while (1)
	{
		i = rand() % 3 + 1;//获取随机数i和j
		j = rand() % 3 + 1;
		if (board[i][j] == ' ')//当该位置为空,下棋
		{
			board[i][j] = 'O';
			break;
		}
	}
}

6.判断输赢

在这里我定义了一个返回值为char类型的函数,输出输赢在Game()中进行。
当每一行,每一列或每一斜行都为相同字符且不为空时返回这个字符。
当棋盘满的时候还没有出现当每一行,每一列或每一斜行都为相同字符时返回P

char IsWin(char board[][3], 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][0] != ' ')
		{
			return board[i][0];
		}
		//列
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i]&& board[0][i] != ' ')
		{
			return board[0][i];
		}
		if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&& board[0][0] != ' ')
		{
			return board[0][0];
		}
		if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[0][0] != ' ')
		{
			return board[0][2];
		}
		//平局
		if (full(board, row, col) == 1)
		{
			return 'P';
		}
	}
	//没有赢也没有平局
	return ' ';
}

判断棋盘是否放满

对棋盘进行遍历,若还有位置为空则为放满,返回0,棋盘放满则返回1

static int full(char board[][3], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

7.主函数

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
	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\n");
			break;
		}
	} while (input);
	return 0;
}

到这里我的三子棋小游戏也就完全结束了,在写这个游戏中我学会了如何对二维数组进行遍历,加强了我对循环的使用,最后放一波完整的游戏截图吧!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

到此,我的三子棋小游戏也就完美收官了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值