Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Morpion en C et SDL, besoin d'aide !

8 réponses
Avatar
Shady
Bonjour =E0 tous,

Je me suis lanc=E9 dans la programmation en C avec la libraire SDL pour=20
les graphismes.=20
Je tente de faire un jeu du type Morpion, dont vous connaissez=20
probablement le principe.

Seulement j'ai un probl=E8me.=20
Le morpion est affich=E9 (ses cases et la fenetre du jeu) mais lorsque je=
=20
clique sur les cases, il ne se passe rien (le cercle n'apparait pas,=20
signe que la case est coch=E9e, elle reste vide) alors que j'ai=20
l'impression d'avoir tout bien fait.=20
Comme si les clics de la souris n'=E9taient pas pris en compte alors que=20
j'ai fait ca bien (^^).

Voici mon code :

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>

// Surfaces et rectangle
SDL_Rect rect, rect2, rect3, rect4, rect5, rect6, rect7, rect8, rect9;
SDL_Surface *Screen, *vide, *rond, *croix;

int cochecase[10]=3D{0,0,0,0,0,0,0,0,0};
int MouseX;
int MouseY;

SDL_Event event;


int main (int argc, char **argv)
{
SDL_Init (SDL_INIT_VIDEO);
Screen =3D SDL_SetVideoMode (300, 300, 32, SDL_SWSURFACE|=20
SDL_DOUBLEBUF);
SDL_WM_SetCaption ("Morpion !", NULL);




void affichage()
{
SDL_FillRect(Screen, NULL, 0);
=20
rect2.x =3D (Screen->w / 3);
rect2.y =3D (Screen->h / 3)- (rect.w);
=20
rect3.x =3D (Screen->w / 3)+ (rect.h);
rect3.y =3D (Screen->h / 3)- (rect.w);
=20
rect4.x =3D (Screen->w / 3)- (rect.h);
rect4.y =3D (Screen->h / 3);
=20
rect5.x =3D (Screen->w / 3);
rect5.y =3D (Screen->h / 3);
=20
rect6.x =3D (Screen->w / 3) + (rect.h);
rect6.y =3D (Screen->h / 3);
=20
rect7.x =3D (Screen->w / 3) - (rect.h);
rect7.y =3D (Screen->h / 3)+ (rect.w);
=20
rect8.x =3D (Screen->w / 3);
rect8.y =3D (Screen->h / 3)+ (rect.w);
=20
rect9.x =3D (Screen->w / 3) + (rect.h);
rect9.y =3D (Screen->h / 3) + (rect.w);


vide=3DSDL_LoadBMP("vide.bmp");
rond=3DSDL_LoadBMP("cercle.bmp");
croix=3DSDL_LoadBMP("croix.bmp");

if(cochecase[1]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect);
if(cochecase[1]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect);
if(cochecase[1]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect);
=20
if(cochecase[2]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect2);
if(cochecase[2]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect2);
if(cochecase[2]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect2);

if(cochecase[3]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect3);
if(cochecase[3]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect3);
if(cochecase[3]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect3);

/*case 4*/
if(cochecase[4]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect4);
if(cochecase[4]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect4);
if(cochecase[4]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect4);

if(cochecase[5]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect5);
if(cochecase[5]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect5);
if(cochecase[5]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect5);

if(cochecase[6]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect6);
if(cochecase[6]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect6);
if(cochecase[6]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect6);

/*case 7*/
if(cochecase[7]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect7);
if(cochecase[7]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect7);
if(cochecase[7]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect7);

if(cochecase[8]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect8);
if(cochecase[8]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect8);
if(cochecase[8]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect8);

if(cochecase[9]=3D=3D0)
SDL_BlitSurface(vide,NULL,Screen,&rect9);
if(cochecase[9]=3D=3D1)
SDL_BlitSurface(rond,NULL,Screen,&rect9);
if(cochecase[9]=3D=3D2)
SDL_BlitSurface(croix,NULL,Screen,&rect9);

SDL_Flip(Screen);
}



void getMousePosition(void)
{
SDL_PumpEvents();

SDL_GetMouseState(&MouseX, &MouseY);

MouseX=3Devent.motion.x;
MouseY=3Devent.motion.y;
return;
}

while (1)
{
if (SDL_PollEvent (&event) && event.type=3D=3DSDL_QUIT)
break;
=20
switch(event.type)
{=20
case SDL_MOUSEBUTTONDOWN:
=20
if ((event.button.x < 100) && (event.button.y < 100))=20
{
cochecase[1]=3D=3D1;
}
=20
if ((event.button.x < 100) && (event.button.y > 200))=20
{ =20
cochecase[7]=3D=3D1;
}
=20
if ((event.button.x < 100) && (event.button.y < 200) &&=20
(event.button.y >100))=20
{=20
cochecase[4]=3D=3D1;
}
=20
if ((event.button.x > 100) && (event.button.x < 200) &&=20
(event.button.y < 200) && (event.button.y >100))=20
{ =20
cochecase[5]=3D=3D0;
}
=20
if ((event.button.x > 100) && (event.button.x < 200) &&=20
(event.button.y < 100))=20
{
cochecase[2]=3D=3D0;
}
=20
if ((event.button.x > 100) && (event.button.x < 200) &&=20
(event.button.y > 200))=20
{
cochecase[8]=3D=3D0; =20
}
=20
if ((event.button.x > 200) && (event.button.y > 200))=20
{
=20
cochecase[9]=3D=3D0;
}

if ((event.button.x > 200) && (event.button.y < 100))=20
{
cochecase[3]=3D=3D0;
=20
}
=20
if ((event.button.x > 200) && (event.button.y > 100) &&=20
(event.button.y < 200))=20
{
cochecase[6]=3D=3D0; =20
=20
}
case SDL_MOUSEMOTION:
getMousePosition();
break;
}
=20
affichage();
}
SDL_FreeSurface(Screen);
SDL_FreeSurface(vide);
SDL_FreeSurface(rond);
SDL_FreeSurface(croix);
=20
=20
return 0;
}


Par ailleurs la variable "cochecase" sert =E0 informer le programme sur le=
=20
fait qu'une case soit coch=E9e ou non, ainsi on ne peut cocher deux fois=20
la m=EAme.=20
Enfin pour l'instant on ne peut rien cocher puisque ca ne fonctionne pas=20
^^
De plus, l'IA n'est pas encore programm=E9e.

Merci par avance pour votre pr=E9cieuse aide, et d=E9sol=E9 si mon texte=20
n'apparait pas bien mais c'est la premi=E8re fois que j'utilise les=20
Newsgroups et je m'y perds un peu dans les histoires d'encodage ...

Amicalement,
Joy.

8 réponses

Avatar
Vincent Burel
hello

primo, vous avez trop de code redondant, donc trop de possibilité d'erreur.
Secondo votre procedure de gestion souris n'est pas claire.

De manière générale quand on a un nombre "important" de choses similaire à
l'écran (comme vos cases de votre plateau de jeu), alors on sérialise tout.
Autrement dit on programme un objet "case" avec sa méthode d'affichage, ses
coordonnées courante, son status courant (vide, rond ou croix) sa fonction
qui dit si les coordonnée souris correspondent ou pas ... et l'algorithme de
votre programme devient plus simple, car plus court, et surtout moins
redondant.

A+
VB


"Shady" wrote in message
news:
Bonjour à tous,

Je me suis lancé dans la programmation en C avec la libraire SDL pour
les graphismes.
Je tente de faire un jeu du type Morpion, dont vous connaissez
probablement le principe.

Seulement j'ai un problème.
Le morpion est affiché (ses cases et la fenetre du jeu) mais lorsque je
clique sur les cases, il ne se passe rien (le cercle n'apparait pas,
signe que la case est cochée, elle reste vide) alors que j'ai
l'impression d'avoir tout bien fait.
Comme si les clics de la souris n'étaient pas pris en compte alors que
j'ai fait ca bien (^^).

Voici mon code :

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>

// Surfaces et rectangle
SDL_Rect rect, rect2, rect3, rect4, rect5, rect6, rect7, rect8, rect9;
SDL_Surface *Screen, *vide, *rond, *croix;

int cochecase[10]={0,0,0,0,0,0,0,0,0};
int MouseX;
int MouseY;

SDL_Event event;


int main (int argc, char **argv)
{
SDL_Init (SDL_INIT_VIDEO);
Screen = SDL_SetVideoMode (300, 300, 32, SDL_SWSURFACE|
SDL_DOUBLEBUF);
SDL_WM_SetCaption ("Morpion !", NULL);




void affichage()
{
SDL_FillRect(Screen, NULL, 0);

rect2.x = (Screen->w / 3);
rect2.y = (Screen->h / 3)- (rect.w);

rect3.x = (Screen->w / 3)+ (rect.h);
rect3.y = (Screen->h / 3)- (rect.w);

rect4.x = (Screen->w / 3)- (rect.h);
rect4.y = (Screen->h / 3);

rect5.x = (Screen->w / 3);
rect5.y = (Screen->h / 3);

rect6.x = (Screen->w / 3) + (rect.h);
rect6.y = (Screen->h / 3);

rect7.x = (Screen->w / 3) - (rect.h);
rect7.y = (Screen->h / 3)+ (rect.w);

rect8.x = (Screen->w / 3);
rect8.y = (Screen->h / 3)+ (rect.w);

rect9.x = (Screen->w / 3) + (rect.h);
rect9.y = (Screen->h / 3) + (rect.w);


vide=SDL_LoadBMP("vide.bmp");
rond=SDL_LoadBMP("cercle.bmp");
croix=SDL_LoadBMP("croix.bmp");

if(cochecase[1]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect);
if(cochecase[1]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect);
if(cochecase[1]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect);

if(cochecase[2]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect2);
if(cochecase[2]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect2);
if(cochecase[2]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect2);

if(cochecase[3]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect3);
if(cochecase[3]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect3);
if(cochecase[3]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect3);

/*case 4*/
if(cochecase[4]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect4);
if(cochecase[4]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect4);
if(cochecase[4]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect4);

if(cochecase[5]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect5);
if(cochecase[5]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect5);
if(cochecase[5]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect5);

if(cochecase[6]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect6);
if(cochecase[6]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect6);
if(cochecase[6]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect6);

/*case 7*/
if(cochecase[7]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect7);
if(cochecase[7]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect7);
if(cochecase[7]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect7);

if(cochecase[8]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect8);
if(cochecase[8]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect8);
if(cochecase[8]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect8);

if(cochecase[9]==0)
SDL_BlitSurface(vide,NULL,Screen,&rect9);
if(cochecase[9]==1)
SDL_BlitSurface(rond,NULL,Screen,&rect9);
if(cochecase[9]==2)
SDL_BlitSurface(croix,NULL,Screen,&rect9);

SDL_Flip(Screen);
}



void getMousePosition(void)
{
SDL_PumpEvents();

SDL_GetMouseState(&MouseX, &MouseY);

MouseX=event.motion.x;
MouseY=event.motion.y;
return;
}

while (1)
{
if (SDL_PollEvent (&event) && event.type==SDL_QUIT)
break;

switch(event.type)
{
case SDL_MOUSEBUTTONDOWN:

if ((event.button.x < 100) && (event.button.y < 100))
{
cochecase[1]==1;
}

if ((event.button.x < 100) && (event.button.y > 200))
{
cochecase[7]==1;
}

if ((event.button.x < 100) && (event.button.y < 200) &&
(event.button.y >100))
{
cochecase[4]==1;
}

if ((event.button.x > 100) && (event.button.x < 200) &&
(event.button.y < 200) && (event.button.y >100))
{
cochecase[5]==0;
}

if ((event.button.x > 100) && (event.button.x < 200) &&
(event.button.y < 100))
{
cochecase[2]==0;
}

if ((event.button.x > 100) && (event.button.x < 200) &&
(event.button.y > 200))
{
cochecase[8]==0;
}

if ((event.button.x > 200) && (event.button.y > 200))
{

cochecase[9]==0;
}

if ((event.button.x > 200) && (event.button.y < 100))
{
cochecase[3]==0;

}

if ((event.button.x > 200) && (event.button.y > 100) &&
(event.button.y < 200))
{
cochecase[6]==0;

}
case SDL_MOUSEMOTION:
getMousePosition();
break;
}

affichage();
}
SDL_FreeSurface(Screen);
SDL_FreeSurface(vide);
SDL_FreeSurface(rond);
SDL_FreeSurface(croix);


return 0;
}


Par ailleurs la variable "cochecase" sert à informer le programme sur le
fait qu'une case soit cochée ou non, ainsi on ne peut cocher deux fois
la même.
Enfin pour l'instant on ne peut rien cocher puisque ca ne fonctionne pas
^^
De plus, l'IA n'est pas encore programmée.

Merci par avance pour votre précieuse aide, et désolé si mon texte
n'apparait pas bien mais c'est la première fois que j'utilise les
Newsgroups et je m'y perds un peu dans les histoires d'encodage ...

Amicalement,
Joy.
Avatar
rm
Le mercredi 2 novembre 2005 à 20:37:47, Vincent Burel a écrit :

bonsoir,

et surtout moins
redondant.



en parlant de redondance, tu as cité, _sous_ ta réponse, l'intégralité des
250 lignes du message de Shady :-)

@+
--
rm
Avatar
Vincent Burel
"rm" wrote in message
news:14h2hhviz4lg3.rqkmnt1ze8vi$
Le mercredi 2 novembre 2005 à 20:37:47, Vincent Burel a écrit :

bonsoir,

> et surtout moins
> redondant.

en parlant de redondance, tu as cité, _sous_ ta réponse, l'intégralité des
250 lignes du message de Shady :-)



quand on répond sur le usenet, je crois qu'il faut garder la partie du
message de son interlocuteur concerné par la réponse :-)

VB
Avatar
florian.sinatra
Vincent Burel a écrit :
"rm" wrote in message
news:14h2hhviz4lg3.rqkmnt1ze8vi$

Le mercredi 2 novembre 2005 à 20:37:47, Vincent Burel a écrit :

bonsoir,


et surtout moins
redondant.



en parlant de redondance, tu as cité, _sous_ ta réponse, l'intégralité des
250 lignes du message de Shady :-)




quand on répond sur le usenet, je crois qu'il faut garder la partie du
message de son interlocuteur concerné par la réponse :-)

VB




Pas tout à fait : <http://www.giromini.org/usenet-fr/repondre.html>
Avatar
Vincent Burel
"florian.sinatra" wrote in message
news:4369ef90$
> Vincent Burel a écrit :
> quand on répond sur le usenet, je crois qu'il faut garder la partie du
> message de son interlocuteur concerné par la réponse :-)
>
> VB
>
>
Pas tout à fait : <http://www.giromini.org/usenet-fr/repondre.html>



Et oui, je connais un peu, avec le temps :-) Avec le temps tout s'en va,
sauf sur internet ou tout recommence éternellement...

Bref ! Notez que si je n'avais pas cité l'intégralité du message, certains
chipotteurs notoires auraient pu arguer que l'utilisation du mot "redondant"
n'était pas judicieux (n'ayant justement plus assez de redondance dans le
message original :-). Ce qui aurait généré quantité de messages inutiles.
Alors que là, seule une petite tribu de gens nouveau sur ce newsgroup, se
permettent d'être pointilleux à défaut d'être brillant dans d'autre domaine.
:-)

VB
Avatar
Arnold McDonald
Vincent Burel wrote:

Alors que là, seule une petite tribu
de gens nouveau sur ce newsgroup, se permettent d'être pointilleux à
défaut d'être brillant dans d'autre domaine. :-)



Je me disais aussi, il vieilli ou quoi ? Ben non :-).

--
Arnold McDonald (AMcD®)

http://arnold.mcdonald.free.fr/
Avatar
GG
Bonjour,

Je me disais aussi, il vieilli ou quoi ? Ben non :-).



Toi non plus, enfin heureusement que jour après jour
le temps passe. :-)
--
Cordialement.
GG.
Avatar
ByB
Si je n'étais pas venu sur ce forum le 02/11/2005, aurai-je su que
Shady avait dit que
Bonjour à tous,

Je me suis lancé dans la programmation en C avec la libraire SDL pour
les graphismes.
Je tente de faire un jeu du type Morpion, dont vous connaissez
probablement le principe.

Seulement j'ai un problème.
Le morpion est affiché (ses cases et la fenetre du jeu) mais lorsque je
clique sur les cases, il ne se passe rien (le cercle n'apparait pas,
signe que la case est cochée, elle reste vide) alors que j'ai
l'impression d'avoir tout bien fait.
Comme si les clics de la souris n'étaient pas pris en compte alors que
j'ai fait ca bien (^^).




a) Mettez en place un fichier de log (fichier texte) dans lequel vous
écrirez une info selon l'endroit du programme où vous passez. De cette
façon, vous vérifierez si, lorsque vous cliquez sur une case, votre
programme passe bien à tel ou tel endroit selon ce que vous avez
programmé. De cette façon, vous devriez pouvoir déterminer si le
programme se comporte comme vous l'avez prévu, et si non, pourquoi (ou
à partir de quel moment ça ne marche pas).

b) Une fois que vous avez mieux cerné le problème de cette façon,
concentrez vos recherches sur celui ci. Vérifiez les valeurs de vos
variables (que vous pouvez aussi écrire dans le fichier de log).

c) Comme le suggère Vincent Burel, simplifiez votre code, car vous ne
tirez pas suffisament parti des possibilités objet du C++

Bon courage.



--
LA FINALITE DYNAMISE LES RESULTATS THEMATIQUES DES BENEFICIAIRES