[C]项目--三子棋游戏

三子棋

  • 楔子:
    三子棋是我们小时候经常玩的游戏,那么我们今天尝试用C语言实现一下这个小游戏.需要用到的主要知识就是函数封装和数组.
    以下为程序主体:
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//定义棋盘为 3 * 3
#define ROW 3
#define COL 3
char g_board[ROW][COL];

//对于全局变量,没显式初始化,就会默认初始化为 0 
void menu() {
	while (1) {
		printf("         三子棋\n");
		printf("-----------------------\n");
		printf("1.开始游戏  0.退出游戏\n");
		printf("-----------------------\n");
		int a = 0;
		scanf("%d", &a);//接受玩家选择指令
		if (a == 1) {
			break;
		}
		else {
			printf("\n输入有误,请根据选项数字重新输入!\n");
			printf("\n");
			continue;
		}
	}
}



//1.进行棋盘的初始化
void Init() {
	srand((unsigned int)time(0));//设置随机种子
	for (int row = 0; row < ROW; ++row) {
		for (int col = 0; col < COL; ++col) {
			g_board[row][col] = ' ';//未下子用空格表示
		}
	}
}

//打印棋盘
void Print() {
	printf("|---|---|---|\n");
	for (int row = 0; row < ROW; ++row) {
		printf("| %c | %c | %c |\n", g_board[row][0],
			g_board[row][1], g_board[row][2]);
		printf(" ---|---|--- \n");
	}
}

//玩家落子回合
void PlayerMove() {
	printf("请玩家落子!\n");
	while (1) {
		printf("请输入坐标(row col):\n");
		int row, col;
		scanf("%d %d", &row, &col);
		//判断输入参数是否合法
		if (row < 0 || row >= ROW || col < 0 || col >= COL) {
			printf("输入的坐标非法,请重新输入!\n");
			continue;
		}
		if (g_board[row][col] != ' ') {
			printf("当前位置已经有子,请重新输入!\n");
			continue;
		}
		g_board[row][col] = 'x';//完成元素的更迭,直观上来看就是"落子"了
		break;
	}
}

//电脑落子回合
void ComputerMove() {
	printf("请电脑落子!\n");
	while (1) {
		//电脑"随机下"
		int row = rand() % ROW;
		int col = rand() % ROW;
		if (g_board[row][col] != ' ') {
			continue;
		}
		g_board[row][col] = 'o';
		break;
	}
}

//判断棋盘是否全部填满的函数
int Isfull() {
	for (int row = 0; row < ROW; ++row) {
		for (int col = 0; col < COL; ++col) {
			if (g_board[row][col] == ' ') {
				return 0;
			}
		}
	}
	return 1;
}
char CheckWinner() {
	//检查行列斜线是否可以连成三个
	//行
	for (int row = 0; row < ROW; ++row) {
		if (g_board[row][0] == g_board[row][1] &&
			g_board[row][0] == g_board[row][2] &&
			g_board[row][0] != ' ') {
			return g_board[row][0];
		}
	}
	//列
	for (int col = 0; col < COL; ++col) {
		if (g_board[0][col] == g_board[1][col] &&
			g_board[0][col] == g_board[2][col] &&
			g_board[0][col] != ' ') {
			return g_board[0][col];
		}
	}
	//斜  两条对角线
	if (g_board[0][0] == g_board[1][1] &&
		g_board[0][0] == g_board[2][2] &&
		g_board[0][0] != ' ') {
		return g_board[0][0];
	}
	if (g_board[0][2] == g_board[1][1] &&
		g_board[0][2] == g_board[2][0] &&
		g_board[0][2] != ' ') {
		return g_board[0][2];
	}
	//判断和棋情况
	if (Isfull()) {
		//如果填满了 返回和棋
		return 'q';
	}
	//如若没填满  返回 胜负未分
	return ' ';
}

//游戏逻辑主体
int main() {
	menu();//1.先打印菜单函数,让玩家选择
	Init();//2.玩家选择开始,初始化棋盘
	Print();//3.打印棋盘
	char winner;//4.判断胜者
	while (1) {

		//winner -> x 玩家胜
		//winner -> o 电脑胜
		//winner -> ' '胜负未分
		//winner -> q 和棋

		//5.玩家落子,判定是否游戏结束
		PlayerMove();
		winner = CheckWinner();
		if (winner != ' ') {
			//如果CheckWinner函数返回了 胜负未分 则跳出循环,跳出玩家落子阶段
			break;
		}
		Print();//打印更新后的棋盘

		//6.电脑落子,判定是否游戏结束
		ComputerMove();
		winner = CheckWinner();
		if (winner != ' ') {
			break;
		}
		Print();
	}
	if (winner == 'x') {
		printf("玩家胜\n");
		Print();
	}
	else if (winner == 'o') {
		printf("电脑胜\n");
		Print();
	}
	else {
		printf("和棋\n");
		Print();
	}
	system("pause");
	return 0;
}

需要注意的是:

  1. 在程序首用define定义变量是为了程序的延展性,让他不仅限于此代码,而可以扩展成为4 * 4或者 5 * 5的四子棋或五子棋.
  2. 整个游戏逻辑必须明晰:
    打印菜单,让玩家选择.
    打印棋盘 (选择开始再打印,否则退出游戏)
    玩家落子,判定胜负
    电脑落子,判定胜负
    大体框架明确了,接下来就是完成拆分的具体小模块了,化整为零的解决.
  3. 尽量不要只局限于本项目,尽量多抽象一些参数出来,将它包装化,让我们可以对它进行延伸和衍生,达到一定程度上的泛型编程.
  • 总结:
    一个小游戏的实现,让我对所学知识的总和运用能力有了一定的提升,函数是为了主体而服务的,所以一定要确定目标逻辑,再有针对性的下笔.

猜你喜欢

转载自blog.csdn.net/qq_42351880/article/details/84871749