逆向软件工程

本逆向软件工程的项目来自我朋友大一做的扫雷项目,以下是其源代码 运行环境是VScode。

点击查看代码
#include<stdio.h>
//#include"asaolei.h"
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2
#define Count 10
void initially(char arr[ROWS][COLS],int r,int c,char ch);
void DisplayBoard(char a[ROWS][COLS],int row,int col);
void setmine(char a[ROWS][COLS],int row,int col);
void menu()//游戏的菜单
{
    printf("********************\n");
    printf("******1、PLAY*******\n");
    printf("******0、exit*******\n");
    printf("********************\n");
}

void initially(char a[ROWS][COLS],int row,int col,char ch)
{
    int i,j;
    for(i=0;i<row;i++)
    {
        j=0;
        for(j=0;j<col;j++)
        {
            a[i][j]=ch;
        }
    }

}

    void DisplayBoard(char a[ROWS][COLS],int row,int col)
    {
        int i,j;
        printf("-------扫雷游戏------\n");
        printf("--------start-------\n");
        for(i=0;i<=col;i++)
        {
            printf("%-2d",i);
        }
        printf("\n");
        for(i=1;i<=row;i++)
        {
            printf("%d",i);
            for(j=1;j<=col;j++)
            {
                printf("%2c",a[i][j]);
            }
            printf("\n");
        }
    }
    void setmine(char a[ROWS][COLS],int row,int col)
    {
        int count = Count;
        while(count)
        {
            int x=rand()%row+1;
            int y=rand()%col+1;//将雷的坐标控制在1~9之内
            if(a[x][y]=='0')
            {
                a[x][y]='1';
                count --;
            }

        }
    }
    int Getmine_count(char mine[ROWS][COLS],int x,int y)
    {
        int count=0,i,j;
        for(i=x-1;i<=x+1;i++)
        {
            for(j=y-1;j<=y+1;j++)
            {
                if(mine[i][j]=='1')
                {
                    count++;
                }
            }
        }
        return count;
    }
    void Findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
    {
        int x;
        int y;
        int win=0;
        printf("请输入要排查的坐标\n");
        while(win<row*col-Count)
        {
            scanf("%d %d",&x,&y);
            if(x>=1&&x<=row&&y>=1&&y<=col)
        {
            if(mine[x][y]=='1')
            {
                printf("很遗憾,你被我埋的雷炸死咯哈哈哈\n");
                printf("小趴菜,让你看看我的雷在哪\n");
                DisplayBoard(mine,ROW,COL);
                break;
            }
            else
            {
                //统计该坐标周围一共有多少个雷
                int n=Getmine_count(mine,x,y);
                show[x][y]=n+'0';
                DisplayBoard(show,ROW,COL);
                win++;
            }
        }
        else{
            printf("坐标非法请重新输入\n");
        }
        if(win==row*col-Count)
        {
            printf("铁子实力有的呢,拆弹专家,排雷成功\n");
            break;
        }
        }
    }
void game()//完成扫雷游戏
{
    char mine[ROWS][COLS] = {0};//全部初始化为‘0’
    char show[ROWS][COLS] = {0};// 全部初始化为‘*’
    //定义一个初始化函数完成初始化
    initially(mine,ROWS,COLS,'0');
    initially(show,ROWS,COLS,'*');
    //打印棋盘
    //DisplayBoard(mine,ROW,COL);
    //DisplayBoard(show,ROW,COL);
    //布置雷,在9*9的棋盘上随机布置10个雷
    setmine(mine,ROW,COL);
    //DisplayBoard(mine,ROW,COL);
    DisplayBoard(show,ROW,COL);
    //排查雷
    Findmine(mine,show,ROW,COL);

}
void test()
{
    int n;
    srand((unsigned int)time(NULL));
    do
    {
        menu();
        printf("请选择->");
        scanf("%d",&n);
        switch(n)
        {
            case 1 :
                game();
                n=0;
                break;
            case 0 :
                printf("游戏结束,退出游戏\n");
                break;
            default :
                printf("选择错误,请重新选择\n");
                break;

        }
    } while (n);
}
int main()
{
    test();
    
    
    return 0;
}

原来的代码存在的问题是:
1、有重复的代码 代码冗余
2、有不必要的循环,在Findmine函数中,每次输入坐标后都会重新计算周围雷的数量,可以考虑在初始化时预先计算每个格子的雷数,减少运行时计算量。
3、在setmine函数中,随机生成雷的位置时,如果位置已经被占用,会重新生成随机数。(可以考虑使用洗牌算法(Fisher-Yates shuffle)来生成雷的位置,避免重复生成随机数)
4、在Findmine函数中缺少对输入坐标的验证,没有确保输入的坐标是有效的
以下是改进后的代码:

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
#define MINE_COUNT 10

void initially(char arr[ROWS][COLS], int rows, int cols, char ch);
void displayBoard(char a[ROWS][COLS], int row, int col);
void setMines(char a[ROWS][COLS], int row, int col);
int getMineCount(char mine[ROWS][COLS], int x, int y);
void findMines(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void menu();
void game();
void test();

void initially(char a[ROWS][COLS], int rows, int cols, char ch) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            a[i][j] = ch;
        }
    }
}

void displayBoard(char a[ROWS][COLS], int row, int col) {
    printf("-------扫雷游戏------\n");
    printf("--------start-------\n");
    for (int i = 0; i <= col; i++) {
        printf("%-2d", i);
    }
    printf("\n");
    for (int i = 1; i <= row; i++) {
        printf("%d", i);
        for (int j = 1; j <= col; j++) {
            printf("%2c", a[i][j]);
        }
        printf("\n");
    }
}

void setMines(char a[ROWS][COLS], int row, int col) {
    int count = MINE_COUNT;
    while (count) {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (a[x][y] == '0') {
            a[x][y] = '1';
            count--;
        }
    }
}

int getMineCount(char mine[ROWS][COLS], int x, int y) {
    int count = 0;
    for (int i = x - 1; i <= x + 1; i++) {
        for (int j = y - 1; j <= y + 1; j++) {
            if (mine[i][j] == '1') {
                count++;
            }
        }
    }
    return count;
}

void findMines(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
    int x, y;
    int win = 0;
    while (win < row * col - MINE_COUNT) {
        printf("请输入要排查的坐标 (x y): ");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col) {
            if (mine[x][y] == '1') {
                printf("很遗憾,你被我埋的雷炸死咯哈哈哈\n");
                printf("小趴菜,让你看看我的雷在哪\n");
                displayBoard(mine, ROW, COL);
                break;
            } else {
                int n = getMineCount(mine, x, y);
                show[x][y] = n + '0';
                displayBoard(show, ROW, COL);
                win++;
            }
        } else {
            printf("坐标非法请重新输入\n");
        }
    }
    if (win == row * col - MINE_COUNT) {
        printf("铁子实力有的呢,拆弹专家,排雷成功\n");
    }
}

void menu() {
    printf("********************\n");
    printf("******1、PLAY*******\n");
    printf("******0、exit*******\n");
    printf("********************\n");
}

void game() {
    char mine[ROWS][COLS] = {0};
    char show[ROWS][COLS] = {0};
    initially(mine, ROWS, COLS, '0');
    initially(show, ROWS, COLS, '*');
    setMines(mine, ROW, COL);
    displayBoard(show, ROW, COL);
    findMines(mine, show, ROW, COL);
}

void test() {
    int n;
    srand((unsigned int)time(NULL));
    do {
        menu();
        printf("请选择->");
        scanf("%d", &n);
        switch (n) {
            case 1:
                game();
                break;
            case 0:
                printf("游戏结束,退出游戏\n");
                break;
            default:
                printf("选择错误,请重新选择\n");
                break;
        }
    } while (n != 0);
}

int main() {
    test();
    return 0;
}
改进后的代码明显更加简洁 清晰。 以下图片是运行实例:

posted @ 2025-02-27 19:08  peng1257  阅读(16)  评论(0)    收藏  举报