Skocz do zawartości
Marrrcin

C++ Kółko I Krzyżyk

Rekomendowane odpowiedzi

Napisałem kółko i krzyżyk dla dwóch graczy w którym pola wypełnia się za pomocą podawania współrzędnych. Mam problem z wykrywaniem remisu. Remis byłby wtedy kiedy wszystkie pola będą wypełnione ale żaden z graczy nie ułoży trzech figur w rzędzie. Kółka i krzyżyki są wprowadzane do dwuwymiarowej tablicy. Wcześniej miałem to tak zrobione, że remis był wtedy gdy wartości we wszystkich komórkach tablicy będą różne od ' ' (spacja). Wariant ten nie działał więc uprościłem go do minimum zakładając że remis wystąpi wtedy gdy współrzędne zostaną wprowadzone 9 razy. Takie rozwiązanie jest bardzo "zawodne", ale i tak mi nie działa. Gdzie tkwi błąd? Poniżej kod:

#include <iostream.h>#include <conio.h>char znak;char pole[3][3];int x,y,liczba,licznik;bool wygrana;void wyswietl(){	 cout << "				'OS X'" << endl << endl;	 cout << "			  0	 1	 2" << endl; 	 cout << "		   -------------------" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		 0 |  " << pole[0][0] << "  |  " << pole[1][0] << "  |  " << pole[2][0] << "  |" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		   -------------------" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << " 'OS Y'  1 |  " << pole[0][1] << "  |  " << pole[1][1] << "  |  " << pole[2][1] << "  |" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		   -------------------" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		 2 |  " << pole[0][2] << "  |  " << pole[1][2] << "  |  " << pole[2][2] << "  |" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		   -------------------" << endl;	 } void czyszczenie(){	 for(x=0; x<=2; x++) pole[x][0]=' ';	 for(x=0; x<=2; x++) pole[x][1]=' ';	 for(x=0; x<=2; x++) pole[x][2]=' ';}	 void sprawdzenie(){	 if((pole[0][0]=='O') && (pole[0][1]=='O') && (pole[0][2]=='O')) wygrana=true;		   	 if((pole[1][0]=='O') && (pole[1][1]=='O') && (pole[1][2]=='O')) wygrana=true;	 if((pole[2][0]=='O') && (pole[2][1]=='O') && (pole[2][2]=='O')) wygrana=true;	 	 if((pole[0][0]=='O') && (pole[1][0]=='O') && (pole[2][0]=='O')) wygrana=true;		   	 if((pole[0][1]=='O') && (pole[1][1]=='O') && (pole[2][1]=='O')) wygrana=true;	 if((pole[0][2]=='O') && (pole[1][2]=='O') && (pole[2][2]=='O')) wygrana=true;	 	 if((pole[0][0]=='O') && (pole[1][1]=='O') && (pole[2][2]=='O')) wygrana=true;		   	 if((pole[2][0]=='O') && (pole[1][1]=='O') && (pole[0][2]=='O')) wygrana=true;	 	 	 if((pole[0][0]=='X') && (pole[0][1]=='X') && (pole[0][2]=='X')) wygrana=true;		   	 if((pole[1][0]=='X') && (pole[1][1]=='X') && (pole[1][2]=='X')) wygrana=true;	 if((pole[2][0]=='X') && (pole[2][1]=='X') && (pole[2][2]=='X')) wygrana=true;	 	 if((pole[0][0]=='X') && (pole[1][0]=='X') && (pole[2][0]=='X')) wygrana=true;		   	 if((pole[0][1]=='X') && (pole[1][1]=='X') && (pole[2][1]=='X')) wygrana=true;	 if((pole[0][2]=='X') && (pole[1][2]=='X') && (pole[2][2]=='X')) wygrana=true;	 	 if((pole[0][0]=='X') && (pole[1][1]=='X') && (pole[2][2]=='X')) wygrana=true;		   	 if((pole[2][0]=='X') && (pole[1][1]=='X') && (pole[0][2]=='X')) wygrana=true;}void gra(int nr){ 	 cout << " KOLKO I KRZYZYK" << endl << endl << endl;	 cout << " GRACZ 1: KOLKO" << endl << " GRACZ 2: KRZYZYK" << endl << endl;	 wyswietl();	 cout << endl;	 	 cout << " Ruch GRACZA " << nr << ". Podaj wspolrzedne pola: " << endl;	 cout << " Podaj X: ";	 cin >> x;	 cout << " Podaj Y: ";	 cin >> y;	 if (pole[x][y]==' ') pole[x][y]=znak; else {cout << endl << " TO POLE JEST JUŻ ZAJĘTE, WYBIERZ INNE";}}	 	 int main(){	 znak='O';	 	 liczba=1;	 licznik=0;	 wygrana=false;	 czyszczenie();	 do	 {		 gra(liczba);		 system("cls");		 		 if(liczba==1)		 {			 liczba=2;			 znak='X';		 }		 else		 {			 liczba=1;			 znak='O';		 }  		 sprawdzenie();		 licznik++;			  	 }	 while ( (licznik<9) || (wygrana==false) ); 	 cout << " KOLKO I KRZYZYK" << endl << endl << endl;	 wyswietl();	 if (wygrana==true)	 {		if(liczba==1) liczba=2; else liczba=1;		cout << endl << " WYGRAL GRACZ " << liczba << "!!!";	 }	 else cout << endl << "REMIS!";	 getch();}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dam Ci parę rad. Na początku - musisz jakoś zablokować możliwość wpisywania jako strzału współrzędnych [123,456], czyli poza tablicowych. Co do sprawdzenia czy padł remis. Po prostu sprawdź, czy występuje w tablicy jeszcze znak spacji. Poza tym możesz w tablicy przechowywać nie znaki, a cyfry/liczby reprezentujące stan gry. Będzie Ci łatwiej ewentualnie rozbudować potem grę. Jakbyś chciał coś więcej to pisz.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Akurat nie mam pod ręką kompilatora, ale tak na oko problem tu może być w procedurze gra - gdy zostanie wykryta sytuacja, że ktoś próbuje postawić pionka na zajętym już polu to nastąpi wyjście z tej procedury a właściwszym wydaje się pozostawanie w niej w pętli aż do skutku tj. do chwili wskazania wolnego pola. Staraj się unikać zmiennych globalnych, przy dłuższym programie zemszczą sie na Tobie.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Kiedyś na uczelni popełniłem takie coś w c

Może się do czegoś przyda - nie pamiętam czy to wersja finalna, nie chce mi sie odpalać, pamiętam że jakaś wersja miała błąd logiczny (w złej kolejności warunki)

 

Czyli w moim programie nie można wprowadzić złych współrzędnych a remis następuje gdy zostanie wykonany 9 ruch i nikt nie wygra

 

#include <stdio.h>#include <stdlib.h>	int tablica[3][3]; //delaruje zmienna zewnetrzna w postaci tablicy 2 wymiarowej	int liczydlo=0; //deklaruje zmienna dla licznika ruchow	int k; //deklaruje zewnetrzna zmienna dla licznika w funkcji "sprawdz" ktora bedzie takze w przypadku		 //mozliwosci wygrania lub przegrania przez komputer zawierala numer kolumny lub wiersza 		 //ktory moze przyniesc przegrana lub zwyciestwo	int main(){	int a,b;  //wypelniam tablice zerami dla pustych pol mozna to zrobic przy deklarowaniu tblicy ale chce pocwiczyc petle for;)	for (a=0; a<3; a++)	for (b=0; b<3; b++)	tablica[a][b]=0;	printf ("\nInteligentna gra w kolko i krzyzyk, grasz krzyzykiem;)\n\n");	printf ("Kto ma zaczynac ? wcisnij 1 dla komputera 2 dla czlowieka 3 zeby zakonczyc\n\nAle uprzedzam jezeli ja zacze masz najwyzej szanse na remis :D\n");	scanf ("%d", &a);	if (a==1) {komputer();} //wywoluje funkcje "komputer" ktora wykonuje ruch dla komputera	if (a==2) {wyswietl(); czlowiek();} //wywoluje funkcje "czlowiek" ktora wczytuje do tablicy ruch czlowieka	if (a==3) {printf ("koniec\n");}	else {printf ("Blad miales wcisnac 1, 2 lub 3\n"); main();}}	int komputer() //funkcja "komputer"{	if (liczydlo==0) //sprawdzam czy zaczynal komputer jesli tak wykonuje optymalny pierwszy ruch {	printf ("Wykonuje pierwszy ruch !!\n");	tablica[0][0]=4;//optymalny pierwszy ruch lezy na krancu przekatnych; w tym wypadku w punkcie 1x1	liczydlo++;	wyswietl();	czlowiek();	}	else {	sprawdz(); //wywoluje funkcje sprawdz ktora sprawdza czy komputer moze wygrac czy przegrac	if (sprawdz()==1) {printf ("Gratuluje wygrales  !!!\n\n"); exit(0);}	if (sprawdz()==2) {printf ("Wygralem hahaha !!!\n\n"); exit(0);} 	else{	printf ("Moja kolej :D\n");	int c;	c=sprawdz();	losuj(c);	wyswietl();	czlowiek();}}}	int czlowiek() //funkcja "czlowiek" wypelnia wskazane przez czlowieka komorki tablicy jedynkami	{	sprawdz(); //wywoluje funkcje sprawdz ktora sprawdza czy ktos wygral;)	if (sprawdz()==1) {printf ("Gratuluje wygrales  !!!\n\n"); exit(0);}	if (sprawdz()==2) {printf ("Wygralem hahaha !!!\n\n"); exit(0);}  	else	{	int x, y;	printf ("podaj numer wiersza  0, 1 lub 2\n",x);	scanf ("%d", &x);	printf ("podaj numer kolumny 0, 1 lub 2\n",y);	scanf ("%d", &y);	if ((tablica[x][y]==4) || (tablica[x][y]==1)) {printf ("Blad podales zajete pole !!!\n"); wyswietl(); czlowiek();} 	else if ((x>2) || (y>2) || (x<0) || (y<0)) {printf ("Blad podales nieprawidlowa wartosc !!!\n"); wyswietl(); czlowiek();}	else	tablica[x][y]=1;	liczydlo++;	wyswietl();	komputer();}}	int sprawdz() //jedna z wazniejszych funkcji w programie - sprawdza szanse na wygrana lub porazke	//i na tej podstawie zwraca rozne wartosci ktore potem sa wykorzystywane przez funkcje losuj{  	if (liczydlo==9) {printf ("Niestety remis !! :(\n\n"); exit(0);} 	else	for (k=0; k<3; k++) if (tablica[k][0]+tablica[k][1]+tablica[k][2]==3) return 1; //wygral czlowiek	for (k=0; k<3; k++) if (tablica[0][k]+tablica[1][k]+tablica[2][k]==3) return 1; //wygral czlowiek	if (tablica[0][0]+tablica[1][1]+tablica[2][2]==3) return 1; //wygral czlowiek	if (tablica[2][0]+tablica[1][1]+tablica[0][2]==3) return 1; //wygral czlowiek	for (k=0; k<3; k++) if (tablica[k][0]+tablica[k][1]+tablica[k][2]==12) return 2; //wygral komputer	for (k=0; k<3; k++) if (tablica[0][k]+tablica[1][k]+tablica[2][k]==12) return 2; //wygral komputer	if (tablica[0][0]+tablica[1][1]+tablica[2][2]==12) return 2; //wygral komputer	if (tablica[2][0]+tablica[1][1]+tablica[0][2]==12) return 2; //wygral komputer	if (tablica[0][0]+tablica[1][1]+tablica[2][2]==8) return 5; //moze wygrac komputer w pierwszej przekatnej	if (tablica[0][0]+tablica[1][1]+tablica[2][2]==2) return 5; //moze wygrac czlowiek w pierwszej przekatnej	if (tablica[2][0]+tablica[1][1]+tablica[0][2]==8) return 6; //moze wygrac komputer w drugiej przekatnej	if (tablica[2][0]+tablica[1][1]+tablica[0][2]==2) return 6; //moze wygrac czlowiek w drugiej przekatnej	for (k=0; k<3; k++) if (tablica[k][0]+tablica[k][1]+tablica[k][2]==2) return 3; //moze wygrac czlowiek w kolumnie	for (k=0; k<3; k++) if (tablica[k][0]+tablica[k][1]+tablica[k][2]==8) return 3; //moze wygrac komputer w kolumnie	for (k=0; k<3; k++) if (tablica[0][k]+tablica[1][k]+tablica[2][k]==2) return 4; //moze wygrac czlowiek w wierszu	for (k=0; k<3; k++) if (tablica[0][k]+tablica[1][k]+tablica[2][k]==8) return 4; //moze wygrac komputer w wierszu	return 0; //nikt nie moze wygrac}		int losuj(int b)//funkcja losuj - otrzymuje wartosci z funkcji sprawdz za posrednictwem funkcji komputer	//i na tej podstawie dokonuje wyboru odpowiedniego ruchu{	int x,y;	srand(100);//	printf ("%d\n", b); w celu testowym - sprawdzalem czy funkcja sprawdz zwraca poprawne wartosci	if (b==0) //nikt nie moze wygrac wiec losuje ruch{	int x,y;	do{	x = rand()%3;	y = rand()%3;} 	while (tablica[x][y] !=0);	tablica[x][y] =4;	liczydlo++;	return 0;}	if (b==3) //moze wygrac kolumna k wiec blokuje lub wygrywam{	int x,y;	do{	x = k;	y = rand()%3;} 	while (tablica[x][y] !=0);	tablica[x][y] =4;	liczydlo++;	return 0;}	if (b==4) //moze wygrac wiersz k wiec blokuje lub wygrywam{	int x,y;	do{	x = rand()%3;	y = k;} 	while (tablica[x][y] !=0);	tablica[x][y]=4;	liczydlo++;	return 0;}		if (b==5) //moze wygrac pierwsza przekatna wiec blokuje lub zwyciezam{	int x,y;	x=0;	y=0;	while (tablica[x][y]!=0)	{x++; y++;}	tablica[x][y]=4;	liczydlo++;	return 0;}		if (b==6) //moze wygrac druga przekatna wiec blokuje lub zwyciezam{	int x,y;	x=2;	y=0;	while (tablica[x][y]!=0)	{x--; y++;}	tablica[x][y]=4;	liczydlo++;	return 0;}	}	int wyswietl() //funkcja wswietlajaca plansze do gry{	int a,b;	printf("\n");	for (a=0; a<3; a++){	for (b=0; b<3; b++){	if (tablica[a][b] == 0) printf(". ");	if (tablica[a][b] == 1) printf ("x ");	if (tablica[a][b] == 4) printf ("o ");}	printf("\n");}	printf("\n");	return 0;}
Edytowane przez IGI

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Poprawiłem ten program. Przebudowałem go troche i zmieniłem sposób zapisu kilku rzeczy. W dalszym ciągu nie wiem dlaczego nie wykrywało mi remisu ale udało mi się obejść ten program dodając w ostatniej linijce pętli "if...break;".Poniżej kod, może komuś się w przyszłości przyda.

#include <iostream.h>#include <conio.h>char znak;char pole[3][3];int x,y,liczba,licznik=0;void wyswietl(){	 cout << "				'OS X'" << endl << endl;	 cout << "			  0	 1	 2" << endl; 	 cout << "		   -------------------" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		 0 |  " << pole[0][0] << "  |  " << pole[1][0] << "  |  " << pole[2][0] << "  |" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		   -------------------" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << " 'OS Y'  1 |  " << pole[0][1] << "  |  " << pole[1][1] << "  |  " << pole[2][1] << "  |" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		   -------------------" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		 2 |  " << pole[0][2] << "  |  " << pole[1][2] << "  |  " << pole[2][2] << "  |" << endl;	 cout << "		   |	 |	 |	 |" << endl;	 cout << "		   -------------------" << endl;	 } void czyszczenie(){	 for(x=0; x<=2; x++) pole[x][0]=' ';	 for(x=0; x<=2; x++) pole[x][1]=' ';	 for(x=0; x<=2; x++) pole[x][2]=' ';}	 bool sprawdzenie(){  if(((pole[0][0]=='O') && (pole[0][1]=='O') && (pole[0][2]=='O')) ||		   	 ((pole[1][0]=='O') && (pole[1][1]=='O') && (pole[1][2]=='O')) ||	 ((pole[2][0]=='O') && (pole[2][1]=='O') && (pole[2][2]=='O')) ||	 	 ((pole[0][0]=='O') && (pole[1][0]=='O') && (pole[2][0]=='O')) ||			 ((pole[0][1]=='O') && (pole[1][1]=='O') && (pole[2][1]=='O')) ||	 ((pole[0][2]=='O') && (pole[1][2]=='O') && (pole[2][2]=='O')) ||	 	 ((pole[0][0]=='O') && (pole[1][1]=='O') && (pole[2][2]=='O')) ||	   	 ((pole[2][0]=='O') && (pole[1][1]=='O') && (pole[0][2]=='O')) ||	 	 	 ((pole[0][0]=='X') && (pole[0][1]=='X') && (pole[0][2]=='X')) ||		  	 ((pole[1][0]=='X') && (pole[1][1]=='X') && (pole[1][2]=='X')) ||	 ((pole[2][0]=='X') && (pole[2][1]=='X') && (pole[2][2]=='X')) ||	 	 ((pole[0][0]=='X') && (pole[1][0]=='X') && (pole[2][0]=='X')) ||		 	 ((pole[0][1]=='X') && (pole[1][1]=='X') && (pole[2][1]=='X')) ||	 ((pole[0][2]=='X') && (pole[1][2]=='X') && (pole[2][2]=='X')) ||	 	 ((pole[0][0]=='X') && (pole[1][1]=='X') && (pole[2][2]=='X')) ||		 	 ((pole[2][0]=='X') && (pole[1][1]=='X') && (pole[0][2]=='X')))	 return true; 	 else 	 return false;}void gra(int nr){ 	 cout << " KOLKO I KRZYZYK" << endl << endl << endl;	 cout << " GRACZ 1: KOLKO" << endl << " GRACZ 2: KRZYZYK" << endl << endl;	 wyswietl();	 cout << endl;	 	 cout << " Ruch GRACZA " << nr << ". Podaj wspolrzedne pola: " << endl;	 cout << " Podaj X: ";	 cin >> x;	 cout << " Podaj Y: ";	 cin >> y;	 if (pole[x][y]==' ') 	 {			 pole[x][y]=znak;		 licznik++;	 }	 else 	 {		 cout << endl << " TO POLE JEST JUZ ZAJETE, WYBIERZ INNE.";		 if (liczba==1) liczba=2; else liczba=1; 		 getch();	 }}		  int main(){	 znak='O';	 	 liczba=1;	 czyszczenie();	 do	 {		 gra(liczba);	   		 system("cls");		 		 if(liczba==1)		 {			 liczba=2;			 znak='X';		 }		 else		 {			 liczba=1;			 znak='O';		 }				if (licznik==9) break;	 }	 while ( (!sprawdzenie()) || (licznik==9) );	 cout << " KOLKO I KRZYZYK" << endl << endl << endl;	 wyswietl();	if (sprawdzenie()) 	{		if(liczba==1) liczba=2; else liczba=1;		cout << endl << " WYGRAL GRACZ " << liczba << "!!!";	 }	 else cout << endl << "REMIS!";	 getch();}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...