C语言——初级三子棋游戏的实现

简介: C语言史上最全初级三子棋游戏的实现,看完点个关注哦

一、三子棋游戏的整体设计思路

首先我们可将实现该游戏代码总体分为三个部分来实现:
1.test.c三子棋游戏的测试实现
2.game.h 三子棋游戏的函数声明
3.game.c 三子棋游戏的实现

二、三子棋游戏的各部分代码实现

2.1游戏菜单的打印

我们知道一个游戏程序的实现,我们必须先要打印一个游戏菜单来供游戏用户选择进入游戏,还是选择退出游戏,我们可以通过if---else语句或者switch语句来实现该功能模块的实现,在此,我通过if---else语句来为大家演示。我们先打印一个游戏菜单,在此通menu()来实现其打印:

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

}

接下来我们来实现游戏进入或者退出模块:

int main()
{
    //游戏菜单打印
    menu();
    //判断进入游戏界面
    int i = 0;
    
    while (1)
    {
        if (i == 1)
        {
            //成功进入游戏
            game();
            break;
            
        }
        else if (i == 0)
        {
            printf("退出游戏成功!\n");
            break;
        }
        else
        {
            printf("输入错误,请重新输入!\n");
            break;
        }
    }


    return 0;
}

游戏代码运行截图:
在这里插入图片描述

2.2对游戏棋盘进行初始化

在对进入游戏菜单进行选择之后,我们需要对游戏菜单进行初始化操作,在此我们通过自定义一个==init_board()==来实现该阶段:

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

我们用==ROW==来代表三子棋游戏的行数,用==COL==来代表三子棋游戏的列数
三子棋顾名思义为一个3*3的游戏框架,所以我们可以利用二维数组来实现其功能:

char board[ROW][COL] = { 0 };

2.3对三子棋游戏棋盘进行装饰

在对棋盘进行初始化之后,我们需要对其进行一定的装饰,使其变得更加美观,使其更加具有一定的观赏性,所以我们可以通过自定义一个display_board函数来实现。


//装饰棋盘
void display_board(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
        //数据格式
        //printf(" %c | %c | %c \n ", board[i][0], board[i][1], board[i][2]);
    {
        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)
        {
            //printf("---|---|---\n");
            for (j = 0; j < col; j++)
            {
                printf("---");
                if (j < col - 1)
                    printf("|");
            }
            printf("\n");
        }
    }
}

运行代码如下:
在这里插入图片描述
注意:我们为了避免以后可能会产生不必要的麻烦,我们需要定义两个全局变量==ROW== 和==COL==,这样我们就可以通过控制ROW和COL来控制整个游戏棋盘。

2.4 玩家用户下棋模块的实现

实现该功能我们需要注意两个点:
==1.玩家用户输入的坐标是否合法
2.玩家用户输入的坐标地址是否被占用==
我们通过自定义player_board()来实现该功能
代码实现如下:

//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
    int x = 0;
    int y = 0;
    printf("玩家下棋:>");
    while (1)
    {
        printf("请输入需要下棋的坐标:>");
        scanf("%d %d", &x, &y);
        //需要注意:1.坐标的合法性 2.坐标是否被占用
        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");
        }
    }
}

2.5电脑随机下棋模块的实现

使电脑产生随机数字我们需要运用==rand==和==time==函数,所以我们需要包含两个头文件==stdlib.h==和==time.h==,同时我们需要判断电脑下棋的位置是否被用户所占用,我们通过自定义computer_move函数来实现该功能。

void computer_move(char board[ROW][COL], int row, int col)
{
    printf("电脑下棋:>\n");
    //利用rand来产生随机数
    while (1)
    {
        int x = rand() % row;
        int y = rand() % col;
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }
    }
}

2.6三子棋游戏胜负的判断

我们通过自定义is_win函数来实现该功能,我们规定如下规则:
==1.玩家赢 --> 返回'*'
2.电脑赢 --> 返回'#'
3.平局 --> 返回'Q'
4.游戏继续 --> 返回'C'==
代码如下:

char is_win(char board[ROW][COL], int row, int col)
{
    int i = 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[0][i];
        }
        
    }
    for (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[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    {
        return board[1][1];

    }
    //判断平局
    if (is_full(board, row, col) == 1)
    {
        return 'Q';
    }
    return 'C';

}

在判断平局时我们还需要通过自定义一个full_board函数来实现该功能:

//棋盘满了,返回1
//不满,返回0
static int is_full(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++)
        {
            if (' ' == board[i][j])
            {
                return 0;
            }
        }
    }
    return 1;
}

三、三子棋游戏运行实况

在这里插入图片描述

四、各部分完整代码附录

==test.c==完整代码块

# define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
    printf("*********************************\n");
    printf("**********    1.play   **********\n");
    printf("**********    0.exit   **********\n");
    printf("*********************************\n");

}
void game()
{
    char ret = 0;
    //数据的存储需要一个3*3的二维数组
    char board[ROW][COL] = { 0 };
    //初始化棋盘
    init_board(board, ROW, COL);
    display_board(board, ROW, COL);
    //玩游戏部分
    while (1)
    {
        player_move(board, ROW, COL);
        display_board(board, ROW, COL);
        ret=is_win(board, ROW, COL);
        if (ret != 'C')
            break;
        computer_move(board, ROW, COL);
        display_board(board, ROW, COL);
        ret = is_win(board, ROW, COL);
        if (ret != 'C')
            break;
    }
    //规定:玩家赢- *
    //      电脑赢-#
    //       平局 -Q
    //       游戏继续-C
    if (ret == '*')
    {
        printf("玩家赢\n");
    }
    else if (ret == '#')
    {
        printf("电脑赢\n");
    }
    else if (ret == 'Q')
    {
        printf("平局\n");
    }
    display_board(board, ROW, COL);

}
int main()
{
    //游戏菜单打印
    menu();
    //判断进入游戏界面
    int i = 0;
    srand((unsigned int)time(NULL));
    scanf("%d", &i);
    while (1)
    {
        if (i == 1)
        {
            //成功进入游戏
            game();
            break;
            
        }
        else if (i == 0)
        {
            printf("退出游戏成功!\n");
            break;
        }
        else
        {
            printf("输入错误,请重新输入!\n");
            break;
        }
    }


    return 0;
}

==game.c==完整代码块

# define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            board[i][j] = ' ';
        }
    }
}

//装饰棋盘
void display_board(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
        //数据格式
        //printf(" %c | %c | %c \n ", board[i][0], board[i][1], board[i][2]);
    {
        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)
        {
            //printf("---|---|---\n");
            for (j = 0; j < col; j++)
            {
                printf("---");
                if (j < col - 1)
                    printf("|");
            }
            printf("\n");
        }
    }
}
//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
    int x = 0;
    int y = 0;
    printf("玩家下棋:>");
    while (1)
    {
        printf("请输入需要下棋的坐标:>");
        scanf("%d %d", &x, &y);
        //需要注意:1.坐标的合法性 2.坐标是否被占用
        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)
{
    printf("电脑下棋:>\n");
    //利用rand来产生随机数
    while (1)
    {
        int x = rand() % row;
        int y = rand() % col;
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }
    }
}

//棋盘满了,返回1
//不满,返回0
static int is_full(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++)
        {
            if (' ' == board[i][j])
            {
                return 0;
            }
        }
    }
    return 1;
}
char is_win(char board[ROW][COL], int row, int col)
{
    int i = 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[0][i];
        }
        
    }
    for (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[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    {
        return board[1][1];

    }
    //判断平局
    if (is_full(board, row, col) == 1)
    {
        return 'Q';
    }
    return 'C';

}

game.h完整代码块

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
# define ROW 3   //ROW 代表棋盘的行数
# define COL 3   //COL 代表棋盘的列数
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//装饰棋盘
void display_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);

在这里插入图片描述

相关文章
|
1月前
|
机器学习/深度学习 C语言
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
【8月更文挑战第5天】本篇文章用C语言采用多文件编写实现了一个基础的扫雷游戏(附源码),并讲解了关于函数递归的基础概念及其相对应的习题练习(附源码)
35 1
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
|
2月前
|
存储 C语言 开发者
C语言实战 | Flappy Bird游戏
【7月更文挑战第4天】Flappy Bird是由越南开发者制作的简单却极具挑战性的游戏,玩家需控制小鸟穿越水管障碍。游戏涉及角色初始化、显示和更新。小鸟和水管结构体存储数据,使用变量和数组。初始化小鸟和水管,显示背景、小鸟和水管,更新小鸟位置及碰撞检测。代码示例展示了小鸟和水管的状态管理,当小鸟与管道碰撞或触地时,游戏结束。游戏的成功在于其独特的虐心体验。
51 0
C语言实战 | Flappy Bird游戏
|
1月前
|
算法 编译器 C语言
【C语言篇】猜数字游戏(赋源码)
rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的⼤⼩是依赖编译器上实现的,但是⼤部分编译器上是32767。
|
2月前
|
存储 编译器 C语言
C语言实战 | “贪吃蛇”游戏
【7月更文挑战第5天】在C语言实战中,本文档介绍了如何构建一个简单的“贪吃蛇”游戏。游戏的核心是控制蛇移动并增长,当吃掉食物时,蛇的身体变长。数据结构使用固定大小的数组表示蛇的位置,变量存储食物位置和蛇的长度。初始化后,利用非阻塞式`getKey()`函数实现WASD键盘控制蛇的运动方向。虽然蛇的边界检测和吃食物后的增长尚未详细说明,但提到了这些问题作为练习留给读者解决,并预告将在后续章节讨论模块化编程以简化复杂代码。
77 0
C语言实战 | “贪吃蛇”游戏
|
2月前
|
存储 数据管理 C语言
C语言实战 | 使用链表完成“贪吃蛇”游戏
【7月更文挑战第1天】整体思维,即系统思维,强调以整体视角理解事物。在编程中,结构体体现这种思想,将相关变量打包处理。示例展示了如何用链表而非数组实现“贪吃蛇”游戏,链表提供了更灵活的动态数据管理。一系列代码图片详细描绘了链表结构体在游戏中的应用,包括节点定义、移动、碰撞检测等,凸显了使用链表的优势和代码的清晰组织。
32 0
C语言实战 | 使用链表完成“贪吃蛇”游戏
|
3月前
|
算法 编译器 C语言
猜数字游戏C语言代码实现
猜数字游戏C语言代码实现
|
3月前
|
存储 C语言
C语言实战 | “贪吃蛇”游戏重构
在程序设计中,模块化思维至关重要,尤其对于复杂项目,它帮助分解任务,便于团队协作。以“贪吃蛇”游戏为例,游戏涉及两个角色:蛇和食物。使用数组存储蛇的位置,变量存储食物位置。游戏流程分为初始化、显示和更新数据。初始化时,食物位置随机,蛇的位置根据数组设定。显示数据则根据这些信息在屏幕上呈现角色。更新数据时,处理蛇的移动和增长以及食物的生成和消失。类似地,通过模块化方法可开发“打砖块”游戏,涉及球、球拍和砖墙,每个角色都有相应数据结构和更新逻辑。通过这种方式,游戏开发就像搭建积木,遵循框架逐步实现。
59 0
C语言实战 | “贪吃蛇”游戏重构
|
3月前
|
C语言
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
21 1
|
3月前
|
C语言
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
21 1
|
3月前
|
存储 安全 Serverless
扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会
扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会