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