【c语言】三子棋详解

一、三子棋游戏介绍

三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。

如果两个人都掌握了技巧,那么一般来说就是平棋。一般来说,第二步下在中间最有利(因为第一步不能够下在中间),下在角上次之,下在边上再次之。最大的好处就是随便找个地方就可以玩这个简单而有趣的游戏了。

二、主函数test部分

我们将代码分到下面三个部分来写

test.c用来实现主函数

game.c用来实现游戏函数

game.h用来声明函数

2.1设计菜单

首先在我们需要设计一个游戏开始菜单,玩家可以自行选择开始游戏,游戏模式,结束游戏,下面是在主函数写的菜单代码

void menu()
{
    printf("*****************************\n");
    printf("********   1. play     ******\n");
    printf("********   0. eixt     ******\n");
    printf("*****************************\n");
}

2.2 test函数

test函数通过使用一个Switch函数,根据用户输入input的值来选择游戏模式,开始游戏或者退出游戏,若用户选择1,则进入game函数进行游戏。

void test()
{
    int input = 0;
    do
    {
        menu();
        printf("请选择:");
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            printf("退出游戏\n");
            break;
        case 1:
            game();
            break;
        default:
            printf("选择错误\n");
            break;
        }
    } while (input);
}

2.3 主函数部分

主函数仅调用test函数,其它函数进行分开写,由test函数调用,这样写会让程序简洁,更加清晰,方便读者理解程序。

int main()
{
    srand((unsigned)time(NULL));
    test();
    return 0;
}

三、游戏设计部分

3.1初始化棋盘函数

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

3.2 打印棋盘函数

打印棋盘时要注意,棋盘最右边不需要打印“|”,棋盘最下边不需要打印“—”,所以使用了if判断函数,当j < col – 1才打印“|”,i < row – 1才打印“—”,这样打印出来的出事化棋盘就如下图所示。

void print_board(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        int j = 0;
        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");
        }
    }
}

3.3玩家下棋函数

玩家下棋函数要注意的一点是,数组下表是从0开始,但玩家在下棋不一定会知道这个规则,所以我们让玩家输入的坐标从1开始,再将输入的坐标进行-1的操作。

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

3.5电脑下棋函数

电脑下棋这里采用时间随机函数,通过rand()取到的随机值进行对行和列取余,保证随机值在0~行和列数之间的数。

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

3.6判断输赢函数

判断输赢函数主要由四个子函数组成,分别为判断行、判断列、判断对角线以及判断是否平局,具体判断方法是根据三个位置的符号都相等且不为空格时成立,若没有满足胜利的情况,进入判断是否平局函数,判断是否平局函数调用了一个is_full子函数,它的作用是用来判断是否棋盘满了,如果没有分出胜负,又判断出棋盘满了,则视为平局,返回字符P;

static int is_full(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 is_win(char board[ROW][COL], int row, int col)
{
    int i = 0;
    int j = 0;
    //判断三行
    for (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 (j = 0; j < col; j++)
    {
        if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
            return board[0][j];
    }
//判断对角线
    if (board[0][0] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    {
        return board[0][0];
    }
    if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
    {
        return board[0][0];
    }
//判断是否平局
    if (is_full(board, ROW, COL) == 1)
    {
        return 'P';
    }
    return 'C';
}

3.7 主函数中game函数模块

该模块主要用于调用game.c中的各个游戏实现函数,该函数由一个循环构成,只有当一方胜利或平局时才会跳出循环。

void game()
{
    char board[ROW][COL];
    //初始化棋盘
    init_board(board, ROW, COL);
    print_board(board,ROW, COL);
    int ret;
    while (1)
    {
    //玩家下棋
        player_move(board, ROW, COL);
        print_board(board, ROW, COL);
        ret = is_win(board, ROW, COL);
    //判断输赢
        if (ret != 'C')
        {
            break;
        }
//电脑下棋
        computer_move(board, ROW, COL);
        print_board(board, ROW, COL);
//判断输赢
        ret = is_win(board, ROW, COL);
        if (ret != 'C')
        {
            break;
        }
    }
//根据返回值进行游戏输赢的判定
    if (ret == '*')
        printf("玩家胜利\n");
    else if (ret == '#')
        printf("电脑胜利\n");
    else if (ret=='P')
        printf("平局\n");
}

四、game.h函数

该函数主要进行头文件以及函数的声明,还用了define定义行和列,这样做的好处是方便棋盘大小的修改,如修改成10*10的棋盘,我们只需要进行修改define定义的值就可以了。

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 3
#define COL 3

//初始化棋盘
void init_board(char board[ROW][COL],int row, int col);
//打印棋盘
void print_board(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);

五、测试结果

5.1玩家胜利

5.2电脑胜利

5.3平局

六、总结

在进行三子棋游戏设计时,应该先理清楚设计的思路和逻辑,然后再将各个部分功能函数进行实现,还有设计时还需要从玩家的角度考虑问题,比如玩家输入时的坐标从1开始。还有棋盘设计时,要灵活设计,利用宏定义行和列,方便后面修改棋盘的大小。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三子棋是一种简单的棋类游戏,玩家和电脑轮流在一个3x3的棋盘上下棋。玩家输入的坐标会在棋盘上标记为"*",而电脑会自动选择一个合适的位置下棋。下面是一个简单的C语言实现的例子: 首先,我们需要初始化一个3x3的二维数组来表示棋盘,并用空格字符来表示棋盘上的空位。\[1\] 然后,我们可以编写一个函数来让玩家输入下棋的坐标,并将其标记在棋盘上。\[2\]这个函数会检查玩家输入的坐标是否合法,即在1-3的范围内,并且对应的位置在棋盘上是空的。如果是合法的,就将该位置标记为"*",否则要求玩家重新输入。 接下来,我们可以编写一个函数来让电脑下棋。这个函数可以随机选择一个合法的位置,并将其标记在棋盘上。\[3\]同样,这个函数也会检查选择的位置是否合法,并且对应的位置在棋盘上是空的。 最后,我们可以使用一个while循环来实现玩家和电脑轮流下棋的过程。每次落子后,都会打印当前的棋盘状态。当棋盘上出现三个连续的"*"或"O"时,游戏结束。 这是一个简单的C语言实现的三子棋游戏。希望对你有帮助! #### 引用[.reference_title] - *1* *2* [C语言——简单三子棋](https://blog.csdn.net/weixin_46263870/article/details/123002439)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [c语言三子棋](https://blog.csdn.net/wastedyouth/article/details/124169006)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值