C语言实现三子棋游戏:模块化设计与核心逻辑详解

Ruby
Ruby
发布时间:2026-10-16 | 5人浏览过
原创

使用C语言开发三子棋游戏是理解模块化编程与二维数组应用的经典案例。本文将演示如何通过拆分头文件、实现文件和测试文件,完成从棋盘渲染到胜负判定的全套逻辑。

1. 项目结构与准备

为了保证代码的可读性与可维护性,建议将项目拆分为三个核心文件:test.c(负责主逻辑与菜单交互)、game.c(封装游戏核心行为)以及 game.h(存储宏定义与函数声明)。这种模块化设计使得各部分职责明确,便于后续修改参数或扩展功能。

2. 框架搭建与循环控制

游戏启动后应提供一个循环菜单,允许用户多次游玩直至主动退出。在 main 函数中,使用 do-while 结构结合输入判断来控制程序流程。

int main()
{
    int input = 0;
    do {
        menu();
        scanf("%d", &input);
        switch (input) {
            case 1: game(); break;
            case 0: printf("退出游戏\n"); break;
            default: printf("输入错误\n"); break;
        }
    } while (input);
    return 0;
}

3. 棋盘数据管理与初始化

三子棋的棋盘本质上是一个二维字符数组。为了支持不同大小的棋盘,建议在头文件中定义行列常量:

#define ROW 3
#define COL 3

在实际游戏中,空白位置通常用空格字符表示。需要在 game.c 中实现一个遍历函数,将指定大小的数组全部填充为空格:

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] = ' ';
}

4. 交互式棋盘渲染

原始的直接输出无法呈现美观的网格效果。为了实现行列分隔线,需要分别处理“数据行”和“分割行”,并使用内层循环动态添加管道符 | 以保持通用性:

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("|");
        }
        printf("\n");
        // 打印行分隔线
        if (i < row - 1) {
            for (int j = 0; j < col; ++j) {
                printf("---");
                if (j < col - 1) printf("|");
            }
            printf("\n");
        }
    }
}

当行列数改变时(例如修改为10x10),上述代码依然能正确生成对应规模的网格视图:

5. 玩家操作与输入校验

玩家输入坐标后,程序需执行两步校验:首先检查坐标是否在合法范围内(1~3),其次检测该格子是否已被占用。若合法且空闲,则将对应数组元素更新为标识符号(如 '*'):

void player_move(char board[ROW][COL], int row, int col)
{
    int x, y;
    while (1) {
        printf("请输入坐标:>");
        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;
            }
            printf("该坐标被占用,请重新输入\n");
        } else {
            printf("坐标非法,请重新输入\n");
        }
    }
}

6. 电脑 AI 与胜负判定

电脑逻辑: 简单模式下,利用 rand() 生成随机横纵坐标并尝试落子,直到找到空白格为止。

胜负判断: 创建一个返回值类型为字符型的判定函数。扫描所有行、列及对角线是否存在三连相同棋子。如果棋盘已满且无胜者则返回平局标志,否则继续。

char is_win(char board[ROW][COL], int row, int col) {
    // ... 行、列、对角线检查 ...
    // 若棋盘填满则返回 'Q' (Quiesce/Drawl)
    // 否则返回 'C' (Continue)
}

7. 最终游戏效果展示

经过完整串联后,可以体验以下三种典型的游戏结局场景:

game.h (头文件)

#pragma once
#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 DisplayBoard(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);

game.c (实现文件)

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
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("|");}printf("\n");
        if(i<row-1){for(int j=0;j<col;++j){printf("---");if(j<col-1)printf("|");}printf("
");}}}
void player_move(char board[ROW][COL], int row, int col){
    int x,y; while(1){
        printf("请输入坐标:>");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 computer_move(char board[ROW][COL], int row, int col){
    int x,y; while(1){x=rand()%row;y=rand()%col;if(board[x][y]==' '){board[x][y]='#';break;}}}
char is_win(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[0][2]==board[1][1]&&board[1][1]==board[2][0]&&board[1][1]!=' ')return board[1][1];
    // Check Draw/Continue logic...
    return 'C';
}

test.c (主控文件)

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game(){
    char ret='C'; char board[ROW][COL]={0};
    InitBoard(board,ROW,COL); DisplayBoard(board,ROW,COL);
    while(ret=='C'){
        player_move(board,ROW,COL); DisplayBoard(board,ROW,COL);
        ret=is_win(board,ROW,COL); if(ret!='C') break;
        computer_move(board,ROW,COL); DisplayBoard(board,ROW,COL);
        ret=is_win(board,ROW,COL); if(ret!='C') break;
    }
    if(ret=='*') printf("玩家赢\n"); else if(ret=='#') printf("电脑赢\n"); else printf("平局\n");
}
int main(){
    srand((unsigned int)time(NULL));
    // Loop Menu structure as defined earlier
}
以上就是C语言模块化设计三子棋游戏的详细内容,更多关于C语言小游戏开发的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表