你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

C语言数组实例-三子棋

2021/12/30 3:08:54

三子棋

这个项目是B站鹏哥C语言的课程中。数组部分的实战代码。

博主只是跟着学跟着写的。

整体其实并不是很复杂,将最复杂的game模块进行了独立编写,所以出现了game.c和game.h。

刚入手时需要注意的是一定不要想这个项目有多复杂。

编写步骤
  1. 理思路(整体流程)

项目进入需要的界面。+ 功能选择。 将这些写完再考虑下一步。

功能选择: 进入游戏 || 退出游戏 || 输入错误。

  1. 游戏准备 (将以下出现的小模块都函数来写。)

    (1) 需要棋盘,+ 初始化棋盘。 -->二维数组

    (2) 棋盘的显示。

  2. 游戏开始

    (1) 玩家下棋

    (2) 电脑下棋

    (3)每次下完展示棋盘

  3. 结果判断

    (1) 玩家赢返回"*"

    (2) 电脑赢返回"#"

    (3) 平局返回"Q"

    (4) 继续返回"C"

  4. 整理、解决问题(debug)

三子棋代码

以下是我通过调试的代码。(环境:win10,编译器:Clion)

运行文件main.c
//
// Created by Tian_baby on 2021/12/29.
//

#include "game.h"
//打印初识目录界面
void menu(){
    printf("*****************************\n");
    printf("****  1. play   0. exit  ****\n");
    printf("*****************************\n");
}

//游戏的实现
void game(){
    // 定义数组来存储棋盘
    char board[ROW][COL] = {0};
    char res = 0;
    //初始化棋盘都是空格
    InitBoard(board,ROW,COL);
    //打印棋盘
    DisplayBoard(board,ROW,COL);
    while(1){
        PlayerMove(board,ROW,COL);//玩家下棋
        DisplayBoard(board,ROW,COL);//展示棋盘情况
        res = JudgeWin(board,ROW,COL);
        if(res!='C') break; //结果不等于C代表结束了
        ComputerMove(board,ROW,COL);// 电脑下棋
        DisplayBoard(board,ROW,COL);//展示棋盘的情况
        res = JudgeWin(board,ROW,COL);
        if(res!='C') break;
    }
    if(res == '*') printf("玩家赢。 \n");
    else if(res == '#') printf("电脑。 \n");
    else printf("平局了");

}

// 游戏流程
void test(){
    int input = 0;//功能选择输入项
    // 随机数
    srand((unsigned int)time(NULL));
    // 控制游戏的重复
    do {
        menu();
        printf("请选择: ");
        scanf( "%d",&input);
        switch (input) {
            case 1:
                printf("\n********    三 子 棋   ********\n");
                game();//游戏内容
                break;
            case 0:
                printf("退出游戏\n");
                break;
            default:
                printf("输入错误,请重新输入\n");
                break;
        }
    } while (input);
}

// 主函数
int main() {
    test();
    return 0;
}

在此文件中,test()是整体的流程控制。test()中的srand()是因为要使用rand()函数所以提前准备使用的;menu()是进入功能界面的函数;game()是游戏最主要的内容,其内容写在另一个game.c文件中(后面详细解说)。

game.c的头文件game.h
//
// Created by Tian_baby on 2021/12/29.
//

#ifndef ARR_GAME_GAME_H
#define ARR_GAME_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 JudgeWin(char board[ROW][COL],int row,int col);
//在game中还有一个函数IsFull()是在game.c中自己使用了所以可以不在这里声明。
#endif //ARR_GAME_GAME_H

该文件主要是对game()中函数使用前的声明。

功能文件game.c
//
// Created by Tian_baby on 2021/12/29.
//

#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) {
            if (j == col - 1) printf(" %c ", board[i][j]);
            else printf(" %c |", board[i][j]);
        }
        // 打印分隔行
        printf("\n");
        if (i < row - 1) {
            for (int j = 0; j < col; ++j) {
                (j < col - 1) ? printf("---|") : printf("---");
            }
        };
        printf("\n");
    }
}

// 玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col) {
    int x = 0, y = 0;
    printf("玩家下棋-->>\n");
    printf("请输入你要走的位置:\n");
    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("坐标不存在,请重新输入。");
        }
    }
}

// 电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col) {
    int x = 0, y = 0;
    printf("电脑下棋-->>\n");
    while (1) {
        x = rand() % row;
        y = rand() % col;
        if (board[x][y] == ' ') {
            board[x][y] = '#';
            break;
        }
    }
}

//判断是否填满   返回一棋盘慢了  返回0棋盘没有满
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 JudgeWin(char board[ROW][COL], int row, int col) {
    // 这个函数返回四种状态--玩家赢"*"  电脑赢"#"  平局"Q"  继续"C"
    // 行相等
    for (int i = 0; i < row; ++i) {
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
            return board[i][0];
    }
    // 列相等
    for (int i = 0; i < col; ++i) {
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
            return board[0][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];
    // same_count = 0;
    // for (int i = 0; i < col-1; ++i) {
    //     if (board[i][i] == board[i+1][i+1]&&board[i][i] != ' ')
    //         same_count+=1;
    // }  //-->>这是我自己想的另一种思路  就是判断总次数如果斜线上的所有的值都相等
    //          那么same_count的值应该==ROW-1

    //是否平局
    if(1 == IsFull(board,ROW, COL)) return 'Q';
    return 'C';
}

棋盘的初始化InitBoard( ); 打印棋盘DisplayBoard( ); 玩家下棋PlayerMove( ); 电脑下棋ComputerMove( ); 判断输赢JudgeWin()