Проблемы с тестовыми примерами локально в C - PullRequest
1 голос
/ 05 мая 2020

привет, моя задача написать тест, который проверяет, отличается ли доска Minesweeper (после выбора опции воспроизведения) от предыдущей.

прежде всего я написал основную функцию the replay.

после этого я протестировал его локально, работает ли он, и в каждой игре каждая доска была разной. не было никаких проблем. поэтому я начал писать тестовые примеры, и теперь я здесь.

TEST replay_board() {
    Game *game = create_game();
    Board *board = create_board(9, 9, 9);
    game->board = board;
    int k = 0;
    printf("\n");
    char mine_list[100];
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (game->board->tiles[i][j]->is_mine == true) {
                mine_list[k] = '1';
                printf("1");
            } else {
                mine_list[k] = '0';
                printf("0");
            }

            k++;
        }
    }
    printf("\n");
    mine_list[k] = '\0';

    replay_game(replay, game);

    char mine_list2[100];
    k = 0;

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (game->board->tiles[i][j]->is_mine == true) {
                mine_list2[k] = '1';
                printf("1");
            } else {
                mine_list2[k] = '0';
                printf("0");
            }
            k++;
        }
    }
    printf("\n");
    mine_list2[k] = '\0';
    int same = 0;

    if (strcmp(mine_list, mine_list2) != 0) {
        same = 0;
    } else {
        same = 1;
    }
    ASSERT_EQ(same, 0);
    PASS();
    destroy_game(game);
}

в каждом тесте он пишет, что старый кабан такой же, как и предыдущий, но локально я вижу, что они не такие .

Я не знаю, как лучше сравнивать две строки, но это был самый простой способ сравнить их по структуре

функция воспроизведения

void replay_game(char* replay, Game* game) {
    while (strcmp(replay, "yes") != 0 && strcmp(replay, "no") != 0 ) {
        scanf("%s", replay);
        if (strcmp(replay, "yes") != 0 || strcmp(replay, "no") != 0) {
            printf("invalid value\n");
        }
    }
    if (strcmp(replay, "yes") == 0) {
        destroy_board(game->board);
        game->game_state = PLAYING;
        game->board = create_board(9, 9, 9);
        game->player->score = 0;
    }
}

функция create_board

int generate_random_coordinates(int upper_range) {
    return rand() % upper_range;
}

/**
 * Generates random coordinates to row and column according to mine count value
 * Randomly sets mines to the Board pointer
 */
void set_mines_randomly(Board *board) {
    assert(board != NULL);

    int board_mine_count = 0;
    srand(time(NULL));
    while (board_mine_count != board->mine_count) {
        int random_row = generate_random_coordinates(board->row_count);
        int random_column = generate_random_coordinates(board->column_count);

        if (board->tiles[random_row][random_column]->is_mine == false) {

            board->tiles[random_row][random_column]->is_mine = true;
            board_mine_count++;
        }
    }
}

Board *create_board(int row_count, int column_count, int mine_count) {
    Board *board = (Board *) calloc(1, sizeof(Board));
    board->row_count = row_count;
    board->column_count = column_count;
    board->mine_count = mine_count;

    for (int row = 0; row < board->row_count; row++) {
        for (int column = 0; column < board->column_count; column++) {
            board->tiles[row][column] = (Tile *) calloc(1, sizeof(Tile));
            board->tiles[row][column]->tile_state = CLOSED;
            board->tiles[row][column]->is_mine = false;
        }
    }
    set_mines_randomly(board);
    set_tile_values(board);
    return board;
}

основной

#include <stdlib.h>
#include <string.h>
#include "game.h"
#include "user_interface.h"
#include "board.h"

int main() {
    char replay[] = "yes";
    Game *game = create_game();
    Board *board = create_board(9, 9, 9);
    game->board = board;
    read_player_name(game);

    // impleting the replay function
    while(strcmp(replay, "yes") == 0) {
        play_game(game);
        printf("Chcel by si znova zahrat? (yes/no)\n");
        scanf("%3s", replay);
        printf("\n");



        // new part
        char mine_list[100];
        int k = 0;

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (game->board->tiles[i][j]->is_mine == true) {
                    mine_list[k] = '1';
                    //printf("1");
                } else {
                    mine_list[k] = '0';
                    //printf("0");
                }
                k++;
            }
        }
        mine_list[k] = '\0';

        replay_game(replay, game);

        char mine_list2[100];
        k = 0;

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (game->board->tiles[i][j]->is_mine == true) {
                    mine_list2[k] = '1';
                    //printf("1");
                } else {
                    mine_list2[k] = '0';
                    //printf("0");
                }
                k++;
            }
        }
        mine_list2[k] = '\0';        
        printf("%s\n", mine_list);
        printf("%s\n", mine_list2);

        // new part ending heree

    }
    destroy_game(game);
    exit(EXIT_SUCCESS);
}

запуск основного после проигрыша вывод

   1 2 3 4 5 6 7 8 9 
1  1 1 0 0 0 0 0 0 0 
2  X 1 0 1 1 1 0 0 0 
3  - 1 0 1 X 1 0 0 0 
4  - 1 1 1 1 1 1 1 1 
5  - X 1 0 0 0 1 X - 
6  - - 2 1 1 1 2 - - 
7  - - X - - X - - - 
8  - X - - X - - - - 
9  - - - - - - X - - 

Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 13
Chcel by si znova zahrat? (yes/no)
yes 

после воспроизведения в течение 2 минут

   1 2 3 4 5 6 7 8 9 
1  0 0 0 0 0 1 - 1 0 
2  0 0 0 0 1 3 X 2 0 
3  0 0 0 0 1 X X 3 1 
4  1 1 0 0 1 2 2 2 X 
5  X 1 0 0 0 0 0 1 - 
6  - 2 1 2 2 3 2 1 - 
7  - - X - X X X - - 
8  - - - - - - - 1 - 
9  - - - - - - - - - 

Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 19
Chcel by si znova zahrat? (yes/no)

НЕ ПРОШЛО результат теста:

* Suite test_board:
......
000000000000001100000010001000100000000000001000100000100010000000000000000000000
000000000000001100000010001000100000000000001000100000100010000000000000000000000
F
FAIL replay_board: same != 0 (tests/test_board.c:125)

game.h

typedef enum  {
    FAILED,
    PLAYING,
    SOLVED,
} GameState;

typedef struct {
    Board *board;          /* Struct of the play field */
    Player *player;        /* Struct of user who is playing the Game */
    GameState game_state;  /* Enum for status of the Game */
} Game;

* create_game () *

Game *create_game() {
    Game *game = (Game *) calloc(1, sizeof(Game));
    Player *player = (Player *) calloc(1, sizeof(Player));
    game->player = player;
    game->player->score = 1;
    game->game_state = PLAYING;
    return game;
}

новый вывод после обновления основного с помощью printf

   1 2 3 4 5 6 7 8 9 
1  - 1 0 0 0 0 0 0 0 
2  X 1 0 0 0 0 1 1 1 
3  - 1 0 0 0 0 1 X - 
4  - 1 1 0 0 1 2 - - 
5  - X 2 1 1 1 X - X 
6  1 1 2 X 1 1 2 X X 
7  0 0 1 1 1 0 1 3 X 
8  0 0 0 0 0 0 0 1 1 
9  0 0 0 0 0 0 0 0 0 

Ľutujem asd. Riešenie je nesprávne!
Vaše skóre je: 17
Chcel by si znova zahrat? (yes/no)
yes

000000000100000000000000010000000000010000101000100011000000001000000000000000000
000000001100000000000000000000100011000000000000000010010000000000001000000010000

   1 2 3 4 5 6 7 8 9 
1  - - - - - - - - - 
2  - - - - - - - - - 
3  - - - - - - - - - 
4  - - - - - - - - - 
5  - - - - - - - - - 
6  - - - - - - - - - 
7  - - - - - - - - - 
8  - - - - - - - - - 
9  - - - - - - - - - 



Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Вы проверили, что replay_game("yes", game); действительно меняет игру?

В любом случае, есть гораздо более простой и правильный способ сделать это. Выделите новый указатель платы *, скопируйте содержимое платы в новую выделенную память, используя memcpy, а затем вызовите replay_game. Предполагая, что это действительно изменяет переменную board, теперь вы можете просто сравнить две платы внутри одного вложенного l oop.

0 голосов
/ 05 мая 2020

Вот проблема:

char* mine_list[100];

Вы определили mine_list как массив char * вместо массива char. Ваш компилятор должен был выдавать вам несколько предупреждений, где бы вы его ни использовали. Измените его на массив char:

char mine_list[100];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...