C语言写三子棋游戏(初级版本)

思维导图

目录

思维导图

1.准备阶段

作用:

2test.c

2.1游戏第一步,写个主函数(在这个函数内部实现选择,打印菜单,玩游戏的功能)

2.2菜单函数的实现:

4.game()内函数的实现(game.c)

4.1初始化函数(InitBoard(board,ROW,COL))

4.2显示棋盘函数(Display(board,ROW,COL))

4.3玩家下棋函数 (PlayMove(board,ROW,COL))

4.4电脑下棋(ComputerMove(board,ROW,COL)

5.全部代码 

5.1game.h(头文件)

5.2test.c

5.3game.c


1.准备阶段

创建三个文件:test.c game.c game .h,前两个是源文件,最后一个是头文件。

作用:

test.c:测试代码。在这里放主函数,以及安排顺序协调实现实现其它函数的功能,让游戏运行起来。

game.c:定义函数。

game.h:声明函数。

2test.c

2.1游戏第一步,写个主函数(在这个函数内部实现选择,打印菜单,玩游戏的功能)

代码如下:

int main() {
	int input = 0;
srand((unsigned int)time(NULL));//函数rand()的种子
	do {
		menu();//打印菜单函数
        printf(”请选择>:\n");
		scanf("%d", &input);
		switch (input) {//使用switch....case语句进行选择
		case 1:game();//游戏函数
			break;
		case 0:printf("退出游戏\n");
			break;
		default:printf("选择错误,请重新选择>:\n");
			break;

		}

	} while (input);
	return 0;
}

2.2菜单函数的实现:

代码如下:

void menu() {
	printf("***********************\n");
	printf("******* 1. play  ******\n");//1代表玩
	printf("******* 0. exit  ******\n");//0代表退出
	printf("***********************\n");
}

2.3game函数的玩游戏逻辑

void game() {
	char board[ROW][COL] = {0};//定义一个3*3的棋盘,ROW与COL是宏定义变量
	InitBoard(board, ROW, COL);//初始化棋盘,作用是将棋盘board[][]初始化为空格
	Display(board, ROW, COL);//显示棋盘;
	char ret = 0;
	while (1) {//人机大战不会一下子就结束,所以要有循环.
		PlayerMove(board, ROW, COL);//玩家下棋;
		ret=IsWin(board, ROW, COL);//判断输赢以及是否继续,如果不用继续就跳出循环
		if (ret != 'C'){//假设代表继续的符号为'C' 
			break;
		}
		Display(board, ROW, COL);//显示棋盘
		ComputerMove(board, ROW, COL);//电脑下棋;
		ret=IsWin(board, ROW, COL);//判断输赢,如果不用继续就跳出循环
		if(ret!='C') {// 假设代表继续的符号为'C'
			break;
		}
		Display(board, ROW, COL);//显示棋盘;
	}
	if (ret == '*') {//假设玩家赢的返回符号为’*‘
		printf("玩家赢\n");
	}
	else if (ret == '#') {//假设电脑赢的返回符号为’#‘
		printf("电脑赢\n");
	}
	else {//假设平局的返回符号为’Q'.
		printf("平局\n");
	}
}

4.game()内函数的实现(game.c)

4.1初始化函数(InitBoard(board,ROW,COL))

void InitBoard(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++) {
			board[i][j] = ' ';//遍历初始化为空格。
		}
	}
}

4.2显示棋盘函数(Display(board,ROW,COL))

先看看我的棋盘:

 这个棋盘其实可以分成六组来看:

void Display(char board[ROW][COL], int row, int col) {
	int i = 0;
	int j = 0;
	for (i = 0;i < row;i++) {//第一个循环代表会打印row组
		for (j = 0;j < col;j++) {//打印  |  |  。
			printf(" %c ", board[i][j]);
			if (j < col - 1)//|只打印col-1行
				printf("|");
		}
		printf("\n");
		if (i < row - 1) {//打印---|---|---
			for (j = 0;j < col;j++) {
				printf("---");
				if (j < col - 1)//|只打印col-1行
					printf("|");
			}
			printf("\n");
		}
	}
}

 看看效果:

4.3玩家下棋函数 (PlayMove(board,ROW,COL))

我想要实现的功能:

1.不是程序员的人也能轻松下棋(第一格坐标就是(1,1))。

2.下的格子用”*“代替。

3.如果下棋的地方被下了就不能下了。

4.不能下超过数组范围的地方。

实现代码:

void PlayerMove(char board[ROW][COL], int row, int col) {
    int x = 0;
	int y = 0;
	while (1) {
printf("玩家下棋>:\n");
scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {//判断坐标是否合法
			if (board[x - 1][y - 1] == ' ') {//判断下棋处是否被占用。x-1,y-1操作使得玩家下的(1,1)就是二维数组的(0,0)。
				board[x - 1][y - 1] = '*';//将玩家下棋处改为’*‘。
				break;//只有玩家下成功了才能跳出循环。
			}
			else
			{
				printf("该位置已被占用,请重新输入>:\n");//被占用提示
			}
		}
		else
		{
			printf("坐标非法,请重新输入>:\n");//坐标非法提示
		}
	}
}

现在用Display()显示一下:

4.4电脑下棋(ComputerMove(board,ROW,COL)

电脑下棋的功能暂且实现到下随机合理的值。

代码:

void ComputerMove(char board[ROW][COL], int row, int col) {
	printf("电脑下棋>:\n");
	int x = 0;
	int y = 0;
	while (1) {
	x = rand() % row;//调用库函数rand()随机生成0-row-1的值,所以x的值不会超过row
	y = rand() % col;//调用库函数rand()随机生成0-col-1的值,所以x的值不会超过col
		if (board[x][y] == ' ') {//电脑下的地方合法才能跳出循环
			board[x][y] = '#';
			break;
		}
	}
}

调用Display()看看效果:

4.5判断输赢(IsWin(board,ROW,COL))

功能:1.玩家赢返回’*‘。

2.电脑赢返回’#‘。

3. 平局返回’Q'.

4.游戏继续,返回‘C'。

实现代码:

char BoardFull( 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;
	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];
		else 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])//判断左对角线
		return board[0][0];
	else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//判断右对角线
		return board[0][2];
	else if (BoardFull(board, ROW, COL) ){//判断棋盘有没有满
		return 'Q';
	}
	return 'C';//若无赢,无满就继续
}

看看效果:

5.全部代码 

5.1game.h(头文件)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL], int row, int col);
void Display(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);

5.2test.c

#define  _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu() {
	printf("***********************\n");
	printf("******* 1. play  ******\n");
	printf("******* 0. exit  ******\n");
	printf("***********************\n");
}
void game() {
	char board[ROW][COL] = {0};//定义一个3*3的棋盘,ROW与COL是宏定义变量
	InitBoard(board, ROW, COL);//初始化棋盘,作用是将棋盘board[][]初始化为空格
	Display(board, ROW, COL);//显示棋盘;
	char ret = 0;
	while (1) {//人机大战不会一下子就结束,所以要有循环.
		PlayerMove(board, ROW, COL);//玩家下棋;
		Display(board, ROW, COL);//显示棋盘
		ret=IsWin(board, ROW, COL);//判断输赢以及是否继续,如果不用继续就跳出循环
		if (ret != 'C'){//假设代表继续的符号为'C' 
			break;
		}
		ComputerMove(board, ROW, COL);//电脑下棋;
		Display(board, ROW, COL);//显示棋盘;
		ret=IsWin(board, ROW, COL);//判断输赢,如果不用继续就跳出循环
		if(ret!='C') {// 假设代表继续的符号为'C'
			break;
		}
	}
	if (ret == '*') {//假设玩家赢的返回符号为’*‘
		printf("玩家赢\n");
	}
	else if (ret == '#') {//假设电脑赢的返回符号为’#‘
		printf("电脑赢\n");
	}
	else {//假设平局的返回符号为’Q'.
		printf("平局\n");
	}
}
int main() {
	srand((unsigned int)time(NULL));
	int input = 0;
	do {
		menu();//打印菜单函数
		printf("请选择>:\n");
		scanf("%d", &input);
		switch (input) {//使用switch....case语句进行选择
		case 1:game();//游戏函数
			break;
		case 0:printf("退出游戏\n");
			break;
		default:printf("选择错误,请重新选择>:\n");
			break;

		}

	} while (input);
	return 0;
}

5.3game.c

#define  _CRT_SECURE_NO_WARNINGS
#include"game.h"
void InitBoard(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++) {
			board[i][j] = ' ';//遍历初始化为空格。
		}
	}
}
void Display(char board[ROW][COL], int row, int col) {
	int i = 0;
	int j = 0;
	for (i = 0;i < row;i++) {//第一个循环代表会打印row组
		for (j = 0;j < col;j++) {//打印  |  |  。
			printf(" %c ", board[i][j]);
			if (j < col - 1)//|只打印col-1行
				printf("|");
		}
		printf("\n");
		if (i < row - 1) {//打印---|---|---
			for (j = 0;j < col;j++) {
				printf("---");
				if (j < col - 1)//|只打印col-1行
					printf("|");
			}
			printf("\n");
		}
	}
}
void PlayerMove(char board[ROW][COL], int row, int col) {
	int x = 0;
	int y = 0;
	while (1) {
	printf("玩家下棋>:\n");
	scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {//判断坐标是否合法
			if (board[x - 1][y - 1] == ' ') {//判断下棋处是否被占用。x-1,y-1操作使得玩家下的(1,1)就是二维数组的(0,0)。
				board[x - 1][y - 1] = '*';//将玩家下棋处改为’*‘。
				break;//只有玩家下成功了才能跳出循环。
			}
			else
			{
				printf("该位置已被占用,请重新输入>:\n");//被占用提示
			}
		}
		else
		{
			printf("坐标非法,请重新输入>:\n");//坐标非法提示
		}
	}
}
void ComputerMove(char board[ROW][COL], int row, int col) {
	printf("电脑下棋>:\n");
	int x = 0;
	int y = 0;
	while (1) {
	x = rand() % row;//调用库函数rand()随机生成0-row-1的值,所以x的值不会超过row
	y = rand() % col;//调用库函数rand()随机生成0-col-1的值,所以x的值不会超过col
		if (board[x][y] == ' ') {//电脑下的地方合法才能跳出循环
			board[x][y] = '#';
			break;
		}
	}
}
char BoardFull( 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;
	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];
		else 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])//判断左对角线
		return board[0][0];
	else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//判断右对角线
		return board[0][2];
	else if (BoardFull(board, ROW, COL) ){//判断棋盘有没有满
		return 'Q';
	}
	return 'C';//若无赢,无满就继续
}

如果有不对的地方,请多多指教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值