[C] Saisie clavier

Salut a tous !!

Je suis entrain d’implementer un othello avec IA en C.
Je n’en ai fais qu’a la fac et malheureusement je manque un peu de pratique sur les I/O;
Alors j’aimerais savoir comment faire pour que demander a lutilisateur de tapper un coup ( a 1 ou b 2 ou … jusqua … h 8 ou z 0 ) ?
Sachant que faut pas que ca plante meme si il met un espace ou un entrer etc…
En gros redemander jusqu’a que la saisie soit bonne sans pouvoir faire planter le truc.

Je suis sous gcc, gets est “depreciated” et scanf("%s",…) plante si insertion d’un espace.
Je peux paraitre exigent de prime abord mais j’arrive a le faire en tapant d’abort
a-h ou z puis 0-8 mais pour epater la gallerie, si un dieux du C savait faire ca
en utilisant directement la convention de representation des coups imposer par notre chargé de td(et inspiré du reglement officiel de la FFO !) ca roxerai les loutres :stuck_out_tongue:

Help

Cordialement

Et pour inserer ou debut d’un fichier une ligne comment kon feR? lecture puis reecriture? :stuck_out_tongue:

“En gros redemander jusqu’a que la saisie soit bonne sans pouvoir faire planter le truc.”
Il y a le :[cpp]do {
blabla
blabla
}
while(condition pour la répétition, ie : saisie == ’ ');[/cpp]

oui, la boucle de _Raynor fera l’affaire, en pseudo code ca donnerais :

int ok = FALSE;
do {
touche = saisie();
for (int i = 0; i < NOMBRE_TOUCHES_RECONNUS; i++)
{
si touche = tableau_touche[i];
ok = TRUE;
}
} while (ok == FALSE);

En gros, tu te fais un tableau des touches que tu veux gérer, tu récupère la saisie, tu fais une boucle qui vérifie que si la saisie correspond à une touche de ce tableau, alors le coup peut être joué et donc la condition est vérifiée.

utilise getchar(), et au fait, TRUE / FALSE c’est pas du C Ansi :slight_smile: Sinon tu as fgets que tu feras intelligemment sur stdin qui fera ce que tu veux. Ex:

char buffer[1024];
fgets( stdin, buffer, 1024 );

Y a plus qu’à parcourir le tableau

Je ne fais pas partie de ceux qui passent leur temps sur des considérations philosphiques en ce qui concerne les normes … TRUE/FALSE ANSI ou pas, n’a jamais été un soucis dans la compréhension du code ni dans la portabilité, donc …

vi vi :o mais je crois qu’il est en Fac, et que justement on lui demandera du C Ansi :o

je pensais qu en C on pouvais appeler une fonction (fscanf ?)
ou tu definissais le format et apres si le mec tape 1 2 alors que j’ai spécifier %1c %1i alors il recommence, en tout cas il beug pas en te sortaant plein de truc sur stdout

ca marche pas top (je tape d2 et appui sur entré je dois retaper un truc genre 8, apres ca affiche bien 3 1, c a d les coordonnées converti, et le 8 il est pas pris en compte, mais pkoi il veut que je tappe ce 8 ou 2 alors que le format est respecté??)

[cpp]
void saisiUnCoup(char camp, int * NumLigne, int * NumColonne)
{
char stamp;

printf(“Veuillez entrez un coup joueur %c puis appuyer sur Entrée:\n”,camp);
scanf("%1c%1d\n",&stamp,NumLigne);

(*NumLigne)-=1;
*NumColonne=stamp-‘a’;

printf(“val ligne:%i\n”,*NumLigne);
printf(“val colonne:%i\n”,*NumColonne);

}
[/cpp]

sinon Comment inséré 1 ligne au debut d’un fichier, sans ecraser ce qui existait?

scanf est assez casse couille à utiliser, essaye le format %c %d

(au passage, %c c’est forcément un caractère, pas deux)

Tu peux tenter fgets + strtol (genre: est ce que j’ai un isnum() et si oui, strtol) pour avoir les choses correctement.

Merci S-N !!!
[cpp]
void saisiUnCoup(char camp, int * NumLigne, int * NumColonne)
{
char tmp[4];

printf(“Veuillez entrez un coup joueur %c puis appuyer sur Entrée:\n”,
camp);

fgets(tmp, sizeof tmp, stdin);

*NumLigne=atoi(tmp[2]);
*NumColonne=tmp[0]-‘a’;

//printf("C:%c ",cChaine[0]);
//printf(“L:%c\n”,cChaine[2]);

printf(“val ligne:%i\n”,*NumLigne);
printf(“val colonne:%i\n”,*NumColonne);

}

[/cpp]

Ca converti bien a en 0, b en 1, c en 2 mais pour le chiffre strol a pas l’air de marcher, avec strtol ou atoi, je suis pret du but ! :stuck_out_tongue:
Bien sur je pars du principe que tout est bien taper, apres je ferais un while avec verifications

Voila comme ca c parfait, je rajouterais le while pour les verifications (je connaissais l’algo Raynor et Karlkox, mais ca peut aider un prochain lecteur :jap:), merci a tous pour vos reponses
[cpp]
char tmp[4];

printf(“Veuillez entrez un coup joueur %c puis appuyer sur Entrée:\n”,
camp);

fgets(tmp, sizeof tmp, stdin);

*NumLigne=tmp[2]-‘0’-1;
*NumColonne=tmp[0]-‘a’;

printf(“val ligne:%i\n”,*NumLigne);
printf(“val colonne:%i\n”,*NumColonne);

[/cpp]

Voila je pense que c portable, et AINSI.

S-N a raison, je suis a la FAC, mais y’a que moi la bas j’ai l’impression qui respecte le AINSI !
Le C faut etre precis dans ce que l’on fait, une erreur meme toute petite ne pardonne pas (une * au lieu d’un &, sorti de tableaux et j en passe), autant savoir ce que fait exactement le C pour ne pas avoir de surprise.
Pour true et false, je l’ai est tjrs considerer comme des int.

Cordialement

Au passage en C si je prog avec GCC sous Linux avec du code portable esqu il marche sous win comme ca?
Sachant que c un othello en printf et fgets?
Edit: ou je dois le recompiler sous win avec Dev-c++ par exemple?

Tu peux le recompiler directement si tu as le Makefile et les binutils/automake win32.

??? c koin je fait un make file mais il utilise gcc, qui nest pas sous win non?

Disons que le mieux c de compile sous win ?

gcc existe sous windows et sur de nombreuses autres plateformes, tu peux avoir le même environnement de développement sous windows que sous Linux via Cygwin ou Mingw32.
Le plus simple reste, comme tu l’as dit, d’utiliser DevC++ qui simplifie grandement la tâche :slight_smile:

Je compile facilement des projets fait sous Win à la Fac (qui est sous Linux). Sinon pour ton prog il est pas très clair quand même.

Il se passe quoi si on rentre autre chose que a-z 0-9 ? faut vérifier tes données…

je verifie pas les coordonnées dans cette fonction mais dans l’appelante.
c’est plus simple car il y a bcp de test avant de valider un coup puisqu a othello on ne peut poser de pions que si l’on prend quelquechose…

mais la le mode “Superviseur” à l’air de fonctionner, il ne manque plus que les fonctions de sauvegardes dans un fichier. si au passage quelqun sais comment inserer une ligne en tete de fichier sans rien ecraser ca serai cool ^^.
Je poste pas l integralité de mon code tout de suite, le projet va evoluer en une implementation d’un IA qui joue a othello grace a min-max et alpha-beeta.
Si ca interesse les clubiciens jpourrais faire un topic dessus une fois que mon compte rendu sera fait
Cordialement

[cpp]
void moteur(char * grille, char camp)
{
int testL;
int testC;

if(!existeCoupPourCamp(grille,camp))
{
printf(“Vous devez passer %c ! :frowning: \nAppuyer sur une touche pour continuer\n”,toupper(camp));
char c;
c=getchar();
return;
}
else
{

  do 
  {
     testL=DIMENSION_MAX;
     testC=DIMENSION_MAX;

     //printf("avant appel L:%i, C:%i\n",testL,testC);

     saisiUnCoup(camp,&amp;testL,&amp;testC);

     //printf("apres appel L:%i, C:%i\n",testL,testC);

  

  } while( 
            (   ( testL > (DIMENSION_MAX-1) )
             || ( testC > (DIMENSION_MAX-1) )            
             || ( testL < 0 )   
             || ( testC < 0 ) 
            ) 
          || ( !coupValide(camp,grille,testL,testC) ) 
         );
     
    joueLeCoup(grille,testL,testC,camp);

}
}

[/cpp]

Non mais vérifier les coordonnées c’est beau, mais vérifier les données utilisateurs (ie: ton fgets) c’est mieux.

Il faut que tu stockes dans un buffer tout le contenu de ton fichier, que tu écris la première ligne dans un nouveau fichier et le contenu du buffer ensuite.