C语言三子棋:模块化结构与核心逻辑详解
本文深入讲解使用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语言游戏开发基础与实战的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













