PDA

View Full Version : [C] gioco del Tris


Filly95
19-02-2012, 15:28
Salve a tutti, ho scritto un piccolo gioco del Tris in C, ma ho riscontrato questi problemi:
[RISOLTO] 1. Quando si prova a mettere una pedina su una casella occupata il numero dei turni non diminuisce (pur avendo messo count_turni--).
[RISOLTO]2. A fine partita non funziona la parte in cui si chiede se si vuole iniziare una nuova partita.
[RISOLTO] 3. In caso di parità non viene eseguito il printf relativo, penso che la variabile risultato non venga settata correttamente a 3 perché credo di aver sbagliato qualcosa nel controllo parità nella funzione check_vincita.
Per ora non mi viene altro in mente, ringrazio tutti in anticipo.
Il mio codice è questo: -.
Uso come editor NotePad++ e come compilatore Dev-C++.

EDIT: Ho risolto due problemi, mi manca l'ultimo, ma proprio non ne vengo a capo. Inoltre vorrei chiedervi se c'è qualche modo di snellire il codice, soprattutto nella funzione check_vincita. Pensavo che

if(schema[7] == schema[8] == schema[9] == 'X' || schema[4] == schema[5] == schema[6] == 'X' || schema[1] == schema[2] == schema[3] == 'X') r = 1;
...

ovvero delle eguaglianze multiple funzionasser, ma mi sono sbagliato.
Grazie ancora.

!fazz
20-02-2012, 09:46
le eguaglianze devi farle 2 a 2 ovvero cella1 ='X' && cella2=='X' ecc ecc

ma se vuoi snellire il codice puoi fare questo trucchetto

considera i char come intero (cast a int) somma i 3 valori e controlla se la somma vale 264 (per le X che corrispondono in intero a 88)

Stewino
20-02-2012, 10:04
Per riavviare ho provato a inserire nuova=getch(); invece di scanf("%c", &nuova); e funziona.
Ovviamente devi aggiungere la libreria conio.h.
Ho notato che dopo il riavvio rimangono le pedine della partita precedente.

Bel programma comunque :)

Filly95
20-02-2012, 10:47
le eguaglianze devi farle 2 a 2 ovvero cella1 ='X' && cella2=='X' ecc ecc

ma se vuoi snellire il codice puoi fare questo trucchetto

considera i char come intero (cast a int) somma i 3 valori e controlla se la somma vale 264 (per le X che corrispondono in intero a 88)
Considerando che è un esercizio di terza (che ho fatto per diletto però) e i cast non sono stati ancora affrontati, penso che terrò questo codice. Strano perché la soluzione che avevo ideato l'avevo cercata, e su un altro source l'avevo vista. Comunque grazie per il trucchetto.
Per riavviare ho provato a inserire nuova=getch(); invece di scanf("%c", &nuova); e funziona.
Ovviamente devi aggiungere la libreria conio.h.
Ho notato che dopo il riavvio rimangono le pedine della partita precedente.

Bel programma comunque :)
Grazie, avevo già provato getch, e andava. A casa a sto punto sostituisco scanf con getch, e metto anche l'inizializzazione dell'array schema dentro il do while al posto che fuori dal main, così ogni volta si resetta. Ora però voglio capire perché scanf non va... Qualche idea?

Stewino
20-02-2012, 11:43
Praticamente lo scanf legge ogni tipo di carattere digitato da tastiera, quindi anche l'invio.

Per risolvere questo problema basta mettere scanf("%s", &nuova); se noti ho sostituito la 'c' con una 's'.
Oppure utilizzi il getch.

;)

Filly95
20-02-2012, 12:02
EDIT: Cercando su Google ho trovato che "%c" non dovrebbe tenere conto del \n ("%s" invece sì) ma nel caso del do while lo fa. Come si risolve? Ho trovato qui (http://www.elvisciotti.it/2007/11/linguaggio-c-stdioh-scanfc/) che mettendo "%c\n" dovrebbe andare a posto.

Stewino
20-02-2012, 14:38
Se utilizzi %c verrà letto anche l'invio.
Es. digito 's' e premo invio, il programma legge il carattere 's' e /n, la variabile sarà uguale a 's' con /n.

Se utilizzi \n%c l'invio verrà scartato.
Es. digito 's' e premo invio, il programma legge il carattere 's' e /n, scarta /n, quindi la variabile sarà uguale a 's'.

;)

Filly95
20-02-2012, 15:54
Sisi, ora funziona tutto! Stavo spiegando a mio nonno come giocare e nel frattempo mi sono accorto che mancava anche l'azzeramento (o meglio, l'inizializzazione a 1) dei turni quando si ricomincia una partita :D
Comunque questo è il codice sorgente finale, se a qualcuno mai sarà utile: http://codepad.org/n73qX3nc.
Un'altra cosa carina da implementare sarebbe l'uscita in qualsiasi momento premendo esc ma non so/ho voglia di implementarla ;)

Stewino
20-02-2012, 16:34
Sarebbe bello farlo con una veste grafica, solo che non so come si fa, a quest'ora l'avrei già fatto :D

Filly95
20-02-2012, 23:11
Sicuramente il c da solo non basta, ci vuole qualche libreria... Però l'esercizio era realizzarlo in console, ce l'ho fatta in 8 ore e ne sono fiero :D

tecno789
21-02-2012, 14:08
sei grande. Fare giochi in C è davvero complicato!! :mad:

Phantom1989
20-11-2012, 10:59
Ciao a tutti ragazzi, sono nuovo del forum. Io ho prodotto una mia versione del gioco del tris ed è funzionante in Code::Blocks 10.05. Questo è il codice:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 3
#define CPU 1
#define PLAYER 0
void stampa(char matrice[DIM][DIM]); //stampa il tabellone ogni volta che un giocatore inserisce una propria pedina
int inserimento (char matrice[DIM][DIM], int stato); //inserisce la pedina del giocatore corrispondente
void vittoria (char matrice[DIM][DIM], char ); //controlla se si è verificato un tris e decreta il vincitore
int main()
{
int status=0, i=0;
char matrix[DIM][DIM]={'.','.','.','.','.','.','.','.','.'}; //inizializzazione di matrice (ho 2 warning per questo)
printf("Il programma permette di giocare a tris con il computer\n");
srand(time(NULL));
status=rand()%2; //testa o croce fra il giocatore e la CPU
stampa(matrix);
i=0;
while(i<10) //si possono occupare solo 9 caselle
{
status=inserimento(matrix, status);
i++;
}
printf("La partita contro la CPU e' finita pari\n");
return 0;
}

void vittoria (char matrice[DIM][DIM], char pedina)
{
int i=0, j=0, flag=0;
for(i=0;i<DIM;i++) //controllo per righe della matrice
{
flag=0;
for(j=0;j<DIM;j++)
{
if(matrice[i][j]==pedina)
flag++;
}
if(flag==3)
{
stampa(matrice);
printf("Giocatore '%c' HAI FATTO TRIS! SEI IL VINCITORE!\n", pedina);
exit(EXIT_SUCCESS);
}
}
for(j=0;j<DIM;j++) //controllo per colonne della matrice
{
flag=0;
for(i=0;i<DIM;i++)
{
if(matrice[i][j]==pedina)
flag++;
}
if(flag==3)
{
stampa(matrice);
printf("Giocatore '%c' HAI FATTO TRIS! SEI IL VINCITORE!\n", pedina);
exit(EXIT_SUCCESS);
}
}
if(matrice[0][0]==pedina && matrice[1][1]==pedina && matrice[2][2]==pedina) //controllo delle diagonali della matrice
{
stampa(matrice);
printf("Giocatore '%c' HAI FATTO TRIS! SEI IL VINCITORE!\n", pedina);
exit(EXIT_SUCCESS);
}
if(matrice[0][2]==pedina && matrice[1][1]==pedina && matrice[2][0]==pedina)
{
stampa(matrice);
printf("Giocatore '%c' HAI FATTO TRIS! SEI IL VINCITORE!\n", pedina);
exit(EXIT_SUCCESS);
}
stampa(matrice);
}

void stampa(char matrice[DIM][DIM])
{
int i=0, j=0;
char righe[DIM]={'A','B','C'}, colonne[DIM+1]={' ','1','2','3'};
for(i=0;i<DIM+1;i++)
{
printf("%c ", colonne[i]);
}
printf("\n");
for(i=0;i<DIM;i++)
{
printf("%c ", righe[i]);
for(j=0;j<DIM;j++)
{
printf("%c ", matrice[i][j]);
}
printf("\n");
}
}

int inserimento (char matrice[DIM][DIM], int stato)
{
char xy[DIM]={'\0','\0','\0'}, sign='\0';
int i=0,j=0;
printf("Mossa?<inserire coordinate>\n");
if(stato==CPU)
{
sign='O'; //assegna un segno distinguibile ad ogni giocatore
do
{
srand(time(NULL));
i=rand()%3; //la CPU deve scegliere casualmente una riga ed una colonna da 0 a 3
srand(time(NULL));
j=rand()%3;
}
while(matrice[i][j]!='.'); //controlla che la casella non sia occupata da un altra pedina
matrice[i][j]=sign; //assegna alla casella libera il segno del giocatore corrente
vittoria(matrice, sign); //rimanda al controllo del tris
stato=PLAYER; //passa la mano all'avversario
return stato; //ritorna il turno del giocatore corrispondente
}
else
{
sign='X';
do
{
gets(xy); //il giocatore deve inserie un carattere compreso fra A,B,C per le righe e 1,2,3 per le colonne
i=xy[0]%65; //traduce le lettere in indici della matrice
j=xy[1]%49; //mette in scala i numeri inseriti per le colonne
}
while(matrice[i][j]!='.');
matrice[i][j]=sign;
vittoria(matrice, sign);
stato=CPU;
return stato;
}
}

Devo ammettere che però non sono molto soddisfatto del risultato perché nella funzione "vittoria" ci sono troppe 'if' e troppe righe di codice nel complesso (ovviamente dovrei ottimizzare il programma passando i parametri delle funzioni con i puntatori). La funzione 'srand()' mi blocca il pc e non so per quale motivo. Vorrei sapere cosa ne pensate e se mi potete dare qualche dritta per ottimizzarlo. Grazie a tutti!