C语言三子棋:模块化结构与核心逻辑详解

蓝鲸
蓝鲸
发布时间:2026-10-15| 5人浏览过
原创

本文深入讲解使用C语言构建三子棋游戏的核心逻辑与工程实践。通过将代码拆分为头文件、实现文件和主程序三个模块,演示如何管理全局常量与函数接口。重点解析二维数组的初始化渲染、用户输入的合法性校验、随机落子的实现,以及复杂的胜负判定条件,提供一套可运行的完整参考源码。

模块化设计与整体架构

一个结构清晰的C语言项目通常遵循“高内聚、低耦合”的原则。在三子棋的实现中,我们将代码分离为三个文件:test.c负责主菜单与游戏循环控制;game.c包含所有核心游戏逻辑如打印、移动和判定;game.h则定义宏常量及函数声明。这种分离方式不仅便于代码复用与维护,也是标准软件工程中的常见实践。

游戏的主循环采用do...while结构,确保至少运行一局,并在局间询问是否继续。引入srand(time(NULL))为后续电脑随机落子提供种子,保证每次运行结果不同。

主程序逻辑示例 (main):

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("玩不玩?\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

棋盘构建:初始化与渲染

三子棋的核心数据结构是一个3x3的字符型二维数组。初始状态下,所有元素均设置为空格' '。在绘制棋盘时,需要处理边框线条的嵌套输出:行分隔符位于每两行棋子之间,列分隔符位于每个棋子之间。

关键代码实现:

初始化函数:

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

打印棋盘:

void Displayboard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		// 打印行内容
		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");
		}
	}
}

交互逻辑:玩家输入与电脑落子

玩家操作:通过提示输入坐标。程序需严格校验两点:一是坐标是否在合法范围(1-3)内;二是该位置是否已被占用。只有满足这两个条件才能更新棋盘并跳出等待循环。

电脑操作:基础版本采用完全随机策略。rand() % row生成0到row-1的随机数作为坐标,并通过while(1)死循环不断重试,直到找到一个空格位置为止。虽然简单,但实现了自动对抗的基本功能。

胜负判定算法

每一手棋落下后,都需要调用判赢函数Iswin。它检查三种获胜条件(行、列、对角线),并使用单一返回值标识状态:

  • '*': 玩家赢
  • '#': 电脑赢
  • 'Q': 平局(棋盘满且无胜者)
  • 'C': 游戏继续

若未出现上述情况,则返回'C'以维持主循环。

完整源码清单

以下为可直接编译使用的三部分源代码。

1. game.h (头文件)

定义全局常量与外部函数声明。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#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);

2. game.c (核心逻辑)

包含初始化、显示、走棋及判断的具体实现。

#include "game.h"

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

void Displayboard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		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, y = 0;
	printf("玩家请输入坐标: ");
	while (1)
	{
		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)
{
	int x = 0, y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int Isfull(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;
}

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][1] == board[i][2] && board[i][1] != ' ')
			return board[i][1];
	// 判断列
	for (int i = 0; i < col; i++)
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
			return board[1][i];
	// 判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
		return board[1][1];
	
	if (Isfull(board, row, col)) return 'Q'; // 平局
	return 'C'; // 继续
}

3. test.c (主流程)

#include "game.h"

void menu()
{
	printf("=====================
");
	printf("=== 1. Start  0. Exit ===
");
	printf("=====================
");
}

void game()
{
	char board[ROW][COL] = {0};
	Initboard(board, ROW, COL);
	Displayboard(board, ROW, COL);
	
	char ret = 0;
	while (1)
	{
		Playermove(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret != 'C') break;
		
		Computermove(board, ROW, COL);
		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");
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
		switch(input)
		{
		case 1: game(); break;
		case 0: break;
		default: printf("选择错误\n"); break;
		}
	} while (input);
	return 0;
}

以上就是C语言三子棋从设计到编码的详细内容,更多关于C语言游戏开发基础与实战的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。