三子棋小游戏(经过轻微改编可变为五子棋)

三子棋游戏

  • 游戏逻辑
  • 构建游戏基本框架
  • 初始化和打印棋盘
  • 玩家和电脑进行下棋
  • 判断棋局状态
  • 三子棋游戏的最终代码
    • 只需要ROW COL改为5就可变为5子棋

游戏逻辑

游戏效果图
三子棋小游戏(经过轻微改编可变为五子棋)_第1张图片

1.游戏要有一个棋盘,棋盘中要有

  • ’ ’ -空格代表无棋子
  • ‘*’-代表玩家下
  • ‘#’-代表电脑下

所以应该先初始化棋盘为空格将棋盘中的数据存储在数组中。
2.要设计玩家走和电脑走分别将落子存储在数组中,并且玩家走时要注意是从1~3,存到数组的下标为 0~2,注意存储时-1;
3.判断输赢还是平局继续,分别判断行列和主对角线和次对角线

4.可以重复玩三子棋游戏

构建游戏基本框架

要有菜单而且可以重复玩,
选1开始游戏
选0退出游戏
选其他数字选择错误请重新选择

#include
void menu()
{
	printf("**************************************\n");
	printf("**********  1.play  0.exit  **********\n");
	printf("**************************************\n");
}
int main()
{
	int input = 0;//判断是否进行游戏
	do
	{
		menu();
		printf("请选择;>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:printf("开始游戏\n");//这里只是进行测试进行游戏时会设计game()函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

三子棋小游戏(经过轻微改编可变为五子棋)_第2张图片
这是游戏的基本框架,接下来会把printf(“开始游戏\n”);替换成game()函数进行游戏设计

初始化和打印棋盘

我们先定义一个存储棋盘数据的数组board[ROW][COL];

  • ROW-棋盘行数
  • COL-棋盘列数
  • 用宏来定义ROW COL的值

初始化棋盘把棋盘数据初始化为0
打印棋盘

  • 每行有 board[][] |(其中|在一行中出现COL-1个)
  • 两行之间— |(其中|在一行中出现COL-1个,两行之间的只有COL-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] = ' ';
		}
	}
}
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 game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
}

三子棋小游戏(经过轻微改编可变为五子棋)_第3张图片

玩家和电脑进行下棋

玩家走时

  • 要注意是从1~3,存到数组的下标为 0~2,注意存储时行列减去1;
  • 判断是否在棋盘范围内,不在范围内就不能下。
  • 判断下棋位置是否有棋子,有棋子就不能下。

电脑走时

  • 设计随机横纵坐标。(rand()函数生成随机数,srand()函数生成随机起点)
  • 横纵坐标范围应该在0~ROW-1,0~COL-1.
  • 如果生成随机数坐标下有棋子,那就再随机生成一个。

在main函数内部do while语句前面加上srand((unsigned)time(NULL));保证具有随机生成起点

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	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] = '*';
				break;
			}
			else
			{
				printf("该位置已被占用,请重新选择\n");
			}
		}
		else
		{
			printf("选择错误请重新选择\n");
		}
	}

}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下:>\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
void game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
	}
}

三子棋小游戏(经过轻微改编可变为五子棋)_第4张图片

已经设计好了玩家和电脑下棋,但是下满了电脑下就陷入了死循环,那是因为没有判断棋局状态的函数,

判断棋局状态

棋局输赢平局还是继续的判断返回值

  • ‘*’ - 返回此字符表示玩家赢

  • ‘#’ - 返回此字符表示电脑赢

  • ‘C’ - 返回此字符表示继续游戏

  • ‘Q’ - 返回此字符表示平局

  • 判断哪方输赢用行判断和列判断对角线判断,只要有判断的坐标有‘ ’就一定没有人在此行列或者对角线赢,若判断完后是有一方输赢,那就返回该次判断过的随机一个坐标的符号

  • 若判断没有那方输赢就该判断哪一方平局或者继续下棋,只需要设计一个函数IsHFull()函数若棋盘满了返回1 - 平局,棋盘未满返回0 - 继续下棋

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

		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}

		}
	}
	return 1;

}
char IsWin(char board[ROW][COL], int row, int col)
{
	//判断行,判断列
	int i = 0;
	int j = 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]==' ')
			{
				break;
			}
		}
		if (j == col - 1)
		{
			return board[i][j];
		}
	}
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < col - 1; i++)
		{
			if (board[i][j] != board[i][j + 1] || board[i][j] == ' ')
			{
				break;
			}
		}
		if (i == col - 1)
		{
			return board[i][j];
		}
	}

	//斜对角线 主对角线
	for (i = 0,j=0; i < row-1&&j<col-1; i++,j++)
	{
		if (board[i][j] != board[i + 1][j + 1] || board[i][j] != ' ')
		{
			break;
		}
		if (i == row - 1 || j == col - 1)
		{
			return board[i][j];
		}
	}
	for (i = 0, j = col-1; i < row - 1 && j >0 ; i++, j--)
	{
		if (board[i][j] != board[i + 1][j - 1] || board[i][j] != ' ')
		{
			break;
		}
		if (i == row - 1 || j == 0)
		{
			return board[i][j];
		}
	}
	
	//判断是否平局
	if (IsFull(board, ROW, COL))
	{
		return 'Q';
	}
	return 'C';
}

game()函数中,通过判断棋局状态的函数通过每次玩家下和电脑下后都调用函数然后用ret接收返回值,如果不是继续就继续下棋,是的话就跳出循环通过ret来输出棋局结果到显示器上。

void game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	int ret = 0;
	while (1)
	{
		PlayerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);

		ComputerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	if (ret == '#')
	{
		printf("电脑赢\n");
	}
	if (ret == 'Q')
	{
		printf("平局\n");
	}
	DisplayBoard(board, ROW, COL);
}

三子棋游戏的最终代码

将这一个游戏分成在三个文件中编写

  • test.c 用来编写函数主要逻辑
  • game.h 用来存放游戏功能函数名
  • game.c 用来编写游戏功能函数

test.c

#include"game.h"
void menu()
{
	printf("**************************************\n");
	printf("**********  1.play  0.exit  **********\n");
	printf("**************************************\n");
}
void game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	int ret = 0;
	while (1)
	{
		PlayerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);

		ComputerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	if (ret == '#')
	{
		printf("电脑赢\n");
	}
	if (ret == 'Q')
	{
		printf("平局\n");
	}
	DisplayBoard(board, ROW, COL);
}
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;
}

game.h

#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 PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

game.c

#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 PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	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] = '*';
				break;
			}
			else
			{
				printf("该位置已被占用,请重新选择\n");
			}
		}
		else
		{
			printf("选择错误请重新选择\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下:>\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int  IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}
char IsWin(char board[ROW][COL], int row, int col)
{
	//判断行,判断列
	int i = 0;
	int j = 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]==' ')
			{
				break;
			}
		}
		if (j == col - 1)
		{
			return board[i][j];
		}
	}
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < col - 1; i++)
		{
			if (board[i][j] != board[i][j + 1] || board[i][j] == ' ')
			{
				break;
			}
		}
		if (i == col - 1)
		{
			return board[i][j];
		}
	}
	//斜对角线 主对角线
	for (i = 0,j=0; i < row-1&&j<col-1; i++,j++)
	{
		if (board[i][j] != board[i + 1][j + 1] || board[i][j] != ' ')
		{
			break;
		}
		if (i == row - 1 || j == col - 1)
		{
			return board[i][j];
		}
	}
	for (i = 0, j = col-1; i < row - 1 && j >0 ; i++, j--)
	{
		if (board[i][j] != board[i + 1][j - 1] || board[i][j] != ' ')
		{
			break;
		}
		if (i == row - 1 || j == 0)
		{
			return board[i][j];
		}
	}	
	//判断是否平局
	if (IsFull(board, ROW, COL))
	{
		return 'Q';
	}
	return 'C';
}

只需要ROW COL改为5就可变为5子棋

你可能感兴趣的:(c语言,算法)