test.c源文件代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include "game.h"

int num = 0;


void menu() {
	printf("*************************************************\n");
	printf("**********   1 . play       0 . exit   **********\n");
	printf("*************************************************\n");
}

void game() {
	char ret = 0;
	 num = 0;
	//数组-存放走出的棋盘信息
	char board[ROW][COL] = {0};
	//初始化棋盘为空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	//下棋
	while (1) {
		//玩家下棋
		PlayerMove(board, ROW, COL);
		num++;//计算所占用的棋盘格数
		DisplayBoard(board, ROW, COL);
	
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;

		//电脑下棋
		ComputerMove(board, ROW, COL);
		num++;
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;

	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
}

void test() {

	int input = 0;

	do {
		menu();
		printf("请输入指令 :\n");
		scanf("%d", &input);
		switch (input) {
		case 1:
			printf("三子棋\n");
			game();
			break;
		case 0:
			printf("游戏退出\n");
			break;
		default :
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);

}

int main() {


	test();
	return 0;
}

这段代码实现了一个简单的三子棋游戏。下面是对代码的整体分析

  1. 头文件和宏定义部分:
  • 代码使用了预处理指令 #define _CRT_SECURE_NO_WARNINGS 1 来禁用特定编译器的警告。
  • 引入了 <stdio.h> 头文件,该头文件包含了输入输出相关的函数。
  • 引入了自定义的 "game.h" 头文件,其中可能包含了游戏所需的函数和常量的声明。
  1. 全局变量部分:
  • 定义了一个全局变量 num,用于记录棋盘上已经落子的次数。
  1. menu() 函数:
  • 打印游戏菜单的函数,显示了两个选项:1. play 和 0. exit。
  1. game() 函数:
  • 游戏的核心逻辑部分。
  • 定义了一个字符变量 ret,用于记录游戏结果。
  • 初始化棋盘,将其所有位置设置为空格。
  • 打印棋盘。
  • 进入游戏循环,直到有一方获胜或平局:
  • 玩家下棋,更新棋盘,打印棋盘。
  • 检查是否有一方获胜,如果有则跳出循环。
  • 电脑下棋,更新棋盘,打印棋盘。
  • 检查是否有一方获胜,如果有则跳出循环。
  • 根据游戏结果 ret 的值,输出对应的信息。
  1. test() 函数:
  • 进行游戏测试的函数。
  • 定义了一个整型变量 input,用于存储用户的输入。
  • 使用 do-while 循环,循环打印菜单并等待用户输入指令。
  • 根据用户输入的指令执行相应的操作:
  • 如果输入是 1,表示选择了 play,调用 game() 函数开始游戏。
  • 如果输入是 0,表示选择了 exit,游戏退出。
  • 如果输入不是 0 或 1,输出选择错误的提示信息。
  • 循环继续,直到用户输入为 0 时退出。
  1. main() 函数:
  • 程序的入口函数。
  • 调用 test() 函数开始游戏。
  • 返回 0 表示程序正常结束。

总体而言,这段代码实现了一个简单的三子棋游戏,提供了菜单选项供用户选择,根据用户的选择进行游戏或退出。游戏逻辑包括玩家和电脑的轮流下棋,判断游戏是否结束,以及输出游戏结果。

game.c源文件代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

extern int num;	//调用全局变量


//初始化
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] = ' ';
		}
	}
}


//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col) {
	for (int i = 0; i < row; i++) {

	
		//打印一行数据
		for (int j = 0; j < col; j++) {
			printf(" %c ", board[i][j]);	//先打印棋子
			if (j < col - 1)		//最后一列不打印分割线
				printf("|");
			if (j == col - 1)	//本行最后一个棋子打印之后换行
				printf("\n");
		}
		//打印分割线
		if (i < row - 1) {		//最后一行不打印分割线
			for (int m = 0; m < col; m++) {
				printf("---");		//打印分割线
				if (m < col - 1)	//最后一列不打印分割线
					printf("|");
				if (m == col - 1)	//本行最后一个分割线打印之后换行
					printf("\n");
			}
		}
	}
}


//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col) {

	int x = 0, y = 0;
	printf("玩家走:>\n");
	while (1) {
		printf("请输入要下的坐标\n");
		scanf("%d%d", &x, &y);
		//判断玩家下棋的合法性
		if ((x <= row && x >= 1) && (y <= col && y >= 1) && (board[x - 1][y - 1] == ' ')) {
			board[x - 1][y - 1] = '*';
			break;
		}
		else
			printf("非法位置,请重新输入!\n");
	}

}


//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col) {
	int x = 0, y = 0;
	printf("电脑走:>\n");
	//判断电脑下棋位置的合法性
	while (1) {
		srand((unsigned int)time(NULL));	//初始化随机种子
		x = rand() % row;		//获得0到row-1的一个随机数
		y = rand() % col;		////获得0到col-1的一个随机数
		if ((x <= row - 1 && x >= 0) && (y <= col - 1 && y >= 0) && (board[x][y] == ' ')) {
			board[x][y] = '#';
			break;
		}
	}
}


//判断输赢
//		*		玩家赢
//		#		电脑赢
//		Q		平局
//		C		继续
char IsWin(char board[ROW][COL], int row, int col) {
	//横三列
	for (int i = 0; i < row; i++) {		//三个元素相等且不等于空格
		if (board[i][0] == board[i][1] && board[i][2] == board[i][0] && board[i][0] != ' ')
			return board[i][0];
	}
	//竖三列
	for (int i = 0; i < col; i++) {		//三个元素相等且不等于空格
		if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}
	//斜两列	//三个元素相等且不等于空格
	if (board[1][1] == board[2][2] && board[1][1] == board[0][0] && board[1][1] != ' ')
		return board[1][1];	//三个元素相等且不等于空格
	if (board[1][1] == board[2][0] && board[1][1] == board[0][2] && board[1][1] != ' ')
		return board[1][1];
	if (num == 9)	//数组被填满
		return 'Q';
	
	return 'C';
}

这段代码是一个简单的三子棋游戏的实现。分析一下每个函数的功能

  1. InitBoard(): 这个函数用于初始化棋盘,将棋盘数组中的所有元素都置为空格。
  2. DisplayBoard(): 这个函数用于打印当前的棋盘状态。它会按照格式打印出棋盘中的棋子,并在棋子之间和行之间打印分割线。
  3. PlayerMove(): 这个函数用于让玩家下棋。它会提示玩家输入要下的坐标,并判断下棋位置的合法性。如果合法,就在棋盘上放置一个玩家的棋子。
  4. ComputerMove(): 这个函数用于让电脑下棋。它会随机生成一个坐标,并判断下棋位置的合法性。如果合法,就在棋盘上放置一个电脑的棋子。
  5. IsWin(): 这个函数用于判断当前的输赢情况。它会检查棋盘上的所有可能的获胜情况,并返回相应的结果。如果玩家赢,返回'*';如果电脑赢,返回'#';如果平局,返回'Q';如果还没有确定胜负,返回'C'

game.h头文件代码:

#pragma once
#define ROW 3
#define COL 3

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//声明
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);

这段代码是一个简单的三子棋游戏的头文件部分。

首先,代码使用了 #pragma once 来确保头文件只被编译一次,避免了重复包含的问题。

接下来,通过 #define 指令定义了棋盘的行数和列数,分别为 3

然后,代码包含了三个头文件:stdio.hstdlib.htime.hstdio.h 包含了输入输出的相关函数,stdlib.h 包含了动态内存分配的函数,time.h 包含了时间相关的函数。

之后,代码声明了几个函数的原型:

  1. InitBoard():用于初始化棋盘,接收一个二维数组 board 以及棋盘的行数 row 和列数 col
  2. DisplayBoard():用于打印当前的棋盘状态,接收一个二维数组 board 以及棋盘的行数 row 和列数 col
  3. PlayerMove():用于玩家下棋的函数,接收一个二维数组 board 以及棋盘的行数 row 和列数 col
  4. ComputerMove():用于电脑下棋的函数,接收一个二维数组 board 以及棋盘的行数 row 和列数 col

最后,代码声明了一个用于判断输赢的函数 IsWin(),接收一个二维数组 board 以及棋盘的行数 row 和列数 col,并返回一个字符表示当前的输赢状态。

运行结果:

C语言实现三子棋小游戏以及步骤详解_分割线

C语言实现三子棋小游戏以及步骤详解_头文件_02

C语言实现三子棋小游戏以及步骤详解_C语言基础_03