TP 13 exo2: Robustify the current tic-tac-toe implementation
[TD_C.git] / TP_13 / exo2 / src / main.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <ncurses.h>
5
6 #include "display.h"
7 #include "coordinates.h"
8
9 int main() {
10 int row, col, errno = 0, round = 0, player = 0, key_pressed = 0;
11 bool winning_condition = false;
12 bool loop_exit_condition = false;
13 const int str_max_length = 50;
14 /* FIXME: make a strings handling library */
15 char* top_msg = malloc(str_max_length * sizeof(char));
16 char* back_msg = malloc(str_max_length * sizeof(char));
17 char* exit_msg = malloc(str_max_length * sizeof(char));
18
19 initscr();
20 getmaxyx(stdscr, row, col);
21 noecho();
22 curs_set(0);
23
24 /* array of the active coordinates in the entered order */
25 coordinates_t coordinates_array[MAX_COORDINATES];
26 init_coordinates(coordinates_array);
27 coordinates_t new_coordinates = {0, 0, 0};
28
29 /* center base coordinates for the board */
30 int base_y = row/2 - 4;
31 int base_x = col/2 - 7;
32
33 do {
34 if (round % 2 != 0) {
35 player = 1;
36 top_msg = "Joueur 2 joue";
37 } else {
38 player = 0;
39 top_msg = "Joueur 1 joue";
40 }
41
42 mvprintw(base_y - 2, (base_x + 7 - strlen(top_msg)/2), top_msg);
43
44 print_board(base_y, base_x);
45
46 print_coordinates(coordinates_array, base_y, base_x);
47
48 /* FIXME: group the winning case code blocks */
49 if (!winning_condition) {
50 /* getch() is blocking */
51 key_pressed = getch();
52 switch (key_pressed) {
53 case 'a':
54 new_coordinates = set_coordinates(1, 1, player);
55 break;
56 case 'z':
57 new_coordinates = set_coordinates(1, 2, player);
58 break;
59 case 'e':
60 new_coordinates = set_coordinates(1, 3, player);
61 break;
62 case 'q':
63 new_coordinates = set_coordinates(2, 1, player);
64 break;
65 case 's':
66 new_coordinates = set_coordinates(2, 2, player);
67 break;
68 case 'd':
69 new_coordinates = set_coordinates(2, 3, player);
70 break;
71 case 'w':
72 new_coordinates = set_coordinates(3, 1, player);
73 break;
74 case 'x':
75 new_coordinates = set_coordinates(3, 2, player);
76 break;
77 case 'c':
78 new_coordinates = set_coordinates(3, 3, player);
79 break;
80 default:
81 /* set invalid coordinates */
82 new_coordinates = set_coordinates(0, 0, player);
83 break;
84 }
85 errno = add_coordinates(new_coordinates, coordinates_array, round);
86 winning_condition = chk_win_conditions(coordinates_array, round);
87 }
88
89 if (errno == 0) {
90 round++;
91 }
92
93 if (winning_condition) {
94 if (player == 0) {
95 back_msg = "Joueur 1 gagne !";
96 } else {
97 back_msg = "Joueur 2 gagne !";
98 }
99 }
100
101 if (!winning_condition) {
102 if (errno == 2) {
103 back_msg = "Choisir une case vide";
104 } else if (errno == 3) {
105 back_msg = "Coordonnees invalides";
106 } else if (errno == 1) {
107 back_msg = "Tableau rempli sans gagnant: egalite";
108 } else if (errno == 4) {
109 back_msg = "Erreur inconnue";
110 } else if (errno == 0) {
111 /* FIXME: properly zero the string to avoid the clear() */
112 back_msg = "";
113 clear();
114 }
115 }
116
117 mvprintw(base_y + 10, (base_x + 7 - strlen(back_msg)/2), back_msg);
118
119 if (winning_condition || errno == 1) {
120 /* print the updated coordinates before exiting */
121 print_coordinates(coordinates_array, base_y, base_x);
122 exit_msg = "Pressez une touche pour sortir ou \'r\' pour rejouer";
123 mvprintw(base_y + 12, (base_x + 7 - strlen(exit_msg)/2), exit_msg);
124 loop_exit_condition = true;
125 if (loop_exit_condition) {
126 int key_exit = 0;
127 /* getch() is blocking */
128 key_exit = getch();
129 if (key_exit == 'r') {
130 round = 0;
131 player = 0;
132 errno = 0;
133 reinit_coordinates(coordinates_array);
134 winning_condition = false;
135 loop_exit_condition = false;
136 clear();
137 }
138 }
139 }
140
141 refresh();
142
143 } while (!loop_exit_condition);
144
145 endwin();
146
147 if (!top_msg)
148 free(top_msg);
149 if (!back_msg)
150 free(back_msg);
151 if (!exit_msg)
152 free(exit_msg);
153
154 exit(EXIT_SUCCESS);
155 }