#include "coordinates.h"
void init_coordinates(coordinates_t* coordinates_array) {
+
for (unsigned i = 0; i < MAX_COORDINATES; i++) {
coordinates_array[i] = set_coordinates(0, 0, 0);
}
}
+void reinit_coordinates(coordinates_t* coordinates_array) {
+
+ init_coordinates(coordinates_array);
+}
+
coordinates_t set_coordinates(int y, int x, unsigned type) {
coordinates_t new_coordinates;
return new_coordinates;
}
+/* FIXME: Does it worth doing a coordinates_t get_coordinates(int y, int x, unsigned type); helper function? */
+/* Or a int get_coordinates_x(coordinates_t coordinates); helper function? */
+
/* the function do a lot of sanity checks before adding new board elements,
- * hence the loop. moving the checks in the main loop is also possible */
+ * hence the loop. moving the checks in the main loop is also possible.
+ * for now, just branch in the main loop given this function error value returned. */
unsigned add_coordinates(coordinates_t new_coordinates, coordinates_t* coordinates_array, unsigned round) {
+
/* valid coordinates are in the [1-3] range */
if (new_coordinates.y < 1 || new_coordinates.y > 3 || new_coordinates.x < 1 || new_coordinates.x > 3) {
return 3; /* error value for invalid coordinates */
- } else if (round == MAX_COORDINATES + 1) {
+ } else if (round == MAX_COORDINATES - 1) {
+ /* round is off-by-one vs. MAX_COORDINATES */
+ coordinates_array[MAX_COORDINATES - 1] = new_coordinates;
return 1; /* error value for full array */
}
-
for (unsigned i = 0; i < MAX_COORDINATES; i++) {
/* check if already entered */
if (new_coordinates.y == (coordinates_array + i)->y && new_coordinates.x == (coordinates_array + i)->x) {
return 4; /* error value for unknown error case - should never happen - */
}
-bool chk_win_conditions(coordinates_t* coordinates_array) {
- for (unsigned i = 0; i < MAX_COORDINATES; i++) {
+static bool chk_line(coordinates_t* coordinates_array, int line_number, unsigned round) {
+ unsigned nb_o_align = 0;
+ unsigned nb_x_align = 0;
+ for (unsigned i = 0; i <= round; i++) {
+ /* check if they are all the same */
+ if ((coordinates_array + i)->y == line_number && (coordinates_array + i)->type == 0) {
+ nb_o_align++;
+ }
+ if ((coordinates_array + i)->y == line_number && (coordinates_array + i)->type == 1) {
+ nb_x_align++;
+ }
+ }
+ if (nb_o_align == 3 || nb_x_align == 3) {
+ return true;
+ }
+ return false;
+}
+
+static bool chk_column(coordinates_t* coordinates_array, int column_number, unsigned round) {
+ unsigned nb_o_align = 0;
+ unsigned nb_x_align = 0;
+
+ for (unsigned i = 0; i <= round; i++) {
+ /* check if they are all the same */
+ if ((coordinates_array + i)->x == column_number && (coordinates_array + i)->type == 0) {
+ nb_o_align++;
+ }
+ if ((coordinates_array + i)->x == column_number && (coordinates_array + i)->type == 1) {
+ nb_x_align++;
+ }
+ }
+ /* one column must be full of the same type */
+ if (nb_o_align == 3 || nb_x_align == 3) {
+ return true;
+ }
+ return false;
+}
+
+static bool chk_diagonals(coordinates_t* coordinates_array, unsigned round) {
+ unsigned nb_o_diag_one = 0, nb_o_diag_two = 0;
+ unsigned nb_x_diag_one = 0, nb_x_diag_two = 0;
+
+ for (unsigned i = 0; i <= round; i++) {
+ /* dumb count of each elements type in the two diagonals */
+ for (int y_x_diag = 1; y_x_diag < 4; y_x_diag++) {
+ if ((coordinates_array + i)->y == y_x_diag && (coordinates_array + i)->x == y_x_diag && (coordinates_array + i)->type == 0) {
+ nb_o_diag_one++;
+ }
+ if ((coordinates_array + i)->y == y_x_diag && (coordinates_array + i)->x == (4 - y_x_diag) && (coordinates_array + i)->type == 0) {
+ nb_o_diag_two++;
+ }
+ if ((coordinates_array + i)->y == y_x_diag && (coordinates_array + i)->x == y_x_diag && (coordinates_array + i)->type == 1) {
+ nb_x_diag_one++;
+ }
+ if ((coordinates_array + i)->y == y_x_diag && (coordinates_array + i)->x == (4 - y_x_diag) && (coordinates_array + i)->type == 1) {
+ nb_x_diag_two++;
+ }
+ }
+ if (nb_o_diag_one == 3 || nb_o_diag_two == 3 || nb_x_diag_one == 3 || nb_x_diag_two == 3) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool chk_win_conditions(coordinates_t* coordinates_array, unsigned round) {
+
+ /* winning conditions begin at round = 4 */
+ if (round > 3) {
+ if (chk_diagonals(coordinates_array, round)) {
+ return true;
+ }
+ for (unsigned i = 1; i < 4; i++) {
+ if (chk_line(coordinates_array, i, round) || \
+ chk_column(coordinates_array, i, round)) {
+ return true;
+ }
+ }
}
return false;
}