aboutsummaryrefslogtreecommitdiff
path: root/voerbak
diff options
context:
space:
mode:
authorlonkaars <l.leblansch@gmail.com>2021-02-23 14:14:50 +0100
committerlonkaars <l.leblansch@gmail.com>2021-02-23 14:14:50 +0100
commit1a55f52bb79b609cd850a77e2f7a9fdc6b4fbf6b (patch)
treea28604c4e89be863954baa887e758bd0419d2e53 /voerbak
parent34c9fa5176f0d2c18457a72085f5803c2d616cc6 (diff)
split up code into seperate files
Diffstat (limited to 'voerbak')
-rw-r--r--voerbak/voerbak.c64
-rw-r--r--voerbak/voerbak.h44
-rw-r--r--voerbak/win.c53
-rw-r--r--voerbak/win.h27
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);