Browse Source
Merge branch 'David' into 'main'
Merge branch 'David' into 'main'
David See merge request pmuw_projekt/pmuw_projekt_notebinder!30remotes/origin/fdai7775-main-patch-54732
fdai8032
11 months ago
8 changed files with 438 additions and 26 deletions
-
255src/main/c/Minesweeper/minesweeper_start.c
-
20src/main/c/Minesweeper/minesweeper_start.h
-
28src/main/c/Snake/snake_start.c
-
8src/main/c/Snake/snake_start.h
-
12src/main/c/main.c
-
40test/Minesweeper/test_bomb_in_array.c
-
97test/Minesweeper/test_number_of_bombs.c
-
4test/Snake/test_collision.c
@ -0,0 +1,255 @@ |
|||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <stdbool.h> |
||||
|
#include <time.h> |
||||
|
#include "minesweeper_start.h" |
||||
|
#pragma region defines |
||||
|
#define BLOCK '#' |
||||
|
#define FLAG 'x' |
||||
|
#define EMPTY ' ' |
||||
|
#define SMALL 10 |
||||
|
#define MIDDLE 15 |
||||
|
#define LARGE 20 |
||||
|
#define EASY 7 |
||||
|
#define NORMAL 5 |
||||
|
#define HARD 3 |
||||
|
#pragma endregion |
||||
|
|
||||
|
|
||||
|
#pragma region Funktion_heads |
||||
|
void main_menu_minesweeper(); |
||||
|
void game_minesweeper(); |
||||
|
void options_minesweeper(); |
||||
|
Minesweeper_Board initialize_minesweeper(); |
||||
|
void place_bombs(Minesweeper_Board *board); |
||||
|
bool array_contains_value(int *array, int value, int length); |
||||
|
void draw_minesweeper(Minesweeper_Board *board); |
||||
|
int open_tile(Minesweeper_Board *board, int tile); |
||||
|
int number_of_bombs(Minesweeper_Board *board, int tile); |
||||
|
void open_empty_space(Minesweeper_Board *board, int tile, int index); |
||||
|
#pragma endregion |
||||
|
|
||||
|
#pragma region Global |
||||
|
unsigned int width = MIDDLE; |
||||
|
unsigned int height = MIDDLE; |
||||
|
int num_bombs = MIDDLE * MIDDLE / NORMAL; |
||||
|
#pragma endregion //Global |
||||
|
|
||||
|
|
||||
|
void minesweeper_start(){ |
||||
|
system("clear"); |
||||
|
main_menu_minesweeper(); |
||||
|
} |
||||
|
|
||||
|
void main_menu_minesweeper(){ |
||||
|
bool running = true; |
||||
|
while (running){ |
||||
|
int option = 0; |
||||
|
|
||||
|
system("clear"); |
||||
|
printf("Waehlen Sie eine Option:\n"); |
||||
|
printf("\t1.Start\n"); |
||||
|
printf("\t2.Options\n"); |
||||
|
printf("\t3.Exit\n"); |
||||
|
|
||||
|
scanf("%d", &option); |
||||
|
getchar(); |
||||
|
|
||||
|
system("clear"); |
||||
|
|
||||
|
switch (option){ |
||||
|
case 1: |
||||
|
game_minesweeper(); |
||||
|
break; |
||||
|
case 2: |
||||
|
options_minesweeper(); |
||||
|
break; |
||||
|
case 3: |
||||
|
running = false; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void game_minesweeper(){ |
||||
|
bool running = true; |
||||
|
int x, y, t; |
||||
|
Minesweeper_Board board = initialize_minesweeper(); |
||||
|
|
||||
|
place_bombs(&board); |
||||
|
|
||||
|
while (running){ |
||||
|
system("clear"); |
||||
|
draw_minesweeper(&board); |
||||
|
|
||||
|
printf("Next turn (x, y, t(0 = open, 1 = flag)): "); |
||||
|
scanf("%d %d %d", &x, &y, &t); |
||||
|
getchar(); |
||||
|
if(x < board.width && x > -1 && y < board.height && y > -1){ |
||||
|
x = x + y * board.width; |
||||
|
if(t == 0){ |
||||
|
int bombs = open_tile(&board, x); |
||||
|
if(bombs == -1){running = false;} |
||||
|
else if(bombs == 0){open_empty_space(&board, x, 0);} |
||||
|
else{board.tiles[x] = bombs + 48;} |
||||
|
} |
||||
|
if(t == 1){board.tiles[x] = board.tiles[x] == FLAG ? BLOCK : board.tiles[x] == BLOCK ? FLAG : board.tiles[x];} |
||||
|
} |
||||
|
if (t == 2){break;} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void options_minesweeper(){ |
||||
|
bool running = true; |
||||
|
while (running){ |
||||
|
int option = 0; |
||||
|
|
||||
|
system("clear"); |
||||
|
printf("Waehlen Sie eine Option:\n"); |
||||
|
printf("\t1.Schwierigkeit\t\t%s\n", num_bombs < 2 * width * height / (NORMAL + EASY) ? "Einfach" : num_bombs < 2 * width * height / (NORMAL + HARD) ? "Normal" : "Schwer"); |
||||
|
printf("\t2.Groesse\t\t%s\n", width * height < MIDDLE * SMALL ? "Klein" : width * height < MIDDLE * LARGE ? "Mittel" : "Gross"); |
||||
|
printf("\t3.Custom\n"); |
||||
|
printf("\t4.Exit\n"); |
||||
|
|
||||
|
scanf("%d", &option); |
||||
|
getchar(); |
||||
|
|
||||
|
switch (option){ |
||||
|
case 1: |
||||
|
printf("Bitte neu Schwierigkeit eingeben (1 - 3): "); |
||||
|
scanf("%d", &num_bombs); |
||||
|
getchar(); |
||||
|
num_bombs = num_bombs == 1 ? EASY : num_bombs == 2 ? NORMAL : HARD; |
||||
|
num_bombs = width * height / num_bombs; |
||||
|
break; |
||||
|
case 2: |
||||
|
num_bombs = num_bombs < width * height / NORMAL ? EASY : num_bombs == width * height / NORMAL ? NORMAL : HARD; |
||||
|
printf("Bitte neu Groesse eingeben (1 - 3): "); |
||||
|
scanf("%d", &width); |
||||
|
getchar(); |
||||
|
width = width == 1 ? SMALL : width == 2 ? MIDDLE : LARGE; |
||||
|
height = width; |
||||
|
num_bombs = width * height / num_bombs; |
||||
|
break; |
||||
|
case 3: |
||||
|
printf("Bitte Breite des Spielfeld eingeben: "); |
||||
|
scanf("%d", &width); |
||||
|
getchar(); |
||||
|
printf("Bitte Hoehe des Spielfeld eingeben: "); |
||||
|
scanf("%d", &height); |
||||
|
getchar(); |
||||
|
printf("Bitte Anzahl der Bomben eingeben: "); |
||||
|
scanf("%d", &num_bombs); |
||||
|
getchar(); |
||||
|
break; |
||||
|
case 4: |
||||
|
running = false; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Minesweeper_Board initialize_minesweeper(){ |
||||
|
Minesweeper_Board board; |
||||
|
board.width = width; |
||||
|
board.height = height; |
||||
|
board.tiles = (int*) malloc(width * height * sizeof(int)); |
||||
|
for(int i = 0; i < width * height; i++){board.tiles[i] = BLOCK;} |
||||
|
board.marked = (int*) malloc(width * height * sizeof(int)); |
||||
|
for(int i = 0; i < width * height; i++){board.marked[i] = 0;} |
||||
|
board.num_bombs = num_bombs; |
||||
|
board.bombs = (int*) malloc(board.num_bombs * sizeof(int)); |
||||
|
for(int i = 0; i < num_bombs; i++){board.bombs[i] = -1;} |
||||
|
return board; |
||||
|
} |
||||
|
|
||||
|
void place_bombs(Minesweeper_Board *board){ |
||||
|
srand(time(NULL)); |
||||
|
int r; |
||||
|
for(int i = 0; i < board->num_bombs; i++){ |
||||
|
while (1){ |
||||
|
r = rand() % (board->width * board->height); |
||||
|
if(!array_contains_value(board->bombs, r, board->num_bombs)){break;} |
||||
|
} |
||||
|
board->bombs[i] = r; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool array_contains_value(int *array, int value, int length){ |
||||
|
for(int i = 0; i < length; i++){ |
||||
|
if(array[i] == value){return true;} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
void draw_minesweeper(Minesweeper_Board *board){ |
||||
|
printf(" "); |
||||
|
for(int i = 0; i < board->width; i++){printf("%d", i / 10);} |
||||
|
printf("\n "); |
||||
|
for(int i = 0; i < board->width; i++){printf("%d", i % 10);} |
||||
|
printf("\n +"); |
||||
|
for(int i = 0; i < board->width; i++){printf("-");} |
||||
|
printf("+\n"); |
||||
|
for(int i = 0; i < board->height; i++){ |
||||
|
printf("%d", i / 10); |
||||
|
printf("%d|", i % 10); |
||||
|
for(int j = 0; j < board->width; j++){printf("%c", board->tiles[i * width + j]);} |
||||
|
printf("|%d", i / 10); |
||||
|
printf("%d\n", i % 10); |
||||
|
} |
||||
|
printf(" +"); |
||||
|
for(int i = 0; i < board->width; i++){printf("-");} |
||||
|
printf("+\n "); |
||||
|
for(int i = 0; i < board->width; i++){printf("%d", i / 10);} |
||||
|
printf("\n "); |
||||
|
for(int i = 0; i < board->width; i++){printf("%d", i % 10);} |
||||
|
printf("\n"); |
||||
|
} |
||||
|
|
||||
|
int open_tile(Minesweeper_Board *board, int tile){ |
||||
|
if(array_contains_value(board->bombs, tile, board->num_bombs)){return -1;} |
||||
|
int num = number_of_bombs(board, tile); |
||||
|
if(1){return num;} |
||||
|
} |
||||
|
|
||||
|
int number_of_bombs(Minesweeper_Board *board, int tile){ |
||||
|
int sum = 0; |
||||
|
for(int i = 0; i < 8; i++){ |
||||
|
int check_tile = tile; |
||||
|
if(i < 3){if(tile % board->width == 0){continue;} |
||||
|
else{check_tile -= 1;}} |
||||
|
if(i > 4){if(tile % board->width + 1 == board->width){continue;} |
||||
|
else{check_tile += 1;}} |
||||
|
if(i % 3 == 0){if(i != 0 && tile / board->width == 0){continue;} |
||||
|
else{check_tile -= board->width;}} |
||||
|
if(i % 3 == 1){if(tile / board->width + 1 == height){continue;} |
||||
|
else{check_tile += board->width;}} |
||||
|
if(array_contains_value(board->bombs, check_tile, board->num_bombs)){sum++;} |
||||
|
} |
||||
|
return sum; |
||||
|
} |
||||
|
|
||||
|
void open_empty_space(Minesweeper_Board *board, int tile, int index){ |
||||
|
board->tiles[tile] = EMPTY; |
||||
|
board->marked[index++] = tile; |
||||
|
for(int i = 0; i < 8; i++){ |
||||
|
int check_tile = tile; |
||||
|
if(i < 3){if(tile % board->width == 0){continue;} |
||||
|
else{check_tile -= 1;}} |
||||
|
if(i > 4){if(tile % board->width + 1 == board->width){continue;} |
||||
|
else{check_tile += 1;}} |
||||
|
if(i % 3 == 0){if(i != 0 && tile / board->width == 0){continue;} |
||||
|
else{check_tile -= board->width;}} |
||||
|
if(i % 3 == 1){if(tile / board->width + 1 == height){continue;} |
||||
|
else{check_tile += board->width;}} |
||||
|
int sum = open_tile(board, check_tile); |
||||
|
if(sum != 0){board->tiles[check_tile] = sum + 48;} |
||||
|
else if(!array_contains_value(board->marked, check_tile, index)){open_empty_space(board, check_tile, index);} |
||||
|
} |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
#ifndef MINESWEEPER_START_H |
||||
|
#define MINESWEEPER_START_H |
||||
|
|
||||
|
typedef struct Minesweeper_Board{ |
||||
|
unsigned int width; |
||||
|
unsigned int height; |
||||
|
int *tiles; |
||||
|
int *marked; |
||||
|
int num_bombs; |
||||
|
int *bombs; |
||||
|
}Minesweeper_Board; |
||||
|
|
||||
|
|
||||
|
void minesweeper_start(); |
||||
|
Minesweeper_Board initialize_minesweeper(); |
||||
|
bool array_contains_value(int *array, int bomb, int length); |
||||
|
int number_of_bombs(Minesweeper_Board *board, int tile); |
||||
|
|
||||
|
|
||||
|
#endif // MINESWEEPER_START_H |
@ -0,0 +1,40 @@ |
|||||
|
#ifdef TEST |
||||
|
#include "unity.h" |
||||
|
#include <stdbool.h> |
||||
|
#include "../../src/main/c/Minesweeper/minesweeper_start.h" |
||||
|
|
||||
|
|
||||
|
void setUp(void){} |
||||
|
void tearDown(void){} |
||||
|
|
||||
|
|
||||
|
void test_bomb_in_array(void){ |
||||
|
/* arrange */ |
||||
|
bool result; |
||||
|
int array[] = {5, 9, 42, 6, 87, 95, 202, 13, 45 ,78}; |
||||
|
int bomb = 42; |
||||
|
int length = 10; |
||||
|
|
||||
|
/* act */ |
||||
|
result = array_contains_value(array, bomb, length); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_TRUE(result); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void test_bomb_not_in_array(void){ |
||||
|
/* arrange */ |
||||
|
bool result; |
||||
|
int array[] = {5, 9, 42, 6, 87, 95, 202, 13, 45 ,78}; |
||||
|
int bomb = 0; |
||||
|
int length = 10; |
||||
|
|
||||
|
/* act */ |
||||
|
result = array_contains_value(array, bomb, length); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_FALSE(result); |
||||
|
} |
||||
|
|
||||
|
#endif // TEST |
@ -0,0 +1,97 @@ |
|||||
|
#ifdef TEST |
||||
|
#include "unity.h" |
||||
|
#include <stdbool.h> |
||||
|
#include "../../src/main/c/Minesweeper/minesweeper_start.h" |
||||
|
|
||||
|
|
||||
|
void setUp(void){} |
||||
|
void tearDown(void){} |
||||
|
|
||||
|
|
||||
|
void test_no_bombs_placed_around_tile(void){ |
||||
|
/* arrange */ |
||||
|
int result; |
||||
|
Minesweeper_Board board = initialize_minesweeper(); |
||||
|
int tile = 0 + board.width * 1; |
||||
|
|
||||
|
/* act */ |
||||
|
result = number_of_bombs(&board, tile); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_EQUAL_INT(0, result);//no bombs placed |
||||
|
} |
||||
|
|
||||
|
void test_searching_for_bombs_on_correct_tiles(void){ |
||||
|
/* arrange */ |
||||
|
int result; |
||||
|
Minesweeper_Board board = initialize_minesweeper(); |
||||
|
int tile = 0 + board.width * 1; |
||||
|
board.bombs[0] = 0 + board.width * 3; |
||||
|
board.bombs[1] = 2 + board.width * 1; |
||||
|
board.bombs[2] = board.width - 1 + board.width * 1; |
||||
|
board.bombs[3] = 0 + board.width * (board.height - 1); |
||||
|
|
||||
|
/* act */ |
||||
|
result = number_of_bombs(&board, tile); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_EQUAL_INT(0, result);//no bombs placed around tile |
||||
|
} |
||||
|
|
||||
|
void test_2_bombs_around_tile(void){ |
||||
|
/* arrange */ |
||||
|
int result; |
||||
|
Minesweeper_Board board = initialize_minesweeper(); |
||||
|
int tile = 0 + board.width * 1; |
||||
|
board.bombs[0] = 0 + board.width * 2; |
||||
|
board.bombs[1] = 1 + board.width * 1; |
||||
|
board.bombs[2] = board.width - 1 + board.width * 1; |
||||
|
board.bombs[3] = 0 + board.width * (board.height - 1); |
||||
|
|
||||
|
/* act */ |
||||
|
result = number_of_bombs(&board, tile); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_EQUAL_INT(2, result);//2 bombs placed around tile |
||||
|
} |
||||
|
|
||||
|
void test_5_bombs_around_tile(void){ |
||||
|
/* arrange */ |
||||
|
int result; |
||||
|
Minesweeper_Board board = initialize_minesweeper(); |
||||
|
int tile = 1 + board.width * 0; |
||||
|
board.bombs[0] = 0 + board.width * 0; |
||||
|
board.bombs[1] = 2 + board.width * 0; |
||||
|
board.bombs[2] = 0 + board.width * 1; |
||||
|
board.bombs[3] = 1 + board.width * 1; |
||||
|
board.bombs[4] = 2 + board.width * 1; |
||||
|
|
||||
|
/* act */ |
||||
|
result = number_of_bombs(&board, tile); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_EQUAL_INT(5, result);//5 bombs placed around tile |
||||
|
} |
||||
|
|
||||
|
void test_8_bombs_around_tile(void){ |
||||
|
/* arrange */ |
||||
|
int result; |
||||
|
Minesweeper_Board board = initialize_minesweeper(); |
||||
|
int tile = 7 + board.width * 7; |
||||
|
board.bombs[0] = 6 + board.width * 6; |
||||
|
board.bombs[1] = 7 + board.width * 6; |
||||
|
board.bombs[2] = 8 + board.width * 6; |
||||
|
board.bombs[3] = 6 + board.width * 7; |
||||
|
board.bombs[4] = 8 + board.width * 7; |
||||
|
board.bombs[5] = 6 + board.width * 8; |
||||
|
board.bombs[6] = 7 + board.width * 8; |
||||
|
board.bombs[7] = 8 + board.width * 8; |
||||
|
|
||||
|
/* act */ |
||||
|
result = number_of_bombs(&board, tile); |
||||
|
|
||||
|
/* assert */ |
||||
|
TEST_ASSERT_EQUAL_INT(8, result);//2 bombs placed around tile |
||||
|
} |
||||
|
|
||||
|
#endif // TEST |
Write
Preview
Loading…
Cancel
Save
Reference in new issue