Mit rontottam el? (C programozási nyelv)
Egy szöveg alapú 3*3-as amőbajátékot akarok készíteni C-ben. A működési elv egyszerű: Bekéri az első játékostól a kezdőlépése koordinátáit, majd a két játékos felváltva tesz egy-egy lépést. Ha egy játékos olyan mezőre akar tenni, ami már foglalt, akkor jelzi (még nem oldottam emg, hogy ekkor ez a játékos ismét léphessen, de nem ez a kérdés célja). Minden lépés után kirajzolja a táblát, majd ellenőrzi, nyert-e valaki, ha igen, kihirdeti és kilép.
Az elv szerintem viszonylag egyszerű, és elég megvalósíthatónak tűnt. A probléma a program lefutásakor adódott. Bármilyen koordinátát adok meg az első játékos kezdőlépésének, mindig a jobb alsó sarokba teszi neki az X-et, majd kihirdeti, hogy ő nyert, 1 lépés után. Többször is átnéztem, arra gondoltam, esetleg az a gond, hogy lokális és globális változónak is ugyanazt a nevet adtam, de ha ez gond lenne, akkor gondolom el sem futott volna a program. Azért használtam ugyanazt a nevet, mert szerintem így átláthatóbb lett a program.
#include <stdio.h>
#include <stdlib.h>
int p1moves(int i, int j) //Player 1 megadja, hova akar lépni
{
printf("Player 1, place your X by telling its coordinates!");
printf("\n");
scanf("%d", &i);
scanf("%d", &j);
}
int p2moves(int i, int j) //Player 2 megadja, hova akar lépni
{
printf("Player 2, place your X by telling its coordinates!");
printf("\n");
scanf("%d", &i);
scanf("%d", &j);
}
int makemovep1 (int i, int j, int table[3][3]){ // A megfelelő koordinátáknál levő tömbeklem értéke 1 lesz
if (table[i-1][j-1] == 0 ) { //Mivel a tömb 0-ról indul, de a játékos 1-el kezdve gondolkodik, eggyel kell csökkenteni a koordinátákat
table[i-1][j-1] = 1;
}
else {
printf("This place is already used!\n"); //Jelzi, hogy a mező már foglalt
}
}
int makemovep2 (int i, int j, int table[3][3]){ // A megfelelő koordinátáknál levő tömbeklem értéke 2 lesz
if (table[i-1][j-1] == 0 ) {
table[i-1][j-1] = 2;
}
else {
printf("This place is already used!\n");
}
}
int check(int i, int j, int table[3][3])
{
for (i=0;i<3;i++){ //Ellenőrzi a tábla minden sorára, van-e 3 ugyanolyan, ha igen, eredményt hirdet
if (table[i][0] == table[i][1] && table[i][1] == table[i][2] && table[i][2] == 1){
printf("Player 1 wins!\n");
system("PAUSE");
exit(0);
}
if (table[i][0] == table[i][1] && table[i][1] == table[i][2] && table[i][2] == 2){
printf("Player 2 wins!\n");
system("PAUSE");
exit(0);
}
}
for (j=0;j<3;j++){ //Ellenőrzi a tábla minden oszlopára, van-e 3 ugyanolyan, ha igen, eredményt hirdet
if (table[0][j] == table[1][j] && table[1][j] == table[2][j] && table[2][j] == 1){
printf("Player 1 wins!\n");
system("PAUSE");
exit(0);
}
if (table[0][j] == table[1][j] && table[1][j] == table[2][j] && table[2][j] == 2){
printf("Player 2 wins!\n");
system("PAUSE");
exit(0);
}
}
if ((table[0][0] == table[1][1] == table[2][2] == 1) || (table[0][2] == table[1][1] == table[2][0] == 1)){ //Ellenőrzés átlókra
printf("Player 1 wins!\n");
system("PAUSE");
exit(0);
}
if ((table[0][0] == table[1][1] == table[2][2] == 2) || (table[0][2] == table[1][1] == table[2][0] == 2)){
printf("Player 2 wins!\n");
system("PAUSE");
exit(0);
}
}
int draw (int i, int j, int table[3][3]){ //Kirajzolja atáblát
for (i=0;i<3;i++){
for (j=0;j<3;j++){
switch (table[i][j]) {
case 1: {
printf("[X]"); //Ha a mező értéke 1, vagyis P1-é, akkor X-et rajzol rá
};
break;
case 2: {
printf("[O]");
};
break;
default: {
printf("[]");
}
}
}
printf("\n");
}
}
int main()
{
int i,j,valt;
int table[3][3];
for (i=0;i<3;i++){
for (j=0;j<3;j++){
table[i][j] = 0;
}
}
p1moves(i,j);
makemovep1(i,j,table);
draw(i,j,table);
check(i,j,table);
for (valt=1;valt<5;valt++){ //Miután P1 lépett egyet, felváltva mennek 4-4 lépést, ha eddig nincs vége, döntetlen
p2moves(i,j);
makemovep2(i,j,table);
check(i,j,table);
draw(i,j,table);
p1moves(i,j);
makemovep1(i,j,table);
check(i,j,table);
draw(i,j,table);
}
printf("The result is a tie!\n");
system("PAUSE");
return 0;
}
Itt van a teljes forráskód, előre is köszönöm a segítséget, továbbá ha esetleg valaki tud adni tippet ahhoz, hogy hogy lehetne tovább fejleszteni, azt is megköszönném.
Az a baj, hogy amikor meghívsz egy függvényt, akkor a lokális változók létrejönnek, majd a függvény végével megsemmisülnek, meghalnak.
int p1moves(int i, int j) //Player 1 megadja, hova akar lépni
Ez a fv. csak beolvassa i, j-t, aztán eldobja az értéküket.
Kijavítási lehetőségek:
-globális változó (csúnya)
-visszatérési értékbe összekombinálod, pl. return 3*i+j; egyértelműen visszafejthető.
-i, j-re mutató pointert adsz a függvénynek, így az a main-beli i, j-t írja át.
Köszönöm a választ, de nem vagyok biztos benne, hogy értem, hálás lennék, ha kifejtenéd egy kicsit, már ha nem nagy munka így reggel fejében.
1. A visszatérési érték miben segít nekem? Nem változtatja meg a globális i és j értékeket, amennyire értem.
2. Ami a pintereket illeti: Akkor ezeket hol is kell deklarálni, és melyik i-re és j-re kell mutassanak?
Egyidejőleg viszont megkaptam a leckét, hogy ügyeljek jobban a változók elnevezésére, mert így, hogy gondok merültek fel, nem értelek pontosan, és így magam alatt vágtam a fát.
Nem néztem tovább, csak azt magyarázom el, amit az első mondott. Pl. a
"int p1moves(int i, int j) //Player 1 megadja, hova akar lépni
{
printf("Player 1, place your X by telling its coordinates!");
printf("\n");
scanf("%d", &i);
scanf("%d", &j);
} "
függvényben. Itt érték szerinti paraméterátadás történik a függvénynek (az argumentumokról van szó), tehát minden, ami a függvényen belül történik velük, az ottani i, j változóval, az ott is marad. Ezek nem azok az i, j változók, amiket máshol is használsz, hanem csak lokális változók.. Nem magukat a változókat kapja meg a függvény, csak az értéküket, mondhatjuk, hogy másolatukat.
Az említett javítási módokról:
- globális változó: ilyenkor a függvényeken kívül deklarálsz változót, és minden függvényben láthatóak, és tudod őket használni. Ergo nem kell ennek a függvénynek argumentum sem.
- visszatérés az értékkel: itt sem kell paraméter a függvénynek, a bekért koordinátákat return utasítással adja vissza. Azért 3*i+j alakban, mert csak egy valamivel térhet vissza a függvény. Ha ezt maradékosan elosztod 3-mal, az eredmény lesz az i, a maradék a j.
- pointerekkel: a változókra mutató pointereket adod át a függvénynek. Ez egy olyan szám, ami a változók memóriahelyére mutat, tehát ha ezzel dolgozol, akkor tényleg ugyanazokat a változókat módosítod a függvényben, és nem csak a másolataikat.
De van egy olyan érzésem, hogy ez is kevés volt neked, szóval mondjuk:
Lacii: Azt hiszem, megértettem. Legalábbis remélem.
Tengor: Megtennéd, hogy linkelsz olyasmi feladatokat, amikre szerinted szükségem lehet? Elismerem, vannak még hiányosságaim, de nem vagyok biztos, hogy tudom, pontosan hogyan tudnám őket pótolni. Angolul is megértem, köszi előre is.
A makemovep1 és makemovep2 miért 2 függvény?
Ugyanígy a p1moves p2moves?
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!