2 * =====================================================================================
4 * Filename: coordinates.c
6 * Description: Data definition and functions to manipulate elements in the grid
9 * Created: 16/03/2017 19:05:02
13 * Author: Jerome Benoit (fraggle), jerome.benoit@piment-noir.org
14 * Organization: Piment Noir
16 * =====================================================================================
19 #include "coordinates.h"
21 void zero_coordinates(coordinates_t
* coordinates_array
) {
23 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
24 coordinates_array
[i
] = set_coordinates(0, 0, 0);
28 coordinates_t
set_coordinates(int y
, int x
, unsigned type
) {
29 coordinates_t new_coordinates
;
31 new_coordinates
.y
= y
;
32 new_coordinates
.x
= x
;
33 new_coordinates
.type
= type
;
34 return new_coordinates
;
37 /* FIXME: Does it worth doing a coordinates_t get_coordinates(int y, int x, unsigned type); helper function? */
38 /* Or a int get_coordinates_x(coordinates_t coordinates); helper function? */
40 /* this function do a lot of sanity checks before adding new board elements,
41 * hence the loop. moving the checks in the main loop is also possible.
42 * for now, just branch in the main loop given this function error value returned. */
43 unsigned add_coordinates(coordinates_t new_coordinates
, coordinates_t
* coordinates_array
, unsigned round
) {
45 /* valid coordinates are in the [1-3] range */
46 if (new_coordinates
.y
< 1 || new_coordinates
.y
> 3 || new_coordinates
.x
< 1 || new_coordinates
.x
> 3) {
47 return 3; /* error value for invalid coordinates */
48 } else if (round
== MAX_COORDINATES
- 1) {
49 /* round is off-by-one vs. MAX_COORDINATES */
50 coordinates_array
[MAX_COORDINATES
- 1] = new_coordinates
;
51 return 1; /* error value for full array */
53 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
54 /* check if already entered */
55 if (new_coordinates
.y
== (coordinates_array
+ i
)->y
&& new_coordinates
.x
== (coordinates_array
+ i
)->x
) {
56 return 2; /* error value for duplicates */
57 } else if ((coordinates_array
+ i
)->y
== 0 && (coordinates_array
+ i
)->x
== 0) {
58 coordinates_array
[i
] = new_coordinates
;
59 return 0; /* error value when everything if fine */
62 return 4; /* error value for unknown error case - should never happen - */
65 static bool chk_line(coordinates_t
* coordinates_array
, int line_number
, unsigned round
) {
66 unsigned nb_o_align
= 0;
67 unsigned nb_x_align
= 0;
69 for (unsigned i
= 0; i
<= round
; i
++) {
70 /* check if they are all the same */
71 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 0) {
74 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 1) {
78 if (nb_o_align
== 3 || nb_x_align
== 3) {
84 static bool chk_column(coordinates_t
* coordinates_array
, int column_number
, unsigned round
) {
85 unsigned nb_o_align
= 0;
86 unsigned nb_x_align
= 0;
88 for (unsigned i
= 0; i
<= round
; i
++) {
89 /* check if they are all the same */
90 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 0) {
93 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 1) {
97 /* one column must be full of the same type */
98 if (nb_o_align
== 3 || nb_x_align
== 3) {
104 static bool chk_diagonals(coordinates_t
* coordinates_array
, unsigned round
) {
105 unsigned nb_o_diag_one
= 0, nb_o_diag_two
= 0;
106 unsigned nb_x_diag_one
= 0, nb_x_diag_two
= 0;
108 for (unsigned i
= 0; i
<= round
; i
++) {
109 /* dumb count of each elements type in the two diagonals */
110 for (int y_x_diag
= 1; y_x_diag
< 4; y_x_diag
++) {
111 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 0) {
114 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 0) {
117 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 1) {
120 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 1) {
124 if (nb_o_diag_one
== 3 || nb_o_diag_two
== 3 || nb_x_diag_one
== 3 || nb_x_diag_two
== 3) {
131 bool chk_win_conditions(coordinates_t
* coordinates_array
, unsigned round
) {
133 /* winning conditions begin at round = 4 */
135 if (chk_diagonals(coordinates_array
, round
)) {
138 for (unsigned i
= 1; i
< 4; i
++) {
139 if (chk_line(coordinates_array
, i
, round
) || \
140 chk_column(coordinates_array
, i
, round
)) {