Votre question

Projet Puissance 4 en C. Expansion retardée ?

Tags :
  • Algorithme
  • Programmation
Dernière réponse : dans Programmation
25 Décembre 2009 17:38:20

Bonjour,

Je viens demander de l'aide pour un problème que je rencontre.

Voilà, je dois faire un puissance 4..
J'ai créé le mode 2 joueurs, tout marche assez bien.

Je viens maintenant de faire 'l'intelligence artificielle" pour un coup à l'avance (c-a-d quand il y a 3 mêmes signes [dans le puissance 4] qui sont à proximité).

Voici l'algorithme que j'ai utilisé (long mais c'est le même tout le temps .. ):

  1. void IA (int c[])
  2. {
  3. int coup = 0;
  4. int i, j;
  5.  
  6.  
  7. // ALGO D'OFFENSIVE
  8.  
  9. for (i=0; i<COLONNES; i++) // vérif verticale
  10. {
  11. for (j=0; j<LIGNES-3; j++)
  12. {
  13. if (matrice[i][j] == matrice[i][j+1] && matrice[i][j+1] == matrice[i][j+2] && matrice[i][j+2] == 'O' && c[i] == j+3)
  14. {
  15. coup = 1;
  16. matrice[i][j+3] = 'O';
  17. c[i]+=1;
  18. if (c[i] > 7) {c[i] = -1;}
  19. break;
  20. }
  21. }
  22. }
  23.  
  24. if (coup == 0)
  25. {
  26. for (j=0; j<LIGNES; j++) // vérif horizontale
  27. {
  28. for (i=0; i<COLONNES-3; i++)
  29. {
  30. if (matrice[i][j] == matrice[i+1][j] && matrice[i+1][j] == matrice[i+2][j] && matrice[i+2][j] == 'O' && c[i+3] == j)
  31. {
  32. coup = 1;
  33. matrice[i+3][j] = 'O';
  34. c[i+3]+=1;
  35. if (c[i+3] > 7) {c[i+3] = -1;}
  36. break;
  37. }
  38. if (coup == 0)
  39. {
  40. if (matrice[i][j] == matrice[i+2][j] && matrice[i+2][j] == matrice[i+3][j] && matrice[i+3][j] == 'O' && c[i+1] == j)
  41. {
  42. coup = 1;
  43. matrice[i+1][j] = 'O';
  44. c[i+1]+=1;
  45. if (c[i+1] > 7) {c[i+1] = -1;}
  46. }
  47. }
  48. if (coup == 0)
  49. {
  50. if (matrice[i][j] == matrice[i+1][j] && matrice[i+1][j] == matrice[i+3][j] && matrice[i+3][j] == 'O' && c[i+2] == j)
  51. {
  52. coup = 1;
  53. matrice[i+2][j] = 'O';
  54. c[i+2]+=1;
  55. if (c[i+2] > 7) {c[i+2] = -1;}
  56. }
  57. }
  58. if (coup == 0)
  59. {
  60. if (matrice[i+1][j] == matrice[i+2][j] && matrice[i+2][j] == matrice[i+3][j] && matrice[i+3][j] == 'O' && c[i] == j)
  61. {
  62. coup = 1;
  63. matrice[i][j] = 'O';
  64. c[i]+=1;
  65. if (c[i] > 7) {c[i] = -1;}
  66. }
  67. }
  68. }
  69. }
  70. }
  71.  
  72. if (coup == 0) // vérif oblique de gauche à droite
  73. {
  74. for (i=0; i<COLONNES-3; i++)
  75. {
  76. for (j=0; j<LIGNES-3; j++)
  77. {
  78. if (matrice[i][j] == matrice[i+1][j+1] && matrice[i+1][j+1] == matrice[i+2][j+2] && matrice[i+2][j+2] == 'O' && c[i+3] == j+3)
  79. {
  80. coup = 1;
  81. matrice[i+3][j+3] = 'O';
  82. c[i+3]+=1;
  83. if (c[i+3] > 7) {c[i+3] = -1;}
  84. break;
  85. }
  86. if (coup == 0)
  87. {
  88. if (matrice[i][j] == matrice[i+2][j+2] && matrice[i+2][j+2] == matrice[i+3][j+3] && matrice[i+3][j+3] == 'O' && c[i+1] == j+1)
  89. {
  90. coup = 1;
  91. matrice[i+1][j+1] = 'O';
  92. c[i+1]+=1;
  93. if (c[i+1] > 7) {c[i+1] = -1;}
  94. break;
  95. }
  96. }
  97. if (coup == 0)
  98. {
  99. if (matrice[i][j] == matrice[i+1][j+1] && matrice[i+1][j+1] == matrice[i+3][j+3] && matrice[i+3][j+3] == 'O' && c[i+2] == j+2)
  100. {
  101. coup = 1;
  102. matrice[i+2][j+2] = 'O';
  103. c[i+2]+=1;
  104. if (c[i+2] > 7) {c[i+2] = -1;}
  105. break;
  106. }
  107. }
  108. if (coup == 0)
  109. {
  110. if (matrice[i+1][j+1] == matrice[i+2][j+2] && matrice[i+2][j+2] == matrice[i+3][j+3] && matrice[i+3][j+3] == 'O' && c[i] == j)
  111. {
  112. coup = 1;
  113. matrice[i][j] = 'O';
  114. c[i]+=1;
  115. if (c[i] > 7) {c[i] = -1;}
  116. break;
  117. }
  118. }
  119. }
  120. }
  121. }
  122. if (coup == 0) // vérif oblique de droite à gauche
  123. {
  124. for (i=COLONNES-1; i>COLONNES-6; i--)
  125. {
  126. for (j=0; j<COLONNES-3; j++)
  127. {
  128. if (matrice[i][j] == matrice[i-1][j+1] && matrice[i-1][j+1] == matrice[i-2][j+2] && matrice[i-2][j+2] == 'O' && c[i-3] == j+3)
  129. {
  130. coup = 1;
  131. matrice[i-3][j+3] = 'O';
  132. c[i-3]+=1;
  133. if (c[i-3] > 7) {c[i-3] = -1;}
  134. break;
  135. }
  136. if (coup == 0)
  137. {
  138. if (matrice[i][j] == matrice[i-2][j+2] && matrice[i-2][j+2] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'O' && c[i-1] == j+1)
  139. {
  140. coup = 1;
  141. matrice[i-1][j+1] = 'O';
  142. c[i-1]+=1;
  143. if (c[i-1] > 7) {c[i-1] = -1;}
  144. break;
  145. }
  146. }
  147. if (coup == 0)
  148. {
  149. if (matrice[i][j] == matrice[i-1][j+1] && matrice[i-1][j+1] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'O' && c[i-2] == j+2)
  150. {
  151. coup = 1;
  152. matrice[i-2][j+2] = 'O';
  153. c[i-2]+=1;
  154. if (c[i-2] > 7) {c[i-2] = -1;}
  155. break;
  156. }
  157. }
  158. if (coup == 0)
  159. {
  160. if (matrice[i-1][j+1] == matrice[i-2][j+2] && matrice[i-2][j+2] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'O' && c[i] == j)
  161. {
  162. coup = 1;
  163. matrice[i][j] = 'O';
  164. c[i]+=1;
  165. if (c[i] > 7) {c[i] = -1;}
  166. break;
  167. }
  168. }
  169. }
  170. }
  171. }
  172.  
  173. //// ALGO DE DEFENSIVE
  174. if (coup == 0)
  175. {
  176. for (i=0; i<COLONNES; i++) // vérif verticale
  177. {
  178. for (j=0; j<LIGNES-3; j++)
  179. {
  180. if (matrice[i][j] == matrice[i][j+1] && matrice[i][j+1] == matrice[i][j+2] && matrice[i][j+2] == 'X' && c[i] == j+3)
  181. {
  182. coup = 1;
  183. matrice[i][j+3] = 'O';
  184. c[i]+=1;
  185. if (c[i] > 7) {c[i] = -1;}
  186. break;
  187. }
  188. }
  189. }
  190. }
  191. if (coup == 0)
  192. {
  193. for (j=0; j<LIGNES; j++) // vérif horizontale
  194. {
  195. for (i=0; i<COLONNES-3; i++)
  196. {
  197. if (matrice[i][j] == matrice[i+1][j] && matrice[i+1][j] == matrice[i+2][j] && matrice[i+2][j] == 'X' && c[i+3] == j)
  198. {
  199. coup = 1;
  200. matrice[i+3][j] = 'O';
  201. c[i+3]+=1;
  202. if (c[i+3] > 7) {c[i+3] = -1;}
  203. break;
  204. }
  205. if (coup == 0)
  206. {
  207. if (matrice[i][j] == matrice[i+2][j] && matrice[i+2][j] == matrice[i+3][j] && matrice[i+3][j] == 'X' && c[i+1] == j)
  208. {
  209. coup = 1;
  210. matrice[i+1][j] = 'O';
  211. c[i+1]+=1;
  212. if (c[i+1] > 7) {c[i+1] = -1;}
  213. }
  214. }
  215. if (coup == 0)
  216. {
  217. if (matrice[i][j] == matrice[i+1][j] && matrice[i+1][j] == matrice[i+3][j] && matrice[i+3][j] == 'X' && c[i+2] == j)
  218. {
  219. coup = 1;
  220. matrice[i+2][j] = 'O';
  221. c[i+2]+=1;
  222. if (c[i+2] > 7) {c[i+2] = -1;}
  223. }
  224. }
  225. if (coup == 0)
  226. {
  227. if (matrice[i+1][j] == matrice[i+2][j] && matrice[i+2][j] == matrice[i+3][j] && matrice[i+3][j] == 'X' && c[i] == j)
  228. {
  229. coup = 1;
  230. matrice[i][j] = 'O';
  231. c[i]+=1;
  232. if (c[i] > 7) {c[i] = -1;}
  233. }
  234. }
  235. }
  236. }
  237. }
  238.  
  239. if (coup == 0) // vérif oblique de gauche à droite
  240. {
  241. for (i=0; i<COLONNES-3; i++)
  242. {
  243. for (j=0; j<LIGNES-3; j++)
  244. {
  245. if (matrice[i][j] == matrice[i+1][j+1] && matrice[i+1][j+1] == matrice[i+2][j+2] && matrice[i+2][j+2] == 'X' && c[i+3] == j+3)
  246. {
  247. coup = 1;
  248. matrice[i+3][j+3] = 'O';
  249. c[i+3]+=1;
  250. if (c[i+3] > 7) {c[i+3] = -1;}
  251. break;
  252. }
  253. if (coup == 0)
  254. {
  255. if (matrice[i][j] == matrice[i+2][j+2] && matrice[i+2][j+2] == matrice[i+3][j+3] && matrice[i+3][j+3] == 'X' && c[i+1] == j+1)
  256. {
  257. coup = 1;
  258. matrice[i+1][j+1] = 'O';
  259. c[i+1]+=1;
  260. if (c[i+1] > 7) {c[i+1] = -1;}
  261. break;
  262. }
  263. }
  264. if (coup == 0)
  265. {
  266. if (matrice[i][j] == matrice[i+1][j+1] && matrice[i+1][j+1] == matrice[i+3][j+3] && matrice[i+3][j+3] == 'X' && c[i+2] == j+2)
  267. {
  268. coup = 1;
  269. matrice[i+2][j+2] = 'O';
  270. c[i+2]+=1;
  271. if (c[i+2] > 7) {c[i+2] = -1;}
  272. break;
  273. }
  274. }
  275. if (coup == 0)
  276. {
  277. if (matrice[i+1][j+1] == matrice[i+2][j+2] && matrice[i+2][j+2] == matrice[i+3][j+3] && matrice[i+3][j+3] == 'X' && c[i] == j)
  278. {
  279. coup = 1;
  280. matrice[i][j] = 'O';
  281. c[i]+=1;
  282. if (c[i] > 7) {c[i] = -1;}
  283. break;
  284. }
  285. }
  286. }
  287. }
  288. }
  289. if (coup == 0) // vérif oblique de droite à gauche
  290. {
  291. for (i=COLONNES-1; i>COLONNES-6; i--)
  292. {
  293. for (j=0; j<COLONNES-3; j++)
  294. {
  295. if (matrice[i][j] == matrice[i-1][j+1] && matrice[i-1][j+1] == matrice[i-2][j+2] && matrice[i-2][j+2] == 'X' && c[i-3] == j+3)
  296. {
  297. coup = 1;
  298. matrice[i-3][j+3] = 'O';
  299. c[i-3]+=1;
  300. if (c[i-3] > 7) {c[i-3] = -1;}
  301. break;
  302. }
  303. if (coup == 0)
  304. {
  305. if (matrice[i][j] == matrice[i-2][j+2] && matrice[i-2][j+2] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'X' && c[i-1] == j+1)
  306. {
  307. coup = 1;
  308. matrice[i-1][j+1] = 'O';
  309. c[i-1]+=1;
  310. if (c[i-1] > 7) {c[i-1] = -1;}
  311. break;
  312. }
  313. }
  314. if (coup == 0)
  315. {
  316. if (matrice[i][j] == matrice[i-1][j+1] && matrice[i-1][j+1] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'X' && c[i-2] == j+2)
  317. {
  318. coup = 1;
  319. matrice[i-2][j+2] = 'O';
  320. c[i-2]+=1;
  321. if (c[i-2] > 7) {c[i-2] = -1;}
  322. break;
  323. }
  324. }
  325. if (coup == 0)
  326. {
  327. if (matrice[i-1][j+1] == matrice[i-2][j+2] && matrice[i-2][j+2] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'X' && c[i] == j)
  328. {
  329. coup = 1;
  330. matrice[i][j] = 'O';
  331. c[i]+=1;
  332. if (c[i] > 7) {c[i] = -1;}
  333. break;
  334. }
  335. }
  336. }
  337. }
  338. }
  339.  
  340.  
  341. //// RANDOM si coup est toujours à 0
  342. if (coup == 0)
  343. {
  344. do
  345. {
  346. coup = (rand() % ((COLONNES-1) - 0 + 1)) + 0;
  347.  
  348. } while (c[coup] == -1);
  349. matrice[coup][c[coup]] = 'O';
  350. c[coup]+=1;
  351. if (c[coup] > 7) {c[coup] = -1;}
  352.  
  353. }
  354.  
  355. }


Il y a donc d'abord l'attaque (si on en a 3, on met le 4e), ensuite la défensive (si pas d'offensive possible), et enfin le random si on ne voit rien de spécial..
Le problème dans mon code est que .. si par exemple j'ai trois croix à côté horizontalement au milieu du puissance 4 comme ici :




L'ordi va boucher les deux coins ! c'est à dire jouer deux fois, alors que normalement je gagne.
Je pense que le problème se situe lorsque je fais des conditions dans mes boucles (voir le code).
note : le signe 'O' est celui du pC, 'X' celui du joueur !

Quelqu'un pourrait-il m'aider s'il vous plaît ? :pt1cable: 

Merci..

Autres pages sur : projet puissance expansion retardee

25 Décembre 2009 19:18:23

Bonjour,

Je n'ai pas lu tout le code (merci les commentaires ^^), donc désolé si je me trompe, mais ça ne serait pas du à un pépin dans tes boucles, notamment avec l'instruction "break" ?

Exemple: Lignes 26 à 36
Une fois que les 3 X sont trouvés, il met la variable "coup" à 1, puis il fait son break, donc sortie de la boucle:
ligne 28
  1. for (i=0; i<COLONNES-3; i++)

,puis ça reprend à ce niveau, ligne 26
  1. for (j=0; j<LIGNES; j++)

Donc nouvelle vérification, puis nouveau coup possible.

Je ne sais pas si tu as appliqué le même raisonnement ailleurs, donc si c'est ça, à corriger.
m
0
l
25 Décembre 2009 20:52:43

Hello,

Pour expliquer vite fait le code :

Vérif verticale : Une seule boucle. Si trois alignés, on met le 4e.

Horizontale : Plusieurs boucles, car les trois peuvent être alignés (ou pas), avec un trou.

Oblique : Pareil. et en plus il faut balayer le p4 dans deux sens.

Enfin, je peux me tromper..

Sinon, tu as bien raison.
En fait j'ai juste rallongé un peu le code en rajoutant des if (coup == 0) devant chaque vérification ou je ne l'avais pas fait, et maintenant ça marche bien :) 

Cependant, je trouve mon code vraiment très long, je ne sais pas s'il y a moyen de le raccourcir, mais merci du coup de main quand même ;) 
m
0
l
Contenus similaires
26 Décembre 2009 22:29:25

Re,
Pour raccourcir... et bien avec des fonctions, tu as souvent ce genre d'instructions qui se répètent:

  1. if (coup == 0)
  2. {
  3. if (matrice[i-1][j+1] == matrice[i-2][j+2] && matrice[i-2][j+2] == matrice[i-3][j+3] && matrice[i-3][j+3] == 'X' && c[i] == j)
  4. {
  5. coup = 1;
  6. matrice[i][j] = 'O';
  7. c[i]+=1;
  8. if (c[i] > 7) {c[i] = -1;}
  9. break;
  10. }
  11. }


Tu peux faire un truc de ce genre (à adapter suivant les lignes, pointeurs...):

  1. void controle(int k, int l, int m, char *pion, int *coup, int *c[TAILLE_C], int *matrice[TAILLE_1][TAILLE_2])
  2. {
  3. if (*coup == 0)
  4. {
  5. if (*matrice[i-k][j+k] == *matrice[i-l][j+l] && *matrice[i-l][j+l] == *matrice[i-m][j+m] && *matrice[i-m][j+m] == *pion && *c[i] == j)
  6. {
  7. *coup = 1;
  8. //Inversion du symbole
  9. *pion = (*pion=='O') ? 'X' : 'O';
  10. *matrice[i][j] = 'O';
  11. *c[i]+=1;
  12. if (*c[i] > 7) {*c[i] = -1;}
  13. break;
  14. }
  15. }
  16. }


Ensuite, tu n'auras plus qu'à faire ça par exemple:
  1. controle(1, 2, 3, adr_pion, adr_coup, adr_c, adr_matrice);

PS: Il se peut que je me suis planté dans le code, enfin c'est juste l'idée que je veux faire passer :) 

A+
m
0
l
27 Décembre 2009 10:06:58

Plop,

Merci pour l'idée, en fait, j'ai retourné coup en char et je l'avais envoyé à la fonction ASK qui se chargeait normalement de remplir le puissance 4 :


  1. int Ask (char colonne, int c[], int who_is)
  2. {
  3. char signe;
  4. int error = 0;
  5.  
  6. if (who_is == 0) {signe = 'X';} else {signe = 'O';}
  7.  
  8. if (colonne < 49 || colonne > 56)
  9. {
  10. error = 1;
  11. }
  12. if (error == 0)
  13. {
  14. if (c[colonne-49] != -1) // 49 = '1'
  15. {
  16. matrice[colonne-49][c[colonne-49]] = signe;
  17. c[colonne-49]+=1;
  18. if (c[colonne-49] > 7) {c[colonne-49] = -1;}
  19. } else {error = 1;}
  20. }
  21. return error;
  22. }


En revanche, passer la matrice à deux dimensions à une fonction m'avait posé problème (donc j'ai mis le P4 en variable globale).

Pour un simple tableau, je comprends qu'on peut mettre dans l'appel tableau ou &tableau[0] et *tableau ou tableau[] dans la fonction en elle-même.
Mais pour plus de dimensions, je n'ai pas vraiment compris.

Merci =)
m
0
l
a b L Programmation
29 Décembre 2009 20:06:37

Bon, comme ton problème semble se résoudre, je vais un peu te parler de la base de l'IA.

Sinon, pour faire une intelligence artificielle un peu plus élaborée, il te faut voir toutes les possibilités (IA et joueurs). ça va te faire un arbre dont le premier niveau est le pion de l'IA, le second le pion du joueur, le 3ème le pion de l'IA, etc.
Comme tu as 8 colonnes, donc 8 possibilités à chaque fois, chaque branche de ton arbre se divisera en 8 branches dans le niveau suivant.
Tu arrêtes les branches lorsque c'est la victoire du joueur ou de l'IA.
Le principe est simplement de scanner l'arbre pour trouver les branches qui permettent de gagner.
En supposant que tu génères l'arbre complet avec les arrêts de branches (l'arbre est très grand ;)  ), tu cherches à faire gagner l'IA, donc tu regardes tous les chemins qui permettent d'aller à la victoire, et tu peux comptabiliser un score qui augmente suivant le nombre de victoires liées à des sous-branches et diminue suivant la possibilités de branches de défaites de l'IA. Tu cherches donc juste à savoir le chemin victoireux qui a le plus grand score.
Comme l'arbre est exponentiel (x8 à chaque niveaux sans compter les arrêts), c'est impossible de tout prévoir, car le calcul serait trop long. Donc, il faut se limiter à un certain niveau (par exemple 5: IA-Joueur-IA-Joueur-IA).
Pour l'algo, tu peux t'inspirer de l'algorithme de Djikstra.

La qualité de ton IA dépendra donc:
- du meilleur calcul des scores des chemins
- de la profondeur maximale de l'arbre (qui fait ralentir exponentiellement l'algo)

Donc, en gros, c'est peu ce que tu commences à faire, mais il faut prévoir des niveaux supplémentaires grâce à une structure d'arbre.
m
0
l
30 Décembre 2009 14:38:43

Hello,

Ah, j'avais déjà entendu parler de Dijkstra en mathématiques =)

ça a l'air assez compliqué quand même :p 

pour le jeu, j'ai juste fait des boucles en faisant un coup à l'avance, et deux coups à l'avance. Avec d'abord l'offensif et le défensif après à chaque fois, en finissant par un random si rien trouvé..

Il suffit souvent de pousser l'IA à l'erreur pour gagner, ce qui montre que mon truc n'est effectivement pas une IA =D
m
0
l
a b L Programmation
30 Décembre 2009 17:36:58

Si, c'est une IA à un seul niveau.
Sans passer par un arbre explicitement, tu peux mieux sélectionner ton random. Dans le cas du random, tu fais 3 listes pour les 8 possibilités:
- 1ère liste: contient les colonnes qui permettent au joueur d'appliquer la technique offensive
- 2ème liste: contient les colonnes qui permettent au joueur d'appliquer la technique défensive
- 3ème liste: le reste
Après, tu peux faire un random dans la liste 2 (si le joueur doit defendre, c'est bon pour l'IA), et si vide, random dans la liste 3 et si vide random dans la liste 1 (défaite assurée si le joueur a vu le coup gagnant).
En fait, ça revient à l'arbre sur 2 niveaux.
m
0
l
30 Décembre 2009 18:50:06

Mouarf :p 

J'ai fait :

- Si IA a 3 jetons à proximité (diag, vert, ou hor), on met le 4e.
- Si le joueur ***********************, on met le 4e.
- Pareil mais à partir de deux jetons pour l'offensif et le défensif.
- et random

Les seuls trucs un peu bêtes, c'est que desfois il complète deux jetons par un 3e (alors que de toute façon, il ne peut pas y en avoir 4), mais bon mon code est déjà très long :) 

Exe sous Windows : http://www.sendspace.com/file/zfxy64
Code source à compiler sous Linux avec : gcc main.c -DLINUX -o P4 : http://www.sendspace.com/file/um0v29

Si tu as envie de tester =D
m
0
l
a b L Programmation
30 Décembre 2009 19:42:01

Je pense que tu ne devrais pas faire aligner les 3 jetons parce que ça signifie que tu prévoit une victoire à 2 coups, et donc, il te faut 2 niveaux dans ton IA.
A la limite tu peux faire un random pondéré sur les alignements de jetons, comme ça, l'IA est plus difficile à piéger.
m
0
l
30 Décembre 2009 20:09:41

Un random pondéré ?
m
0
l
a b L Programmation
30 Décembre 2009 20:32:38

Par exemple, pour chaque colonne, tu mets un score de 1 si le jeton je touche aucun autre jeton, 3 si ça aligne 2 jetons et de 5 si ça aligne 3 jetons.
tu fais un tableau, ex: {1,1,3,1,5,5,1,3} => total = 20
Tu modifie le taleau pour faire en sorte j'ajoute les scores précédent pour faire les intervalles du random: {1,2,5,6,11,16,17,20}
Tu prends un random sur 20 qui te permet de trouver la colonne choisie.
m
0
l
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS