#C语言 三子棋/多子棋详解

如何用C语言编写一个三子棋/多子棋小游戏
三子棋作为一个游戏,众所周知游戏应该有的框架是
1.游戏菜单
2.游戏内容
3游戏规则(获胜条件)

在明白了这三点之后,在脑海中三子棋/多子棋的游戏框架应该已经初步建立了,接下来我们就开始着手编写代码。
首先创建一个头文件,“game.h”,在里面存放需要引用的函数
如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#pragma warning(disable:4996)

#define ROW 3        //棋盘行
#define COL 3        //棋盘列
#define MODE 3       //选择几子棋

void menu();
void initboard(char board[ROW][COL], int row, int col);
void printfboard(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void commove(char board[ROW][COL], int row, int col);
int full(char board[ROW][COL], int row, int col);
char win(char board[ROW][COL], int row, int col);
void game(char board[ROW][COL]);

其次,我们需要创建一个源文件"game.c"来编写在头文件中所存放的函数
注意:在实际编写过程中是在源文件中编写一个函数,然后在头文件中存放一个!
在这里我们就从头文件的函数顺序开始讲解
1.游戏菜单

void menu()
{
	printf("****************************\n");
	printf("******** 1.开始游戏 ********\n");
	printf("******** 0.退出游戏 ********\n");
	printf("****************************\n");
}

2.初始化棋盘
在这里我们用一个二维数组创作一个棋盘,数组元素为字符型
使用for循环进行遍历每个元素,将它们定义为空格符

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

3.打印棋盘
这一步需要注意的是在棋盘最右列和最后一行不需要棋盘线

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

			for (int k = 0; k < col; k++)
			{
				if (k < col - 1)
				{
					printf("---|");
				}
				else
				{
					printf("---");
				}

			}
		}
		printf("\n");
	}
}

4.玩家落子
此步我们输入坐标的方式进行落子
需要注意的是我们普通人理解的坐标和数组元素坐标不同,前者是从1开始,后者是从0开始。

void playermove(char board[ROW][COL], int row, int col)
{
	int x, y;
	printf("请输入落子坐标:> ");
	while (1)
	{
		scanf("%d%d", &x, &y);
		if (x > 0 && x <= row&&y > 0 && y <= col&&board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '*';
			break;
		}
		else
		{
			printf("坐标非法,请重新输入: > ");
		}
	}
}

5.电脑落子
电脑落子简单来说就是电脑输入的坐标为0~2的随机数,因此次步需要使用rand()函数,然后再对rand()进行模运算就可以得到需要的随机数。

void commove(char board[ROW][COL], int row, int col)
{

	while (1)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (x > 0 && x <= row&&y > 0 && y <= col&&board[x-1][y-1] == ' ')
		{
			board[x-1][y-1] = '#';
			break;
		}
	}
}

6.判断棋盘是否满子
此函数用来检测棋盘满子平局的情况

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

7.获胜条件判断
根据不同情况,函数所返回的值也有所不同

char win(char board[ROW][COL], int row, int col,int mode)
{
	int i = 0;
	int j = 0;
	int mode_1 = 0;
	int flag = 0;
	//判断行
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col - 1; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] != ' ')
				flag++;
			if (flag == mode - 1)
			{
				flag = 0;
				return board[i][j];
			}
		}
		flag = 0;
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		for (j = 0; j < row - 1; j++)
		{
			if (board[j][i] == board[j + 1][i] && board[j + 1][i] != ' ')
				flag++;
			if (flag == mode - 1)
			{
				flag = 0;
				return board[j][i];
			}
		}
		flag = 0;
	}

	//判断对角线
	for (mode_1 = mode - 1; mode_1 < col; mode_1++)
	{
		for (i = 0, j = mode_1; j > 0; i++, j--)
		{
			if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ')
				flag++;
			if (flag == mode - 1)
			{
				flag = 0;
				return board[i][j];
			}
		}
		flag = 0;
	}
	for (mode_1 = 1; mode_1 < col - mode + 1; mode_1++)
	{
		for (i = row - 1, j = mode_1; j <col; i--, j++)
		{
			if (board[i][j] == board[i - 1][j + 1] && board[i][j] != ' ')
				flag++;
			if (flag == mode - 1)
			{
				flag = 0;
				return board[i][j];
			}
		}
		flag = 0;
	}

	for (mode_1 = 0; mode_1 < col - mode + 1; mode_1++)
	{
		for (i = 0, j = mode_1; j < col; i++, j++)
		{
			if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ')
				flag++;
			if (flag == mode - 1)
			{
				flag = 0;
				return board[i][j];
			}
		}
		flag = 0;
	}
	for (mode_1 = mode - 1; mode_1 < col - 1; mode_1++)
	{
		for (i = row - 1, j = mode_1; j > 0; i--, j--)
		{
			if (board[i][j] == board[i - 1][j - 1] && board[i][j] != ' ')
				flag++;
			if (flag == mode - 1)
			{
				flag = 0;
				return board[i][j];
			}
		}
		flag = 0;
	}
	if (full(board, row, col) == 1)
	{
		return 'Q';
	}
	return 'C';
}

8.整体游戏框架构建
在每次玩家和电脑落子后都使用win()函数进行判断一次,将其值返回给ret变量,然后根据不同的ret返回值打印不同的结果。

void game(char board[ROW][COL])
{
	char ret;
	while (1)
	{
		printfboard(board, ROW, COL);
		playermove(board, ROW, COL);
		ret = win(board, ROW, COL,MODE);
		if (ret != 'C')
		{
			printfboard(board, ROW, COL);
			break;
		}
		commove(board, ROW, COL);
		ret = win(board, ROW, COL,MODE);
		if (ret != 'C')
		{
			printfboard(board, ROW, COL);
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家获胜!\n");
	}
	if (ret == '#')
	{
		printf("电脑获胜!\n");
	}
	if (ret == 'Q')
	{
		printf("平局!\n");
	}
}

最后我们需要对我们编写的代码进行测试,所以我们再次创建一个源文件”test.c“进行测试

int main()
{
	srand((unsigned int)time(NULL));
	char board[ROW][COL] = { 0 };
	int n = 0;
	do
	{
		menu();
		scanf("%d", &n);
		initboard(board, ROW, COL);
		switch (n)
		{
		case 1:
			game(board);
			break;
		case 2:
			break;
		default:
			printf("请重新输入: >\n");
			break;
		}

	} while (n != 0);
	system("pause");
	return 0;
}

至此,整个C语言编写三子棋就此结束…

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值