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(coordinates_t coordinates); 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 * for now, just branch in the main loop given this function error value returned. */
48 unsigned add_coordinates(coordinates_t new_coordinates
, coordinates_t
* coordinates_array
, unsigned round
) {
50 /* valid coordinates are in the [1-3] range */
51 if (new_coordinates
.y
< 1 || new_coordinates
.y
> 3 || new_coordinates
.x
< 1 || new_coordinates
.x
> 3) {
52 return 3; /* error value for invalid coordinates */
53 } else if (round
== MAX_COORDINATES
- 1) {
54 /* round is off-by-one vs. MAX_COORDINATES */
55 coordinates_array
[MAX_COORDINATES
- 1] = new_coordinates
;
56 return 1; /* error value for full array */
58 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
59 /* check if already entered */
60 if (new_coordinates
.y
== (coordinates_array
+ i
)->y
&& new_coordinates
.x
== (coordinates_array
+ i
)->x
) {
61 return 2; /* error value for duplicates */
62 } else if ((coordinates_array
+ i
)->y
== 0 && (coordinates_array
+ i
)->x
== 0) {
63 coordinates_array
[i
] = new_coordinates
;
64 return 0; /* error value when everything if fine */
67 return 4; /* error value for unknown error case - should never happen - */
70 static bool chk_line(coordinates_t
* coordinates_array
, int line_number
, unsigned round
) {
71 unsigned nb_o_align
= 0;
72 unsigned nb_x_align
= 0;
74 for (unsigned i
= 0; i
<= round
; i
++) {
75 /* check if they are all the same */
76 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 0) {
79 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 1) {
83 if (nb_o_align
== 3 || nb_x_align
== 3) {
89 static bool chk_column(coordinates_t
* coordinates_array
, int column_number
, unsigned round
) {
90 unsigned nb_o_align
= 0;
91 unsigned nb_x_align
= 0;
93 for (unsigned i
= 0; i
<= round
; i
++) {
94 /* check if they are all the same */
95 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 0) {
98 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 1) {
102 /* one column must be full of the same type */
103 if (nb_o_align
== 3 || nb_x_align
== 3) {
109 static bool chk_diagonals(coordinates_t
* coordinates_array
, unsigned round
) {
110 unsigned nb_o_diag_one
= 0, nb_o_diag_two
= 0;
111 unsigned nb_x_diag_one
= 0, nb_x_diag_two
= 0;
113 for (unsigned i
= 0; i
<= round
; i
++) {
114 /* dumb count of each elements type in the two diagonals */
115 for (int y_x_diag
= 1; y_x_diag
< 4; y_x_diag
++) {
116 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 0) {
119 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 0) {
122 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 1) {
125 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 1) {
129 if (nb_o_diag_one
== 3 || nb_o_diag_two
== 3 || nb_x_diag_one
== 3 || nb_x_diag_two
== 3) {
136 bool chk_win_conditions(coordinates_t
* coordinates_array
, unsigned round
) {
138 /* winning conditions begin at round = 4 */
140 if (chk_diagonals(coordinates_array
, round
)) {
143 for (unsigned i
= 1; i
< 4; i
++) {
144 if (chk_line(coordinates_array
, i
, round
) || \
145 chk_column(coordinates_array
, i
, round
)) {