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 init_coordinates(coordinates_t
* coordinates_array
) {
23 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
24 coordinates_array
[i
] = set_coordinates(0, 0, 0);
28 void reinit_coordinates(coordinates_t
* coordinates_array
) {
30 init_coordinates(coordinates_array
);
33 coordinates_t
set_coordinates(int y
, int x
, unsigned type
) {
34 coordinates_t new_coordinates
;
36 new_coordinates
.y
= y
;
37 new_coordinates
.x
= x
;
38 new_coordinates
.type
= type
;
39 return new_coordinates
;
42 /* FIXME: Does it worth doing a coordinates_t get_coordinates(int y, int x, unsigned type); helper function? */
43 /* Or a int get_coordinates_x(int y, int x, unsigned type); helper function? */
45 /* the function do a lot of sanity checks before adding new board elements,
46 * hence the loop. moving the checks in the main loop is also possible */
47 unsigned add_coordinates(coordinates_t new_coordinates
, coordinates_t
* coordinates_array
, unsigned round
) {
49 /* valid coordinates are in the [1-3] range */
50 if (new_coordinates
.y
< 1 || new_coordinates
.y
> 3 || new_coordinates
.x
< 1 || new_coordinates
.x
> 3) {
51 return 3; /* error value for invalid coordinates */
52 } else if (round
== MAX_COORDINATES
- 1) {
53 /* round is off-by-one vs. MAX_COORDINATES */
54 coordinates_array
[MAX_COORDINATES
- 1] = new_coordinates
;
55 return 1; /* error value for full array */
57 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
58 /* check if already entered */
59 if (new_coordinates
.y
== (coordinates_array
+ i
)->y
&& new_coordinates
.x
== (coordinates_array
+ i
)->x
) {
60 return 2; /* error value for duplicates */
61 } else if ((coordinates_array
+ i
)->y
== 0 && (coordinates_array
+ i
)->x
== 0) {
62 coordinates_array
[i
] = new_coordinates
;
63 return 0; /* error value when everything if fine */
66 return 4; /* error value for unknown error case - should never happen - */
69 static bool chk_line(coordinates_t
* coordinates_array
, int line_number
, unsigned round
) {
70 unsigned nb_o_align
= 0;
71 unsigned nb_x_align
= 0;
73 for (unsigned i
= 0; i
<= round
; i
++) {
74 /* check if they are all the same */
75 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 0) {
78 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 1) {
82 if (nb_o_align
== 3 || nb_x_align
== 3) {
88 static bool chk_column(coordinates_t
* coordinates_array
, int column_number
, unsigned round
) {
89 unsigned nb_o_align
= 0;
90 unsigned nb_x_align
= 0;
92 for (unsigned i
= 0; i
<= round
; i
++) {
93 /* check if they are all the same */
94 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 0) {
97 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 1) {
101 /* one column must be full of the same type */
102 if (nb_o_align
== 3 || nb_x_align
== 3) {
108 static bool chk_diagonals(coordinates_t
* coordinates_array
, unsigned round
) {
109 unsigned nb_o_diag_one
= 0, nb_o_diag_two
= 0;
110 unsigned nb_x_diag_one
= 0, nb_x_diag_two
= 0;
112 for (unsigned i
= 0; i
<= round
; i
++) {
113 /* dumb count of each elements type in the two diagonals */
114 for (int y_x_diag
= 1; y_x_diag
< 4; y_x_diag
++) {
115 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 0) {
118 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 0) {
121 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 1) {
124 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 1) {
128 if (nb_o_diag_one
== 3 || nb_o_diag_two
== 3 || nb_x_diag_one
== 3 || nb_x_diag_two
== 3) {
135 bool chk_win_conditions(coordinates_t
* coordinates_array
, unsigned round
) {
137 /* winning conditions begin at round = 4 */
139 if (chk_diagonals(coordinates_array
, round
)) {
142 for (unsigned i
= 1; i
< 4; i
++) {
143 if (chk_line(coordinates_array
, i
, round
) || \
144 chk_column(coordinates_array
, i
, round
)) {