PageRenderTime 357ms CodeModel.GetById 181ms app.highlight 76ms RepoModel.GetById 95ms app.codeStats 0ms

/indicateurs.c

https://github.com/sylafrs/Dames
C | 340 lines | 237 code | 49 blank | 54 comment | 181 complexity | 2aa0e2d28b4897ea44fc920979ad71e0 MD5 | raw file
  1#include "indicateurs.h"
  2#include <stdio.h>
  3
  4//ICI : le tableau de cases n'est pas modifié !
  5
  6//fonction qui repond ŕ la question : "mon pion ou ma dame peut-il aller lŕ ?"
  7bool possible(Case (*const plateau)[TAILLE_PLATEAU], int sourceX, int sourceY, int caseX, int caseY)
  8{
  9    bool possible = false;
 10    int i;
 11
 12    if(caseX < 0 || caseY < 0 || sourceX < 0 || sourceY < 0 || caseX >= TAILLE_PLATEAU || caseY >= TAILLE_PLATEAU || sourceX >= TAILLE_PLATEAU || sourceY >= TAILLE_PLATEAU )
 13    {
 14        return false;
 15    }
 16
 17    //si en diagonale et case d'arrivee vide...
 18    if(plateau[caseX][caseY].pion == non && abs(caseX-sourceX) == abs(caseY-sourceY))
 19    {
 20        //pion normal
 21        if(plateau[sourceX][sourceY].pion == normal)
 22        {
 23            //si on mange
 24            if(peutManger(plateau, sourceX, sourceY))
 25            {
 26                //si la case se trouve a deux d'intervalle et qu'entre il y ait un pion adverse
 27                //caseX-sourceX : ecart sur X
 28                //si l'ecart est de 2 : sourceX+((caseX - sourceX)/2) est l'abscisse de la case entre !
 29                if(abs(caseX-sourceX) == 2)
 30                    possible = plateau[sourceX+((caseX - sourceX)/2)][sourceY+((caseY - sourceY)/2)].joueur != plateau[sourceX][sourceY].joueur && plateau[sourceX+((caseX - sourceX)/2)][sourceY+((caseY - sourceY)/2)].pion != non;
 31            }
 32
 33            //on ne mange pas
 34            else if(abs(caseX-sourceX) == 1)
 35            {
 36                //les blancs : vers le haut
 37                if(plateau[sourceX][sourceY].joueur == blanc)
 38                    possible = (caseY-sourceY == -1);
 39
 40                //les noirs : vers le bas
 41                else
 42                    possible = (caseY-sourceY == +1);
 43            }
 44        }
 45
 46        //les reines
 47        else
 48        {
 49            //ne peux pas faire de cannibalisme ou sauter un groupe adverse.
 50            possible = true;
 51            i = 1;
 52
 53            //en bas ŕ droite
 54            if(caseX-sourceX > 0 && caseY-sourceY > 0)
 55            {
 56                //continue jusqu'au prochain obstacle
 57                while(possible && sourceX+i < caseX)
 58                {
 59                    possible = (plateau[sourceX+i][sourceY+i].pion == non);
 60                    i++;
 61                }
 62            }
 63
 64            //en bas ŕ gauche
 65            else if(caseX-sourceX > 0 && caseY-sourceY < 0)
 66            {
 67                //continue jusqu'au prochain obstacle
 68                while(possible && sourceX+i < caseX)
 69                {
 70                    possible = (plateau[sourceX+i][sourceY-i].pion == non);
 71                    i++;
 72                }
 73            }
 74
 75            //en haut ŕ gauche
 76            else if(caseX-sourceX < 0 && caseY-sourceY < 0)
 77            {
 78                //continue jusqu'au prochain obstacle
 79                while(possible && sourceX-i > caseX)
 80                {
 81                    possible = (plateau[sourceX-i][sourceY-i].pion == non);
 82                    i++;
 83                }
 84            }
 85
 86            //en haut ŕ droite
 87            else if(caseX-sourceX < 0 && caseY-sourceY > 0)
 88            {
 89                //continue jusqu'au prochain obstacle
 90                while(possible && sourceX-i > caseX)
 91                {
 92                    possible = (plateau[sourceX-i][sourceY+i].pion == non);
 93                    i++;
 94                }
 95            }
 96
 97            //si on peut manger : on doit manger !
 98            //sinon, possible garde sa valeur (on ne mange pas, donc pas d'obstacle)
 99            if(peutManger(plateau, sourceX, sourceY))
100            {
101                //obligé de manger !!!
102                possible = !possible;
103
104                //i = premiere case rencontree
105
106                //en bas ŕ droite, si l'obstacle rencontré est le joueur
107                if(caseX-sourceX > 0 && caseY-sourceY > 0 && plateau[sourceX+i-1][sourceY+i-1].joueur != plateau[sourceX][sourceY].joueur)
108                {
109                    //toutes les cases derriere le premier obstacle sont possibles jusqu'au deuxieme obstacle
110                    while(possible && sourceX+i < caseX)
111                    {
112                        possible = (plateau[sourceX+i][sourceY+i].pion == non);
113                        i++;
114                    }
115                }
116
117                //en bas ŕ gauche
118                else if(caseX-sourceX > 0 && caseY-sourceY < 0 && plateau[sourceX+i-1][sourceY-(i-1)].joueur != plateau[sourceX][sourceY].joueur)
119                {
120                    //toutes les cases derriere le premier obstacle sont possibles jusqu'au deuxieme obstacle
121                    while(possible && sourceX+i < caseX)
122                    {
123                        possible = (plateau[sourceX+i][sourceY-i].pion == non);
124                        i++;
125                    }
126                }
127
128                //en haut ŕ gauche
129                else if(caseX-sourceX < 0 && caseY-sourceY < 0 && plateau[sourceX-(i-1)][sourceY-(i-1)].joueur != plateau[sourceX][sourceY].joueur)
130                {
131                    //toutes les cases derriere le premier obstacle sont possibles jusqu'au deuxieme obstacle
132                    while(possible && sourceX-i > caseX)
133                    {
134                        possible = (plateau[sourceX-i][sourceY-i].pion == non);
135                        i++;
136                    }
137                }
138
139                //en haut ŕ droite
140                else if(caseX-sourceX < 0 && caseY-sourceY > 0 && plateau[sourceX-(i-1)][sourceY+i-1].joueur != plateau[sourceX][sourceY].joueur)
141                {
142                    //toutes les cases derriere le premier obstacle sont possibles jusqu'au deuxieme obstacle
143                    while(possible && sourceX-i > caseX)
144                    {
145                        possible = (plateau[sourceX-i][sourceY+i].pion == non);
146                        i++;
147                    }
148                }
149
150                //on ne peux pas manger, mais on peux manger ? oO
151                else
152                    possible = false;
153            }
154        }
155    }
156
157    return possible;
158}
159
160bool selectionnable(Case (*const plateau)[TAILLE_PLATEAU], int caseX, int caseY)
161{
162    int i,j = 0;
163    bool selectionnable = false;
164    bool souffle;
165
166    if(caseX < 0 || caseY < 0 || caseX >= TAILLE_PLATEAU || caseY >= TAILLE_PLATEAU)
167    {
168        fprintf(stderr, "Erreur : coordonnees erronnees dans selectionnable");
169        exit(EXIT_FAILURE);
170    }
171
172    //on ne selectionne pas une case vide...
173    if(plateau[caseX][caseY].pion != non)
174    {
175        //si on peut manger : on peut selectionner !
176        selectionnable = peutManger(plateau, caseX, caseY);
177
178        //sinon : il faut qu'aucune case ne puisse manger et que le deplacement soit possible !
179        if(!selectionnable)
180        {
181            //regarde si aucun pion ne peut manger
182            souffle = false;
183            while(!souffle && j < TAILLE_PLATEAU)
184            {
185                i = 0;
186                while(!souffle && i < TAILLE_PLATEAU)
187                {
188                    if(plateau[i][j].pion != non && plateau[i][j].joueur == plateau[caseX][caseY].joueur)
189                        souffle = peutManger(plateau, i, j);
190                    i++;
191                }
192                j++;
193            }
194
195            if(!souffle)
196            {
197                //si on peut bouger
198
199                //cas de la reine
200                if(plateau[caseX][caseY].pion == reine)
201                    selectionnable = possible(plateau, caseX, caseY, caseX-1, caseY+1) || possible(plateau, caseX, caseY, caseX+1, caseY+1) || possible(plateau, caseX, caseY, caseX-1, caseY-1) || possible(plateau, caseX, caseY, caseX+1, caseY-1);
202
203                //cas du pion noir
204                else if(plateau[caseX][caseY].joueur == noir)
205                    selectionnable = possible(plateau, caseX, caseY, caseX-1, caseY+1) || possible(plateau, caseX, caseY, caseX+1, caseY+1);
206
207                //cas du pion blanc
208                else
209                    selectionnable = possible(plateau, caseX, caseY, caseX-1, caseY-1) || possible(plateau, caseX, caseY, caseX+1, caseY-1);
210            }
211
212            //(else selectionnable = false;)
213        }
214    }
215
216    return selectionnable;
217}
218
219bool peutManger(Case (*const plateau)[TAILLE_PLATEAU], int caseX, int caseY)
220{
221    bool resultat = false, stop;
222    int i;
223
224    if(caseX < 0 || caseY < 0 || caseX >= TAILLE_PLATEAU || caseY >= TAILLE_PLATEAU)
225    {
226        fprintf(stderr, "Erreur : coordonnees erronnees dans peutManger");
227        exit(EXIT_FAILURE);
228    }
229
230    if(plateau[caseX][caseY].pion == normal)
231    {
232        //si on n'est pas au bord :
233            //si ya un pion adverse adjacent et qu'il y a de la place derriere
234
235        if(caseX < TAILLE_PLATEAU-2 && caseY < TAILLE_PLATEAU-2)
236            resultat = plateau[caseX+2][caseY+2].pion == non && plateau[caseX+1][caseY+1].pion != non && plateau[caseX+1][caseY+1].joueur != plateau[caseX][caseY].joueur;
237
238        if(!resultat && caseX < TAILLE_PLATEAU-2 && caseY > 1)
239            resultat = plateau[caseX+2][caseY-2].pion == non && plateau[caseX+1][caseY-1].pion != non && plateau[caseX+1][caseY-1].joueur != plateau[caseX][caseY].joueur;
240
241        if(!resultat && caseX > 1 && caseY > 1)
242            resultat = plateau[caseX-2][caseY-2].pion == non && plateau[caseX-1][caseY-1].pion != non && plateau[caseX-1][caseY-1].joueur != plateau[caseX][caseY].joueur;
243
244        if(!resultat && caseX > 1 && caseY < TAILLE_PLATEAU-2)
245            resultat = plateau[caseX-2][caseY+2].pion == non && plateau[caseX-1][caseY+1].pion != non && plateau[caseX-1][caseY+1].joueur != plateau[caseX][caseY].joueur;
246    }
247    else if(plateau[caseX][caseY].pion == reine)
248    {
249        //en gros il faut qu'il y ait sur au moins une de ses diagonales, un pion adverse puis un espace
250        //(mais pas de pion de notre couleur sur le chemin)
251
252        resultat = false;
253
254        //sur la diagonale bas-droite
255        stop = false;
256        i = 1;
257        while(!stop && !resultat && caseX+i < TAILLE_PLATEAU-1 && caseY+i < TAILLE_PLATEAU-1)
258        {
259            stop = plateau[caseX+i][caseY+i].pion != non;
260            resultat = stop && plateau[caseX+i][caseY+i].joueur != plateau[caseX][caseY].joueur && plateau[caseX+i+1][caseY+i+1].pion == non;
261            i++;
262        }
263
264        //sur la diagonale bas-gauche
265        stop = false;
266        i = 1;
267        while(!stop && !resultat && caseX+i < TAILLE_PLATEAU-1 && caseY-i > 0)
268        {
269            stop = plateau[caseX+i][caseY-i].pion != non;
270            resultat = stop && plateau[caseX+i][caseY-i].joueur != plateau[caseX][caseY].joueur && plateau[caseX+i+1][caseY-(i+1)].pion == non;
271            i++;
272        }
273
274        //sur la diagonale haut-gauche
275        stop = false;
276        i = 1;
277        while(!stop && !resultat && caseX-i > 0 && caseY-i > 0)
278        {
279            stop = plateau[caseX-i][caseY-i].pion != non;
280            resultat = stop && plateau[caseX-i][caseY-i].joueur != plateau[caseX][caseY].joueur && plateau[caseX-(i+1)][caseY-(i+1)].pion == non;
281            i++;
282        }
283
284        //sur la diagonale haut-droite
285        stop = false;
286        i = 1;
287        while(!stop && !resultat && caseX-i > 0 && caseY+i < TAILLE_PLATEAU-1)
288        {
289            stop = plateau[caseX-i][caseY+i].pion != non;
290            resultat = stop && plateau[caseX-i][caseY+i].joueur != plateau[caseX][caseY].joueur && plateau[caseX-(i+1)][caseY+i+1].pion == non;
291            i++;
292        }
293    }
294
295    return resultat;
296}
297
298bool gagner(Case (*const plateau)[TAILLE_PLATEAU], Joueur joueur)
299{
300    bool victoire = true;
301    int i = 0, j;
302
303    //victoire totale si le joueur adverse n'a plus de pion
304    //soit : si tous les pions presents sont les notres...
305    while(i < TAILLE_PLATEAU && victoire)
306    {
307        j = 0;
308        while(j < TAILLE_PLATEAU && victoire)
309        {
310            if(plateau[i][j].pion != non)
311                victoire = (plateau[i][j].joueur == joueur);
312
313            j++;
314        }
315        i++;
316    }
317    return victoire;
318}
319
320bool bloque(Case (*const plateau)[TAILLE_PLATEAU], Joueur joueur)
321{
322    int i = 0, j;
323    bool pasBloque = false;
324
325    //est bloqué un joueur qui ne peut rien selectionner...
326
327    while(i < TAILLE_PLATEAU && !pasBloque)
328    {
329        j = 0;
330        while(j < TAILLE_PLATEAU && !pasBloque)
331        {
332            if(plateau[i][j].pion != non && plateau[i][j].joueur == joueur)
333                pasBloque = selectionnable(plateau, i, j);
334            j++;
335        }
336        i++;
337    }
338
339    return !pasBloque;
340}