C语言实现五子棋游戏(附带源码)

C语言实现五子棋游戏

五子棋是一种简单但富有策略性的棋类游戏,两个玩家在一个棋盘上交替下棋,每次下一个棋子,目的是在水平、垂直或对角线上形成五颗连续的棋子。这个项目的目标是使用C语言来实现一个简单的五子棋游戏,包括棋盘的显示、玩家输入、胜利条件判断以及游戏循环控制。

项目介绍

1. 项目背景

五子棋游戏源于中国,已经有几百年的历史。它的玩法简单,但极具挑战性。该游戏的规则如下:

  • 游戏使用的是一个15x15的棋盘。
  • 两个玩家轮流在棋盘上放置棋子(黑棋和白棋)。
  • 玩家通过横向、纵向或对角线上的连续五颗棋子来获胜。

本项目旨在用C语言编写一个简单的控制台五子棋游戏,包括棋盘的显示、玩家输入棋子、判断胜负、清空棋盘等功能。

2. 项目目标

本项目将包括以下几个功能:

  • 显示15x15的棋盘。
  • 支持玩家输入棋子的坐标,并在棋盘上标记。
  • 判断胜负:当某个玩家在任意一条方向上形成五子连线时,判定为胜利。
  • 支持游戏重启功能。

3. 开发工具与环境

本项目使用C语言开发,编译器为GCC(或任何兼容的C语言编译器)。操作系统不限,但建议在Linux或Windows环境下进行开发。

4. 功能概述

  • 棋盘显示:实时显示棋盘状态,空白位置用‘+’表示,黑棋用‘X’,白棋用‘O’表示。
  • 玩家输入:两名玩家交替输入行列号来放置自己的棋子。
  • 胜负判断:每次玩家放置棋子后,检查当前棋盘,判断是否有一方玩家的五颗棋子连成一线。
  • 游戏结束:当有玩家胜利或棋盘填满时,游戏结束。

实现思路

1. 数据结构设计

五子棋的棋盘可以使用二维数组来表示。由于棋盘是15x15的,所以我们需要一个15行15列的数组来存储棋盘的状态。

  • 棋盘结构: 用二维数组board[15][15]来表示棋盘。
  • 棋盘符号:
    • 0表示空位置。
    • 1表示黑棋。
    • 2表示白棋。

2. 游戏循环

游戏会按照以下流程进行:

  1. 初始化棋盘并显示。
  2. 轮流让两名玩家输入位置。
  3. 每次玩家输入后,检查当前棋盘,判断是否有玩家胜利。
  4. 如果胜利,宣布结果并结束游戏。如果没有胜利,继续下一轮。

3. 功能实现

  • 棋盘初始化和显示:用一个函数初始化棋盘,并定期显示棋盘的当前状态。
  • 玩家输入:获取玩家输入的行列位置,判断位置是否有效(即是否为空)。
  • 胜利判断:每次玩家下棋后,检查其放置的棋子是否成线(横、纵、斜)。
  • 游戏重启功能:游戏结束后,可以选择是否重新开始。

实现代码

以下是完整的五子棋游戏代码:

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

#define SIZE 15  // 棋盘的大小
#define EMPTY 0  // 空位置
#define BLACK 1  // 黑棋
#define WHITE 2  // 白棋

// 声明函数
void initBoard(int board[SIZE][SIZE]);
void printBoard(int board[SIZE][SIZE]);
int isValidMove(int board[SIZE][SIZE], int row, int col);
int checkWin(int board[SIZE][SIZE], int player);
int checkDirection(int board[SIZE][SIZE], int row, int col, int dRow, int dCol, int player);
void playGame();

int main() {
    playGame();
    return 0;
}

// 初始化棋盘
void initBoard(int board[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            board[i][j] = EMPTY;
        }
    }
}

// 打印棋盘
void printBoard(int board[SIZE][SIZE]) {
    printf("   ");
    for (int i = 0; i < SIZE; i++) {
        printf("%2d ", i + 1);
    }
    printf("\n");

    for (int i = 0; i < SIZE; i++) {
        printf("%2d ", i + 1);
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] == EMPTY) {
                printf(" + ");
            } else if (board[i][j] == BLACK) {
                printf(" X ");
            } else {
                printf(" O ");
            }
        }
        printf("\n");
    }
}

// 判断是否是有效的棋步
int isValidMove(int board[SIZE][SIZE], int row, int col) {
    if (row < 0 || row >= SIZE || col < 0 || col >= SIZE || board[row][col] != EMPTY) {
        return 0;  // 无效的棋步
    }
    return 1;
}

// 检查是否有玩家胜利
int checkWin(int board[SIZE][SIZE], int player) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] == player) {
                if (checkDirection(board, i, j, 1, 0, player) ||  // 横向
                    checkDirection(board, i, j, 0, 1, player) ||  // 纵向
                    checkDirection(board, i, j, 1, 1, player) ||  // 斜向 /
                    checkDirection(board, i, j, 1, -1, player)) {  // 斜向 \
                    return 1;  // 玩家胜利
                }
            }
        }
    }
    return 0;
}

// 检查某个方向是否有五子连成一线
int checkDirection(int board[SIZE][SIZE], int row, int col, int dRow, int dCol, int player) {
    int count = 0;
    for (int i = 0; i < 5; i++) {
        int newRow = row + i * dRow;
        int newCol = col + i * dCol;
        if (newRow >= 0 && newRow < SIZE && newCol >= 0 && newCol < SIZE && board[newRow][newCol] == player) {
            count++;
        } else {
            break;
        }
    }
    return count == 5;
}

// 游戏主循环
void playGame() {
    int board[SIZE][SIZE];
    int currentPlayer = BLACK;  // 从黑棋开始
    int row, col;
    int gameOver = 0;

    initBoard(board);

    while (!gameOver) {
        printBoard(board);
        printf("玩家 %d 轮到你下棋,请输入行和列 (1-%d): ", (currentPlayer == BLACK) ? 1 : 2, SIZE);
        scanf("%d %d", &row, &col);
        row--; col--;  // 转换为数组索引

        if (isValidMove(board, row, col)) {
            board[row][col] = currentPlayer;
            if (checkWin(board, currentPlayer)) {
                printBoard(board);
                printf("玩家 %d 获胜!\n", (currentPlayer == BLACK) ? 1 : 2);
                gameOver = 1;
            } else {
                currentPlayer = (currentPlayer == BLACK) ? WHITE : BLACK;  // 换玩家
            }
        } else {
            printf("无效的棋步,请重新输入。\n");
        }
    }
}

代码解读

1. initBoard()函数

该函数负责初始化棋盘,设置所有位置为空(0)。我们使用一个15x15的二维数组来表示棋盘,空位置用0表示。

2. printBoard()函数

用于打印当前的棋盘状态。根据棋盘的值,打印+表示空位,X表示黑棋,O表示白棋。通过行列号打印每行的坐标,方便玩家查看。

3. isValidMove()函数

检查玩家输入的棋步是否合法。首先检查坐标是否在棋盘范围内,其次确保该位置为空。若合法返回1,否则返回0。

4. checkWin()函数

每次玩家落子后,调用该函数检查是否有玩家胜利。遍历棋盘,针对每个棋子检查其周围的四个方向(横、纵、斜)。如果某个方向连续五颗棋子是同一方玩家的棋子,则判定为胜利。

5. checkDirection()函数

辅助函数,检查某个方向(横、纵或斜)上是否存在五颗相同棋子。如果存在五颗连续的棋子,返回1,表示胜利条件成立。

6. playGame()函数

游戏的主控制函数。初始化棋盘后,进入一个循环,轮流让玩家输入棋步。如果某玩家胜利或棋盘满了,则游戏结束。


项目总结

本项目成功实现了一个简单的五子棋游戏。通过使用二维数组来表示棋盘,并通过函数模块化的设计,使得代码结构清晰且易于扩展。在实现过程中,主要完成了棋盘的显示、玩家输入的验证、胜负判断和游戏流程的控制等核心功能。

项目收获:

  • 学会了如何使用二维数组表示棋盘。
  • 熟悉了函数的模块化设计,增强了代码的可维护性。
  • 提升了C语言编程能力,尤其是在条件判断和循环控制方面。

扩展思路:

  • 可以添加悔棋功能,让玩家可以撤回上一步棋。
  • 可以使用图形化界面(如SDL)来增加用户体验。
  • 可以设计AI对战模式,允许玩家与计算机对战。

通过这个项目,我们能够更好地理解如何在C语言中处理二维数据,如何设计游戏逻辑,并通过实际应用增强自己的编程能力。


这个项目涉及的功能较为简单,但可以通过不断扩展和优化,逐渐形成一个完整且富有挑战的五子棋游戏系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值