带你一步步完成C语言完成的第一个小游戏(详细讲解)还不快来!

文章目录

三子棋介绍

三子棋 是一种民间传统游戏,又叫九宫棋、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。

QQ图片20230622212035.png

确定步骤开始配置文件

我们选择的是用多文件的形式教大家独立完成,三子棋游戏的实现

首先我们要准备三个文件分别是 game.h 来声明函数 game.c 来实现函数的定义 test.c 大体的文件架构就完成了

QQ图片20230624171603.png

游戏代码的实现

步骤一、确定文件主体test.c的几个部分

  • 一、游戏的菜单来确定是否开始和退出

输入1为开始游戏输入0为退出游戏

#include “game.h”//由于我们要调用game.h头文件所以其他需要的头文件
                //就全部放在game.h里面避免代码冗余,让代码更加简洁
//菜单
void menu()
{


    printf("************************\n");
    printf("*******  1.play  *******\n");
    printf("*******  0.exit  *******\n");
    printf("************************\n");
}

int main()
{
    int input = 0;  //创建变量来接收输入的结果
    do
    {   
        //打印菜单
        menu();
        printf("请输入你的选择 >");
        scanf("%d",&input);
        switch (input)
        {
            //开始游戏
        case 1:
            game();//这里先写出游戏函数后面实现
            break; 
            //退出游戏
        case 0: 
            printf("退出游戏!\n");
            break;
        default:
            printf("输入错误,请重新输入!");
            break;
        }
    } while (input);
    return 0;
}

1、编写 game() 函数的主体

  • 1、棋盘的初始化
  • 2、打印棋盘
  • 3、玩家下棋    棋子用 * 表示
  • 4、电脑下棋    棋子用 # 表示
  • 5、判断输赢
    • 玩家赢返回 *****
    • 电脑赢返回 #
    • 平局返回 Q
    • 继续返回 C

1、棋盘的初始化

观察棋盘三子棋盘是3×3的所以我们用3×3的数组存储棋子并完成初始化

void game()//三子棋游戏主体函数
{
    char board[ROW][COL] = {0};
    //初始化数组
    InitBoard(board, ROW, COL);
}
在这里插入代码片

然后先创建实现5个小功能的函数后面再调用

//三子棋游戏
void game()
{





    char board[ROW][COL] = {0};
    //初始化数组
    InitBoard(board, ROW, COL);
    char ret = 0;//用来接收输赢函数返回的  值
    char play = 0;//用来接收下棋坐标被占用的返回值
    //打印棋盘
    DisplayBoard(board, ROW, COL);
    while (1)//创建一个循环只要没有人赢就一直下
    {

        //玩家下棋
        play = PlayMove(board, ROW, COL);
        if (play == 'P')//当下棋时坐标输入错误和坐标被占用就退出循环
                continue;//不让电脑下棋
        //判断输赢
        ret = IsWin(board, ROW, COL);//接收每次判断的结果
        if (ret != 'C')//当返回的不是 C 继续的话就退出说明有人赢了
        {
            system("cls");//退出时清空所有棋盘并打印一遍
            //打印棋盘
            DisplayBoard(board, ROW, COL);      
            break;
        }       
        //打印棋盘
        DisplayBoard(board, ROW, COL);
        //电脑下棋
        ComputerMove(board, ROW, COL);
        system("cls");//每次下完棋后清空屏幕所有内容并打印一遍棋盘
        //打印棋盘    //让每次屏幕上只有一个棋盘
        DisplayBoard(board, ROW, COL);
        //判断输赢
        ret = IsWin(board, ROW, COL);
        if (ret != 'C')//当返回的不是 C 继续的话就退出说明有人赢了
        {               //就进入if里面结束本次循环
            system("cls");//退出时清空所有棋盘并打印一遍
            //打印棋盘
            DisplayBoard(board, ROW, COL);
            break;
        }

    }
    if (ret == '*')
    {
        printf("玩家赢!\n");
    }
    else if (ret == '#')
    {
        printf("电脑赢!\n");
    }
    else 
    {
        printf("平局!\n");
    }
}

步骤二、game.h 头文件的声明

前面已经把游戏拆成了5个小部分接下来就是声明和定义了

  • 声明和经常使用的头文件,我们把它都放在 game.h 的头文件里
#pragma once

#include <stdio.h> //输入输出头文件
#include <stdlib.h> //获取随机函数头文件 后面会用
#include <time.h> //srand函数所需要获取时间戳的头文件 后面会用
#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);
//玩家下棋
int PlayMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
char IsWin(char board[ROW][COL], int row, int col);
//平局
int  IsFull(char board[ROW][COL], int row, int col);

步骤三、game.c 的函数实现

各种函数名和 函数声明 我们已经完成了接下来就是在 game.c 里面实现这些小功能

#include "game.h"//先在game.c里面调用
                //在game.h里面声明的头文件和函数

1、初始化棋子数组函数的实现

用循环遍历数组的棋子使里面存放的都是空格

//初始化数组 
void InitBoard(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++)

        {

            board[i][j] = ' ';
        }
    }
}

2、打印棋盘函数的实现

QQ图片20230624171606.png

观察棋盘发现 分为2个部分组成

QQ图片20230624171609.png

  • 第一部分是 (空格 棋子 空格 | 空格 棋子 空格 | 空格 棋子 空格)
  • 第二部分是 (- – – | – – – | – – -)而每个部分都要输出三次

所以我们用for循环来写

| 每行只有俩个所以要写个if判断

//打印棋盘
void DisplayBoard(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");
        for (j = 0; j < col; j++)
        {

            printf("---");
            if (j < col - 1)
                printf("|");
        }
        printf("\n");
        
    }
}

3、玩家下棋函数的实现

这边接收的是玩家输入的坐标 一般是1 开始 到 3

但是数组下标是从0开始所以把每次玩家输入的行和列 – 1 就好了

//玩家下棋
int  PlayMove(char board[ROW][COL], int row, int col)
{





    int x = 0;
    int y = 0;
    printf("玩家下棋");
    printf("请输入坐标,中间用空格隔开 ->");
    
    scanf("%d %d",&x,&y);
    //检查坐标是否合法
    if (x >= 1 && y >= 1 && x <= row  && y <= col )
    {

        if (board[x - 1][y - 1] == ' ')
        {
             board[x - 1][y - 1] = '*';
        }

        else
        {

            printf("坐标被占用请重新输入!\n");
            return 'P';
        }
    }
    else
    {
        printf("输入错误请重新输入!\n");
        return 'P';
    }
    
}

4、电脑下棋函数的实现

我们让电脑每次产生随机数坐标 产生行和列 来下棋

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{





    //随机下棋
    int x = 0;
    int y = 0;
    printf("电脑下棋:>\n");
    while (1)
    {
        x = rand() % row;//产生的随机数模除我们需要的行 产生的数就在行0~3之内了
        y = rand() % col;
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }

    }
    
}

5、判断输赢函数的实现

//玩家赢返回 *
//电脑赢返回 #
//平局返回   Q
//继续返回   C
char IsWin(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][1] != ' ')
        {
            return board[i][0];
        }

        //判断列
        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 (IsFull(board, row, col) == 1)
    {
        return 'Q';
    }
    else 
    {
        return 'C';
    }
    //继续 C
}

6、判断平局函数的实现

遍历一遍数组当数组里面存放的没有空格就说明棋盘满了 平局

//平局
int IsFull(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 board[ROW][COL] = {0};
    //初始化数组
    InitBoard(board, ROW, COL);
    char ret = 0;
    char play = 0;
    //打印棋盘
     DisplayBoard(board, ROW, COL);
    while (1)
    {

        //玩家下棋
        play = PlayMove(board, ROW, COL);
        if (play == 'P')
            continue;
        //判断输赢
        ret = IsWin(board, ROW, COL);
        if (ret != 'C')
        {
            system("cls");
            //打印棋盘
            DisplayBoard(board, ROW, COL);      
            break;
        }       
        //打印棋盘
        DisplayBoard(board, ROW, COL);
        //电脑下棋
        ComputerMove(board, ROW, COL);
        system("cls");
        //打印棋盘
        DisplayBoard(board, ROW, COL);
        //判断输赢
        ret = IsWin(board, ROW, COL);
        if (ret != 'C')
        {   
            system("cls");
            //打印棋盘
            DisplayBoard(board, ROW, COL);
            
            break;
        }
    }
    if (ret == '*')
    {
        printf("玩家赢!\n");
    }
    else if (ret == '#')
    {
        printf("电脑赢!\n");
    }
    else 
    {
        printf("平局!\n");
    }
}
int main()
{
    int input = 0;  
    do
    {   
        srand((unsigned int)time(NULL));
        //打印菜单
        menu();
        printf("请输入你的选择 >");
        scanf("%d",&input);
        switch (input)
        {
            //开始游戏
        case 1:
            game();
            break; 
            //退出游戏
        case 0: 
            printf("退出游戏!");
            break;
        default:
            printf("输入错误,请重新输入!");
            break;
        }

    } while (input);
    return 0;
}

game.h代码

#pragma once

#include <stdio.h>
#include <stdlib.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);
//玩家下棋
int PlayMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
char IsWin(char board[ROW][COL], int row, int col);
//平局
int  IsFull(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)
{


    int i = 0;
    for (i = 0; i < row; i++)
    {
        int j = 0;
        for (j = 0; j < col; j++)
        {
            board[i][j] = ' ';
        }
    }
}
//打印棋盘
void DisplayBoard(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");
        for (j = 0; j < col; j++)
        {
            printf("---");
            if (j < col - 1)
            {
                
                printf("|");
            }
                
        }

        printf("\n");
        
    }
}
//玩家下棋
int  PlayMove(char board[ROW][COL], int row, int col)
{
    int x = 0;
    int y = 0;
    printf("玩家下棋");
    printf("请输入坐标,中间用空格隔开 ->");
    
    scanf("%d %d",&x,&y);
    //检查坐标是否合法
    if (x >= 1 && y >= 1 && x <= row  && y <= col )
    {
        if (board[x - 1][y - 1] == ' ')
        {
             board[x - 1][y - 1] = '*';
        }
        else
        {
            printf("坐标被占用请重新输入!\n");
            return 'P';
        }
    }
    else
    {
        printf("输入错误请重新输入!\n");
        return 'P';
    }
    
}
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
    //随机下棋
    int x = 0;
    int y = 0;
    printf("电脑下棋:>\n");
    while (1)
    {
        x = rand() % row;
        y = rand() % col;
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }

    }
    
}

//玩家赢 *
//电脑赢 #
//平局   Q
//继续     C
char IsWin(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][1] != ' ')
        {
            return board[i][0];
        }
        //判断列
        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 (IsFull(board, row, col) == 1)
    {
        return 'Q';
    }
    else 
    {
        return 'C';
    }
    //继续 C
    
}
//平局
int IsFull(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;
}

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYyswLPN' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片