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"
23 void init_coordinates(coordinates_t
* coordinates_array
) {
25 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
26 coordinates_array
[i
] = set_coordinates(0, 0, 0);
30 coordinates_t
set_coordinates(int y
, int x
, unsigned type
) {
31 coordinates_t new_coordinates
;
33 new_coordinates
.y
= y
;
34 new_coordinates
.x
= x
;
35 new_coordinates
.type
= type
;
36 return new_coordinates
;
39 /* FIXME: Does it worth doing a coordinates_t get_coordinates(int y, int x, unsigned type); helper function? */
40 /* Or a int get_coordinates_x(int y, int x, unsigned type); helper function? */
42 /* the function do a lot of sanity checks before adding new board elements,
43 * hence the loop. moving the checks in the main loop is also possible */
44 unsigned add_coordinates(coordinates_t new_coordinates
, coordinates_t
* coordinates_array
, unsigned round
) {
46 /* valid coordinates are in the [1-3] range */
47 if (new_coordinates
.y
< 1 || new_coordinates
.y
> 3 || new_coordinates
.x
< 1 || new_coordinates
.x
> 3) {
48 return 3; /* error value for invalid coordinates */
49 } else if (round
== MAX_COORDINATES
) {
50 /* round is off-by-one */
51 coordinates_array
[MAX_COORDINATES
- 1] = new_coordinates
;
52 return 1; /* error value for full array */
54 for (unsigned i
= 0; i
< MAX_COORDINATES
; i
++) {
55 /* check if already entered */
56 if (new_coordinates
.y
== (coordinates_array
+ i
)->y
&& new_coordinates
.x
== (coordinates_array
+ i
)->x
) {
57 return 2; /* error value for duplicates */
58 } else if ((coordinates_array
+ i
)->y
== 0 && (coordinates_array
+ i
)->x
== 0) {
59 coordinates_array
[i
] = new_coordinates
;
60 return 0; /* error value when everything if fine */
63 return 4; /* error value for unknown error case - should never happen - */
66 static bool chk_line(coordinates_t
* coordinates_array
, int line_number
, unsigned round
) {
67 unsigned nb_o_align
= 0;
68 unsigned nb_x_align
= 0;
70 for (unsigned i
= 0; i
< round
; i
++) {
71 /* check if they are all the same */
72 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 0) {
75 if ((coordinates_array
+ i
)->y
== line_number
&& (coordinates_array
+ i
)->type
== 1) {
79 if (nb_o_align
== 3 || nb_x_align
== 3) {
85 static bool chk_column(coordinates_t
* coordinates_array
, int column_number
, unsigned round
) {
86 unsigned nb_o_align
= 0;
87 unsigned nb_x_align
= 0;
89 for (unsigned i
= 0; i
< round
; i
++) {
90 /* check if they are all the same */
91 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 0) {
94 if ((coordinates_array
+ i
)->x
== column_number
&& (coordinates_array
+ i
)->type
== 1) {
98 /* one column must be full of the same type */
99 if (nb_o_align
== 3 || nb_x_align
== 3) {
105 static bool chk_diagonals(coordinates_t
* coordinates_array
, unsigned round
) {
106 unsigned nb_o_diag_one
= 0, nb_o_diag_two
= 0;
107 unsigned nb_x_diag_one
= 0, nb_x_diag_two
= 0;
109 for (unsigned i
= 0; i
< round
; i
++) {
110 /* dumb count of each elements type in the two diagonals */
111 for (int y_x_diag
= 1; y_x_diag
< 4; y_x_diag
++) {
112 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 0) {
115 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 0) {
118 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== y_x_diag
&& (coordinates_array
+ i
)->type
== 1) {
121 if ((coordinates_array
+ i
)->y
== y_x_diag
&& (coordinates_array
+ i
)->x
== (4 - y_x_diag
) && (coordinates_array
+ i
)->type
== 1) {
125 if (nb_o_diag_one
== 3 || nb_o_diag_two
== 3 || nb_x_diag_one
== 3 || nb_x_diag_two
== 3) {
132 bool chk_win_conditions(coordinates_t
* coordinates_array
, unsigned round
) {
134 /* winning conditions begin at round = 5 */
136 if (chk_diagonals(coordinates_array
, round
)) {
139 for (unsigned i
= 1; i
< 4; i
++) {
140 if (chk_line(coordinates_array
, i
, round
) || \
141 chk_column(coordinates_array
, i
, round
)) {