硅基计划 练习 扫雷升级版

(我们接上次扫雷练习继续去讲)##前情提要##之前已经留了个悬念想实现插旗,领域展开,计时,难度选择四个功能经过我结合互联网知识&

(我们接上次扫雷练习继续去讲)

##前情提要##

之前已经留了个悬念

想实现插旗,领域展开,计时,难度选择四个功能

经过我结合互联网知识,写出了扫雷升级版,接下来我就来讲解我如何实现的



一、插旗子

1.我们先规定:输入坐标后再输入“F”或者是“f,是执行插旗子操作,输入“C”或者是“c,则进行排查雷操作

##示例输入:5 5 F←插旗子,6 6 C←排雷

2.我们还规定:假设这个地方已经插了旗子,你可以通过再输入“F”或者“f”来取消插旗,这样就恢复了棋盘最开始的“*”

3.当你输入“C”或者“c”执行排雷后,我们开始正常的排雷函数实现,这里不再赘述

二、计时

1.我们在开始游戏时候先记录下此刻的时间,我们再查找地雷函数中调用clock函数来计算时钟滴答数。

2.开始时我们记录一次,被雷炸死或者游戏胜利我们记录一次,我们再用double类型的双精度浮点型来计算时间差除上double类型的一秒钟的时钟周期来计算耗时多少秒,打印出来即可,在打印棋盘进行展示供玩家观看自己的胜利或者是失败原因

三、领域展开

1.前提是我们输入的坐标不是雷,没有被炸死

2.在排查雷函数中我们调用领域展开函数

3.在领域展开函数中,我们要判断这个坐标是不是在棋盘的范围内

4.在展开区域过程中,我们要判断这个地方到底是不是未知区域(即是不是“*”),如果不是未知区域我们就return返回不执行下面的代码

5.不满足第四个条件我们再来判断这个地方是不是雷,如果是雷我们也用return返回,下面代码不再执行,这样为后续递归如果是雷不至于被炸死,毕竟这个是系统自己的领域展开,而不是玩家的操作,因此如果是雷我们就略过这个区域

6.如果上述两点均未被执行,我们就可以执行领域展开函数,调用统计周围雷的数量的函数,借用“__?__:__”判别式来判断周围雷的数量是否为0,如果是0,就不用在当前区域存储雷数量,维持原样的字符'0'样式。而如果存在雷,则我们在统计完雷数量后再加上字符'0',存放在供玩家展示的棋盘中,展示雷的数量

7.假设周围雷的数量确定是0,我们展开周围区域,利用for循环在当前坐标位置周围9x9位置进行展开,不能展开中心区域(即当前x,y坐标位置),在循环的时候我们利用if函数判断这个地方是不是中心区域,如果是利用continue跳过本轮循环,否则我们进行递归函数,以上全部操作再重复执行,直到限制条件为止

四、选择难度

##由于这个地方难度很大,我还没学习,等以后学习了动态内存分配再来解释,这里就不多解释,我这里就是让AI帮我实现了想法

当然如果你会,你可以在讨论区告诉我或者给我推荐好文章,我会积极去学习的


五、代码展示

 game.h函数声明头文件

#pragma once

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

// 定义难度相关的宏
#define EASY_ROW 5
#define EASY_COL 5
#define EASY_TRUECOUNT 5

#define MEDIUM_ROW 8
#define MEDIUM_COL 8
#define MEDIUM_TRUECOUNT 15

#define HARD_ROW 10
#define HARD_COL 10
#define HARD_TRUECOUNT 30

// 定义默认难度
#define DEFAULT_ROW 9
#define DEFAULT_COL 9
#define DEFAULT_TRUECOUNT 10

// 声明全局变量
extern int selected_row;
extern int selected_col;
extern int selected_truecount;

// 函数声明
void arr(char** arr, int x, int y, char set);
void printfarr(char** arr, int x, int y);
void setarrmine(char** brr, int r, int c);
int countmine(char** crr, int x, int y);
void expand_area(char** mine, char** show, int x, int y);
void findarrmine(char** mine, char** show, int r, int c);
void select_difficulty();

game.c函数定义文件 

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

// 初始化数组函数
void arr(char** arr, int x, int y, char set)
{
    for (int i = 0; i < x; i++) 
    {
        for (int q = 0; q < y; q++) 
        {
            arr[i][q] = set;
        }
    }
}

// 打印数组函数
void printfarr(char** arr, int x, int y) 
{
    printf("------扫雷精简版-----\n");
    for (int i = 0; i <= y; i++) 
    {
        printf("%d ", i);
    }
    printf("\n");
    for (int i = 1; i <= x; i++) 
    {
        printf("%d ", i);
        for (int q = 1; q <= y; q++) 
        {
            printf("%c ", arr[i][q]);
        }
        printf("\n");
    }
}

// 设置地雷函数
void setarrmine(char** brr, int r, int c) 
{
    int count = selected_truecount;
    while (count) {
        int x = rand() % r + 1;
        int y = rand() % c + 1;
        if (brr[x][y] == '0')
        {
            brr[x][y] = '1';
            count--;
        }
    }
}

// 计算周围地雷数量函数
int countmine(char** crr, int x, int y) 
{
    int c = 0;
    for (int i = -1; i <= 1; i++)
    {
        for (int q = -1; q <= 1; q++) 
        {
            if (crr[x + i][y + q] == '1') 
            {
                c++;
            }
        }
    }
    return c;
}

// 递归展开周围不是雷的区域
void expand_area(char** mine, char** show, int x, int y) 
{
    if (x < 1 || x > selected_row || y < 1 || y > selected_col) 
        return;
    if (show[x][y] != '*') 
        return;
    if (mine[x][y] == '1') 
        return;
    int count = countmine(mine, x, y);
    show[x][y] = count == 0 ? '0' : count + '0';
    if (count == 0) 
    {
        for (int i = -1; i <= 1; i++) 
        {
            for (int j = -1; j <= 1; j++) 
            {
                if (i == 0 && j == 0) 
                    continue;
                expand_area(mine, show, x + i, y + j);
            }
        }
    }
}

// 查找地雷函数
void findarrmine(char** mine, char** show, int r, int c) 
{
    int x = 0,y = 0;
    int win = 0;
    char operation;
    clock_t start_time = clock();
    while (win < r * c - selected_truecount) 
    {
        printf("请输入排查坐标及操作(F插旗/C排雷): ");
        scanf("%d %d %c", &x, &y, &operation);
        if (x > 0 && x <= r && y > 0 && y <= c) 
        {
            if (operation == 'F' || operation == 'f') 
            {
                if (show[x][y] == '*') 
                {
                    show[x][y] = 'F';
                }
                else if (show[x][y] == 'F') 
                {
                    show[x][y] = '*';
                }
                printfarr(show, r, c);
            }
            else if (operation == 'C' || operation == 'c') 
            {
                if (mine[x][y] == '1') 
                {
                    printf("游戏结束\n");
                    printfarr(mine, r, c);
                    clock_t end_time = clock();
                    double duration = (end_time - start_time) / (double)CLOCKS_PER_SEC;
                    printf("游戏用时:%.2f 秒\n", duration);
                    break;
                }
                else
                {
                    expand_area(mine, show, x, y);
                    printfarr(show, r, c);
                    win++;
                }
            }
        }
        else 
        {
            printf("坐标非法,重新输入\n");
        }
    }
    if (win == r * c - selected_truecount)
    {
        printf("恭喜你排雷成功\n");
        printfarr(mine, r, c);
        clock_t end_time = clock();
        double duration = (end_time - start_time) / (double)CLOCKS_PER_SEC;
        printf("游戏用时:%.2f 秒\n", duration);
    }
}

try.c游戏主体文件 

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

char operation; // 用于存储用户操作的全局变量

// 定义全局变量
int selected_row = DEFAULT_ROW;
int selected_col = DEFAULT_COL;
int selected_truecount = DEFAULT_TRUECOUNT;

// 菜单函数
void menu() 
{
    printf("----扫雷 精简版----\n");
    printf("----1.   开始 ----\n");
    printf("----2.   选择难度 ----\n");
    printf("----0.   退出 ----\n");
    printf("------------------\n");
}

// 游戏函数
void game() 
{
    // 动态分配内存
    char** arrmine = (char**)malloc((selected_row + 2) * sizeof(char*));
    for (int i = 0; i < selected_row + 2; i++)
    {
        arrmine[i] = (char*)malloc((selected_col + 2) * sizeof(char));
    }
    char** arrshow = (char**)malloc((selected_row + 2) * sizeof(char*));
    for (int i = 0; i < selected_row + 2; i++) 
    {
        arrshow[i] = (char*)malloc((selected_col + 2) * sizeof(char));
    }
    arr(arrmine, selected_row + 2, selected_col + 2, '0');
    arr(arrshow, selected_row + 2, selected_col + 2, '*');
    printfarr(arrshow, selected_row, selected_col);
    setarrmine(arrmine, selected_row, selected_col);
    findarrmine(arrmine, arrshow, selected_row, selected_col);
    // 释放内存
    for (int i = 0; i < selected_row + 2; i++) 
    {
        free(arrmine[i]);
        free(arrshow[i]);
    }
    free(arrmine);
    free(arrshow);
}

// 难度选择函数
void select_difficulty()
{
    int diff;
    printf("请选择难度:\n");
    printf("1. 简单\n");
    printf("2. 中等\n");
    printf("3. 困难\n");
    scanf("%d", &diff);
    switch (diff) 
    {
    case 1:
        selected_row = EASY_ROW;
        selected_col = EASY_COL;
        selected_truecount = EASY_TRUECOUNT;
        break;
    case 2:
        selected_row = MEDIUM_ROW;
        selected_col = MEDIUM_COL;
        selected_truecount = MEDIUM_TRUECOUNT;
        break;
    case 3:
        selected_row = HARD_ROW;
        selected_col = HARD_COL;
        selected_truecount = HARD_TRUECOUNT;
        break;
    default:
        printf("无效的选择,使用默认难度。\n");
        selected_row = DEFAULT_ROW;
        selected_col = DEFAULT_COL;
        selected_truecount = DEFAULT_TRUECOUNT;
    }
}

// 主函数
int main() 
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do {
        printf("扫雷游戏加载中...\n");
        Sleep(1000);
        int sign = 1;
        while (sign <= 3) 
        {
            printf(".");
            Sleep(1000);
            sign++;
        }
        printf("\n");
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input) 
        {
        case 1:
            game();
            break;
        case 2:
            select_difficulty();
            break;
        case 0:
            printf("您已退出");
            break;
        default:
            printf("请重新选择");
            break;
        }
    } while (input);
    return 0;
}

此文章仅代表作者个人观点,如果你有更好意见,欢迎讨论


END 

发布者:admin,转转请注明出处:http://www.yc00.com/web/1754416075a5156790.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信