有人可以帮我扫雷吗?

时间:2018-06-02 07:27:04

标签: c

我目前开始学习C语言。 作为我的家庭作业,我试图在C中制作一个控制台版的扫雷。 但是,它在某种程度上不起作用,我不知道为什么。 问题是,我不允许修改其中的一些功能和变量。他们是

(init_board,display_board,show_interface) 这些是我不允许修改的。

对于10 * 10扫雷, 我的第一个想法是制作一个12 * 12的电路板,并在第一次用户输入之前计算我需要的所有功能。

当用户扫描采矿方块时,程序终止并且它正是我想要的,所以它工作正常。但是,当用户扫描未定义的方形时,函数reveal()似乎无法正常工作。

这是我有缺陷的代码......有人可以帮助我吗?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma warning(disable: 4996)

#define BOARD_SIZE              10
#define SQUARE_NUM              (BOARD_SIZE*BOARD_SIZE)
#define MINE_NUM                17
#define SHUFFLE_NUM             100000

int left_square;
int mines; // only for debugging

int end; // only 1 when player lose

int mine_board[BOARD_SIZE][BOARD_SIZE];
/* 0 : non-mined, 1 : mined */

int display_board[BOARD_SIZE][BOARD_SIZE];
/* -1 : no mines around, 0 : unknown, 1~8 : number of mines */

int board_revealed[BOARD_SIZE + 2][BOARD_SIZE + 2];
int calculate_board[BOARD_SIZE + 2][BOARD_SIZE + 2][2];
// 0 : non-mined, 1 : mined
// layer 0 : current mine state
// layer 1 : how many mines are nearby

void board_oracle();
void store_board(); // store mine_board to calculate_board
void init_board(); // initialize mine_board by randomly planting fixed number of mines
void show_interface(); // print display_board
void reveal(int x, int y);

int sweep(int x, int y);
/*
* return : 1 if player sweeps mined square, else 0
*/

int check_game();
/*
* check if the player swept all non-mined squares
* return : 1 if player swept all non-mined squares, else 0
*/

int main(void) //Todo
{
    init_board();
    show_interface();
    store_board();
    printf("%d unmined square remaining, %d mines here\n", left_square, mines); // debugging
    while (check_game() == 0)
    {
        int x, y;
        printf("input coordinate : ");
        scanf("%d %d", &x, &y);
        if (sweep(x, y) == 0)
        {
            reveal(x, y);
        }
        else
        {
            display_board[x - 1][y - 1] = -1;
            end = 1;
            show_interface();
            printf("player lost");
            return 0;
        }
        show_interface();
    }

}


void init_board()
{
    int i;
    int shuffle[BOARD_SIZE * BOARD_SIZE];
    int temp;
    int r1, r2;

    srand(time(NULL)); // set seed

                       // initialize shuffle array
    for (i = 0; i<SQUARE_NUM; i++)
        shuffle[i] = i;

    // shuffling
    for (i = 0; i<SHUFFLE_NUM; i++)
    {
        r1 = rand() % SQUARE_NUM;
        r2 = rand() % SQUARE_NUM;

        temp = shuffle[r1];
        shuffle[r1] = shuffle[r2];
        shuffle[r2] = temp;
    }

    // get mine coordinates from shuffled array
    for (i = 0; i<MINE_NUM; i++)
        mine_board[shuffle[i] / BOARD_SIZE][shuffle[i] % BOARD_SIZE] = 1;
}
//given

void show_interface()
{
    int i, j;

    system("cls"); // clear the screen

                     // rest of this function just prints out display_board
    printf("    ");
    for (i = 0; i<BOARD_SIZE; i++)
        printf(" %2d ", i + 1);
    for (i = 0; i<BOARD_SIZE; i++)
    {
        printf("\n %2d ", i + 1);

        for (j = 0; j<BOARD_SIZE; j++)
        {
            if (display_board[i][j] == -1)
            {
                if (mine_board[i][j] == 1)
                    printf("  * ");
                else
                    printf("  X ");
            }
            else if (display_board[i][j] == 0)
                printf("  - ");
            else
                printf("  %d ", display_board[i][j]);
        }
        printf("\n");
    }
    printf("\n  |\n  v\n\n  Y\n\n");
}
//given

int sweep(int x, int y) // TODo
{
    if (calculate_board[x][y][0] == 0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
//done

int check_game()
{
    if (end == 1)
    {
        return 1;
    }
    else if (left_square == 0)
    {
        printf("You win");
        return 2; // indicates win
    }
    else
    {
        return 0;
    }

}

void store_board()
{
    for (int i = 0; i < 100; i++)
    {
        int x = i / 10; 
        int y = i % 10;
        calculate_board[x + 1][y + 1][0] = mine_board[x][y];
        if (calculate_board[x + 1][y + 1][0] == 0)
        {
            left_square++;
        }
        else
        {
            mines++;
        }
    }
}
// properly working.

void board_oracle()
{
    int i = 1, j = 1;
    for (; i < 11; i++)
    {
        for (; j < 11; j++)
        {
            calculate_board[i][j][1] = calculate_board[i - 1][j - 1][0] + calculate_board[i][j - 1][0] + calculate_board[i - 1][j][0] + calculate_board[i][j + 1][0] + calculate_board[i - 1][j + 1][0] + calculate_board[i + 1][j - 1][0] + calculate_board[i + 1][j][0] + calculate_board[i + 1][j + 1][0];
        }
    }
}

void reveal(int x, int y)
{
    if (x >= 1 && y >= 1 && x<= 11 && y <= 11)
    {
        if (board_revealed[x][y] == 1)
        {
            return;
        }
        else
        {
            if (calculate_board[x][y][1] == 0)
            {
                reveal(x - 1, y - 1);
                reveal(x - 1, y);
                reveal(x - 1, y + 1);
                reveal(x, y - 1);
                reveal(x, y + 1);
                reveal(x + 1, y - 1); 
                reveal(x + 1, y);
                reveal(x + 1, y + 1);
            }
            else
            {
                display_board[x - 1][y - 1] = calculate_board[x][y][1];
                board_revealed[x][y] = 1;
            }
        }
    }
    else
    {
        return;
    }
}

正如一些评论所说,准确地陈述问题 当我运行程序并输入像2 3这样的输入时,程序就崩溃并说 &#34;分段错误(核心转储)&#34; 当它被开采方形时,错误不会发生(它打印&#34;玩家丢失&#34;并完成) 只有在扫描非开采方块时才会出现错误。

正如一些人所说,我添加了一行以确保reveal()停在边缘......但它不会让它变得更好......

1 个答案:

答案 0 :(得分:1)

问题1:

test.c: In function 'reveal':
test.c:221:41: warning: statement with no effect [-Wunused-value]
         display_board[x - 1][y - 1] == calculate_board[x][y][1];
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~

这应该是=。但更重要的是,您应该启用编译器警告,例如在带有-Wall的gcc上。

问题2:

当我选择2 2时,函数reveal会被坐标调用: 2 2 1 1 0 0 -1 -1 -1 0 -2 -1 -3 -2 -4 -3。所以不管你是否让网格变得更大,它最终都会崩溃。在你调用reveal 8次的时候,首先要检查坐标是否有效,即&gt; = 0和&lt; ñ。那么也许你也不需要让网格更大。