Skip to content
Snippets Groups Projects
Commit 3d21c07e authored by Florian Burgener's avatar Florian Burgener
Browse files

Refactoring + memory leak

parent 9631bc1a
No related branches found
No related tags found
No related merge requests found
#include "Connect4.h" #include "Connect4.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -52,9 +53,10 @@ void print_grid_separator(int32_t n, char *front, char *rear, char *separator1, ...@@ -52,9 +53,10 @@ void print_grid_separator(int32_t n, char *front, char *rear, char *separator1,
for (int32_t i = 0; i < n; i += 1) { for (int32_t i = 0; i < n; i += 1) {
printf("%s", separator1); printf("%s", separator1);
if (i < n - 1) if (i < n - 1) {
printf("%s", separator2); printf("%s", separator2);
} }
}
printf("%s", rear); printf("%s", rear);
printf("\n"); printf("\n");
...@@ -73,9 +75,10 @@ void print_grid_body(Piece **grid, int32_t rows, int32_t cols, int32_t y) { ...@@ -73,9 +75,10 @@ void print_grid_body(Piece **grid, int32_t rows, int32_t cols, int32_t y) {
printf("│"); printf("│");
printf("\n"); printf("\n");
if (y < rows - 1) if (y < rows - 1) {
print_grid_separator(cols, "├", "┤", "─", "┼"); print_grid_separator(cols, "├", "┤", "─", "┼");
} }
}
void print_grid(Piece **grid, int32_t rows, int32_t cols) { void print_grid(Piece **grid, int32_t rows, int32_t cols) {
print_grid_separator(cols, "┌", "┐", "─", "┬"); print_grid_separator(cols, "┌", "┐", "─", "┬");
...@@ -100,17 +103,20 @@ void connect4_print(Connect4 *connect4) { ...@@ -100,17 +103,20 @@ void connect4_print(Connect4 *connect4) {
bool connect4_is_full(Connect4 *connect4) { bool connect4_is_full(Connect4 *connect4) {
for (int32_t y = 0; y < connect4->rows; y += 1) { for (int32_t y = 0; y < connect4->rows; y += 1) {
for (int32_t x = 0; x < connect4->cols; x += 1) { for (int32_t x = 0; x < connect4->cols; x += 1) {
if (connect4->grid[y][x] == PieceNone) if (connect4->grid[y][x] == PieceNone) {
return false; return false;
} }
} }
}
return true; return true;
} }
int32_t count_contiguous_pieces(Connect4 *connect4, int32_t x, int32_t y, int32_t x_direction, int32_t y_direction, Piece piece) { int32_t count_contiguous_pieces(Connect4 *connect4, int32_t x, int32_t y, int32_t x_direction, int32_t y_direction, Piece piece) {
if (x < 0 || x >= connect4->cols || y < 0 || y >= connect4->rows || connect4->grid[y][x] != piece) if (x < 0 || x >= connect4->cols || y < 0 || y >= connect4->rows || connect4->grid[y][x] != piece) {
return 0; return 0;
}
return 1 + count_contiguous_pieces(connect4, x + x_direction, y + y_direction, x_direction, y_direction, piece); return 1 + count_contiguous_pieces(connect4, x + x_direction, y + y_direction, x_direction, y_direction, piece);
} }
...@@ -130,10 +136,14 @@ PlacingStatus connect4_place_piece(Connect4 *connect4, Piece piece, int32_t x) { ...@@ -130,10 +136,14 @@ PlacingStatus connect4_place_piece(Connect4 *connect4, Piece piece, int32_t x) {
if (connect4->grid[y][x] == PieceNone) { if (connect4->grid[y][x] == PieceNone) {
connect4->grid[y][x] = piece; connect4->grid[y][x] = piece;
if (connect4_check_win(connect4, x, y, piece)) if (connect4_check_win(connect4, x, y, piece)) {
return PlacingStatusPlayerWon; return PlacingStatusPlayerWon;
if (connect4_is_full(connect4)) }
if (connect4_is_full(connect4)) {
return PlacingStatusGridFull; return PlacingStatusGridFull;
}
return PlacingStatusPiecePlaced; return PlacingStatusPiecePlaced;
} }
} }
...@@ -142,8 +152,10 @@ PlacingStatus connect4_place_piece(Connect4 *connect4, Piece piece, int32_t x) { ...@@ -142,8 +152,10 @@ PlacingStatus connect4_place_piece(Connect4 *connect4, Piece piece, int32_t x) {
} }
Piece change_player(Piece current_player) { Piece change_player(Piece current_player) {
if (current_player == PiecePlayer1) if (current_player == PiecePlayer1) {
return PiecePlayer2; return PiecePlayer2;
}
return PiecePlayer1; return PiecePlayer1;
} }
...@@ -165,8 +177,11 @@ PlacingStatus connect4_play_smart(Connect4 *connect4, void (*on_piece_placed)(Co ...@@ -165,8 +177,11 @@ PlacingStatus connect4_play_smart(Connect4 *connect4, void (*on_piece_placed)(Co
Connect4 *copied_connect4 = connect4_copy(connect4); Connect4 *copied_connect4 = connect4_copy(connect4);
PlacingStatus status = connect4_place_piece(copied_connect4, current_player, x); PlacingStatus status = connect4_place_piece(copied_connect4, current_player, x);
if (status == PlacingStatusColumnFull) if (status == PlacingStatusColumnFull) {
connect4_destroy(copied_connect4);
continue; continue;
}
int32_t y = 0; int32_t y = 0;
for (int32_t i = 0; i < copied_connect4->rows; i += 1) { for (int32_t i = 0; i < copied_connect4->rows; i += 1) {
...@@ -191,22 +206,29 @@ PlacingStatus connect4_play_smart(Connect4 *connect4, void (*on_piece_placed)(Co ...@@ -191,22 +206,29 @@ PlacingStatus connect4_play_smart(Connect4 *connect4, void (*on_piece_placed)(Co
} }
PlacingStatus connect4_play(Connect4 *connect4, int32_t x, void (*on_piece_placed)(Connect4 *)) { PlacingStatus connect4_play(Connect4 *connect4, int32_t x, void (*on_piece_placed)(Connect4 *)) {
if (x < 1 || x > connect4->cols) if (x < 1 || x > connect4->cols) {
return PlacingStatusInvalidColumn; return PlacingStatusInvalidColumn;
}
PlacingStatus status = connect4_place_piece(connect4, connect4->current_player, x - 1); PlacingStatus status = connect4_place_piece(connect4, connect4->current_player, x - 1);
if (status != PlacingStatusInvalidColumn || status != PlacingStatusColumnFull) if (status != PlacingStatusInvalidColumn || status != PlacingStatusColumnFull) {
on_piece_placed(connect4); on_piece_placed(connect4);
if (status != PlacingStatusPiecePlaced) }
if (status != PlacingStatusPiecePlaced) {
return status; return status;
}
connect4->current_player = change_player(connect4->current_player); connect4->current_player = change_player(connect4->current_player);
if (connect4->mode != 3 && connect4->current_player == PiecePlayer2) { if (connect4->mode != 3 && connect4->current_player == PiecePlayer2) {
if (connect4->mode == 1) if (connect4->mode == 1) {
status = connect4_play_random(connect4, on_piece_placed); status = connect4_play_random(connect4, on_piece_placed);
if (connect4->mode == 2) } else if (connect4->mode == 2) {
status = connect4_play_smart(connect4, on_piece_placed); status = connect4_play_smart(connect4, on_piece_placed);
} }
}
return status; return status;
} }
CC = gcc CC = gcc
CCFLAGS = -g -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak CCFLAGS = -g -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak
Connect4.o: Connect4.c Connect4.o: Connect4.c Connect4.h
$(CC) $(CCFLAGS) -c $< -o $@ $(CC) $(CCFLAGS) -c $< -o $@
random.o: random.c random.o: random.c random.h
$(CC) $(CCFLAGS) -c $< -o $@ $(CC) $(CCFLAGS) -c $< -o $@
main.o: main.c main.o: main.c random.h
$(CC) $(CCFLAGS) -c $< -o $@ $(CC) $(CCFLAGS) -c $< -o $@
puissance4: main.o Connect4.o random.o puissance4: main.o Connect4.o random.o
......
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include "Connect4.h" #include "Connect4.h"
char *get_game_result(int32_t mode, Piece current_player, PlacingStatus status) { char *get_game_result(int32_t mode, Piece current_player, PlacingStatus status) {
if (status == PlacingStatusGridFull) if (status == PlacingStatusGridFull) {
return "It is a draw."; return "It is a draw.";
if (current_player == PiecePlayer1) }
if (current_player == PiecePlayer1) {
return "Player one won!"; return "Player one won!";
else if (current_player == PiecePlayer2 && mode == 3) }
if (current_player == PiecePlayer2 && mode == 3) {
return "Player two won!"; return "Player two won!";
}
return "Computer won!"; return "Computer won!";
} }
...@@ -24,18 +28,36 @@ void on_piece_placed(Connect4 *connect4) { ...@@ -24,18 +28,36 @@ void on_piece_placed(Connect4 *connect4) {
connect4_print(connect4); connect4_print(connect4);
} }
void print_help() {
printf("Usage: puissance4 <mode> <row> <col>\n");
printf(" mode specifies the mode: 1 = single player game (random),\n");
printf(" 2 = single player game (AI), 3 = two players game\n");
printf(" row specifies the number of rows (>= 4)\n");
printf(" col specifies the number of columns (>= 4)\n");
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
srand(0); srand(0);
if (argc != 4) {
print_help();
return EXIT_FAILURE;
}
int32_t mode = atoi(argv[1]); int32_t mode = atoi(argv[1]);
int32_t rows = atoi(argv[2]); int32_t rows = atoi(argv[2]);
int32_t cols = atoi(argv[3]); int32_t cols = atoi(argv[3]);
if (mode < 1 || mode > 3 || rows < 4 || cols < 4) {
print_help();
return EXIT_FAILURE;
}
printf("Board size is %dx%d (rows x col)\n", rows, cols); printf("Board size is %dx%d (rows x col)\n", rows, cols);
Connect4 *connect4 = connect4_create(mode, rows, cols); Connect4 *connect4 = connect4_create(mode, rows, cols);
connect4_print(connect4); connect4_print(connect4);
PlacingStatus status; PlacingStatus status;
while (true) { while (true) {
do { do {
printf("Column number? (starts at 1):"); printf("Column number? (starts at 1):");
...@@ -45,11 +67,13 @@ int main(int argc, char *argv[]) { ...@@ -45,11 +67,13 @@ int main(int argc, char *argv[]) {
status = connect4_play(connect4, x, on_piece_placed); status = connect4_play(connect4, x, on_piece_placed);
} while (status == PlacingStatusColumnFull || status == PlacingStatusInvalidColumn); } while (status == PlacingStatusColumnFull || status == PlacingStatusInvalidColumn);
if (status != PlacingStatusPiecePlaced) if (status != PlacingStatusPiecePlaced) {
break; break;
} }
}
print_game_result(mode, connect4->current_player, status); print_game_result(mode, connect4->current_player, status);
connect4_destroy(connect4); connect4_destroy(connect4);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment