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 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(int y, int x, unsigned type); helper function? */
40 /* the 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 unsigned add_coordinates(coordinates_t new_coordinates
, coordinates_t
* coordinates_array
, unsigned round
) {
44 /* valid coordinates are in the [1-3] range */
45 if (new_coordinates
.y
< 1 || new_coordinates
.y
> 3 || new_coordinates
.x
< 1 || new_coordinates
.x
> 3) {
46 return 3; /* error value for invalid coordinates */
47 } else if (round
== MAX_COORDINATES
) {
48 /* round is off-by-one */
49 coordinates_array
[MAX_COORDINATES
- 1] = new_coordinates
;
50 return 1; /* error value for full array */
52 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
53 /* check if already entered */
54 if (new_coordinates
.y
== (coordinates_array
+ i
)->y
&& new_coordinates
.x
== (coordinates_array
+ i
)->x
) {
55 return 2; /* error value for duplicates */
56 } else if ((coordinates_array
+ i
)->y
== 0 && (coordinates_array
+ i
)->x
== 0) {
57 coordinates_array
[i
] = new_coordinates
;
58 return 0; /* error value when everything if fine */
61 return 4; /* error value for unknown error case - should never happen - */
64 static bool chk_line(coordinates_t
* coordinates_array
, int line_number
, unsigned round
) {
65 unsigned nb_o_align
= 0;
66 unsigned nb_x_align
= 0;
68 for (unsigned i
= 0; i
< round
; i
++) {
69 /* check if they are all the same */
70 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 0) {
73 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 1) {
77 if (nb_o_align
== 3 || nb_x_align
== 3) {
83 static bool chk_column(coordinates_t
* coordinates_array
, int column_number
, unsigned round
) {
84 unsigned nb_o_align
= 0;
85 unsigned nb_x_align
= 0;
87 for (unsigned i
= 0; i
< round
; i
++) {
88 /* check if they are all the same */
89 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 0) {
92 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 1) {
96 /* one column must be full of the same type */
97 if (nb_o_align
== 3 || nb_x_align
== 3) {
103 static bool chk_diagonals(coordinates_t
* coordinates_array
, unsigned round
) {
104 unsigned nb_o_diag_one
= 0, nb_o_diag_two
= 0;
105 unsigned nb_x_diag_one
= 0, nb_x_diag_two
= 0;
107 for (unsigned i
= 0; i
< round
; i
++) {
108 /* dumb count of each elements type in the two diagonals */
109 for (int y_x_diag
= 1; y_x_diag
< 4; y_x_diag
++) {
110 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 0) {
113 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 0) {
116 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 1) {
119 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 1) {
123 if (nb_o_diag_one
== 3 || nb_o_diag_two
== 3 || nb_x_diag_one
== 3 || nb_x_diag_two
== 3) {
130 bool chk_win_conditions(coordinates_t
* coordinates_array
, unsigned round
) {
132 /* winning conditions begin at round = 5 */
134 if (chk_diagonals(coordinates_array
, round
)) {
137 for (unsigned i
= 1; i
< 4; i
++) {
138 if (chk_line(coordinates_array
, i
, round
) || \
139 chk_column(coordinates_array
, i
, round
)) {