diff options
Diffstat (limited to 'voerbak')
-rw-r--r-- | voerbak/voerbak.c | 64 | ||||
-rw-r--r-- | voerbak/voerbak.h | 44 | ||||
-rw-r--r-- | voerbak/win.c | 53 | ||||
-rw-r--r-- | voerbak/win.h | 27 |
4 files changed, 130 insertions, 58 deletions
diff --git a/voerbak/voerbak.c b/voerbak/voerbak.c index ebd32eb..1ac74b6 100644 --- a/voerbak/voerbak.c +++ b/voerbak/voerbak.c @@ -3,75 +3,23 @@ #include <memory.h> #include <stdbool.h> -struct Board { - int width; - int height; - int length; - int* board; -}; +#include "voerbak.h" +#include "win.h" -void printBoard(struct Board *b) { +void printBoard(Board *b) { for (int i = 0; i < b->length; i++) printf("%d", b->board[i]); printf("\n"); fflush(stdout); } -int recursiveSolve(struct Board *b, int pos, int direction, int d_index, int currentLength) { - int newPos = pos + direction; - if (newPos > b->length - 1 || newPos < 0) return currentLength; - int row = pos % b->width; - if (row == b->width && d_index >= 1 && d_index <= 3) return currentLength; - if (row == 0 && d_index >= 5 && d_index <= 7) return currentLength; - if (b->board[newPos] != b->board[pos]) return currentLength; - return recursiveSolve(b, newPos, direction, d_index, currentLength + 1); -} - -bool checkWin(struct Board *b, int pos) { - int directions[8] = { - b->width, // north - b->width + 1, // northeast - 1, // east - -b->width + 1, // southeast - -b->width, // south - -b->width -1, // southwest - -1, // west - b->width -1 // northwest - }; - - int values[8]; - for (int i = 0; i < 8; i++) - values[i] = recursiveSolve(b, pos, directions[i], i, 0); - - int joinedValues[4] = { - values[0] + values[4], - values[1] + values[5], - values[2] + values[6], - values[3] + values[7] - }; - - bool won = false; - for (int i = 0; i < 4; i++) { - if (joinedValues[i] >= 3) { - won = won || true; - - int start_pos = pos + directions[i+0] * values[i+0]; - int end_pos = pos + directions[i+4] * values[i+4]; - printf("w:%d-%d\n", start_pos, end_pos); - fflush(stdout); - } - } - - return won; -} - -bool boardFull(struct Board *b) { +bool boardFull(Board *b) { for (int i = 0; i < b->length; i++) if (b->board[i] == 0) return false; return true; } -bool dropFisje(struct Board *b, int column, int disc) { +bool dropFisje(Board *b, int column, int disc) { for (int row = 0; row < b->height; row++) { int pos = column + row * b->width; if (b->board[pos] == 0) { @@ -89,7 +37,7 @@ int main() { int width, height; scanf("%d %d", &width, &height); - struct Board *gameBoard = malloc(sizeof(struct Board)); + Board *gameBoard = malloc(sizeof(Board)); gameBoard->board = malloc(sizeof(int) * (width * height - 1)); gameBoard->width = width; gameBoard->height = height; diff --git a/voerbak/voerbak.h b/voerbak/voerbak.h new file mode 100644 index 0000000..0ef6cf9 --- /dev/null +++ b/voerbak/voerbak.h @@ -0,0 +1,44 @@ +#pragma once +#include <stdio.h> +#include <stdlib.h> +#include <memory.h> +#include <stdbool.h> + +/** + * @brief Structure to store a board + * + * @param width Board width + * @param height Board height + * @param length Board state array length (width * height) + * @param board Board state array + */ +typedef struct { + int width; + int height; + int length; + int* board; +} Board; + +/** + * @brief Print the board array + */ +void printBoard(Board*); + +/** + * @brief Check if the board is full (draw) + * + * @return `true` board is full + */ +bool boardFull(Board*); + +/** + * @brief Drop a disc into the board + * + * @return `true` if drop was successful, `false` if column full + */ +bool dropFisje(Board*, int, int); + +/** + * @brief Main function + */ +int main(); diff --git a/voerbak/win.c b/voerbak/win.c new file mode 100644 index 0000000..c995060 --- /dev/null +++ b/voerbak/win.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include <stdbool.h> + +#include "voerbak.h" + +int winCheckRecursive(Board *b, int pos, int direction, int d_index, int currentLength) { + int newPos = pos + direction; + if (newPos > b->length - 1 || newPos < 0) return currentLength; + int row = pos % b->width; + if (row == b->width && d_index >= 1 && d_index <= 3) return currentLength; + if (row == 0 && d_index >= 5 && d_index <= 7) return currentLength; + if (b->board[newPos] != b->board[pos]) return currentLength; + return winCheckRecursive(b, newPos, direction, d_index, currentLength + 1); +} + +bool checkWin(Board *b, int pos) { + int directions[8] = { + b->width, // north + b->width + 1, // northeast + 1, // east + -b->width + 1, // southeast + -b->width, // south + -b->width -1, // southwest + -1, // west + b->width -1 // northwest + }; + + int values[8]; + for (int i = 0; i < 8; i++) + values[i] = winCheckRecursive(b, pos, directions[i], i, 0); + + int joinedValues[4] = { + values[0] + values[4], + values[1] + values[5], + values[2] + values[6], + values[3] + values[7] + }; + + bool won = false; + for (int i = 0; i < 4; i++) { + if (joinedValues[i] >= 3) { + won = won || true; + + int start_pos = pos + directions[i+0] * values[i+0]; + int end_pos = pos + directions[i+4] * values[i+4]; + printf("w:%d-%d\n", start_pos, end_pos); + fflush(stdout); + } + } + + return won; +} + diff --git a/voerbak/win.h b/voerbak/win.h new file mode 100644 index 0000000..41122a5 --- /dev/null +++ b/voerbak/win.h @@ -0,0 +1,27 @@ +#pragma once +#include <stdbool.h> + +#include "voerbak.h" + +/** + * @brief Get length of longest streak with same color from `pos` in direction `direction` + * + * @param b Board to check + * @param pos Position to check win position from (position of last dropped disc) + * @param direction Direction offset to step forward to + * @param d_index Index of direction in directions array (defined in `checkWin()`) + * @param currentLength Current length of same color 'streak' + * + * @return Length of longest streak with same color from `pos` in direction `direction` + */ +int winCheckRecursive(Board*, int, int, int, int); + +/** + * @brief Check for winning position from position `pos` + * + * @param b Board to check + * @param pos Position to check win position from (position of last dropped disc) + * + * @return `true` if game was won by the color that's in `b->board[pos]` + */ +bool checkWin(Board*, int); |