skapa spel: TIC TAC TOE
Ett program måste skapas där två spelare kan spela Tic-Tac-Toe ("Farmer's Chess").
Det måste skrivas / kodas för fem funktioner,
void resetSpel ()
Alla element / mellanslag / "rutor" i gSpel är inställda på " " (blank / mellanslag).ritaSpel ()
Skriver ut det aktuella innehållet i spelet med ett utseende som anges nedan.bool kontrolleraSpel (const int n)
Kontrollerar och returnerar om n finns på tavlan (index 0-8) och om utrymmet / rutten är ledig eller inte.
(Men det sätter omöjligt en bit på plats, det görs i / av spelet.)bool kontrolleraVinnar ()
Hittar och returnerar true / false till om någon spelare har tre i rad (horisontellt, vertikalt eller
på en av de två diagonalerna).int spelaSpelet ()
Denna funktion är "motor / hjärna" i spelet. Det slingrar tills nio bitar är inställda, eller så
någon har vunnit (har tre i rad). Det kommer att växla mellan vilken av de två spelarna som sätter det
nästa bit ('X' eller 'O'). Efter varje chipplacering skrivs kortet ut.
Det returnerar spelarens nummer (1, 2) som har vunnit, möjligen 0 (noll) om ingen vinner.
Jag provar nu att skriva kontrolleraVinnar og ritaSpel funktion.
Ser det här bra ut?
void ritaSpel() {
printf("\t\nTic Tac Toe\n");
printf("\t---%c-----%c-----%c---\n", ANTRUTER[1], ANTRUTER[2], ANTRUTER[3]);
printf("\t | | | |\n");
printf("\t | | | |\n");
printf("\t---%c-----%c-----%c---\n", ANTRUTER[4], ANTRUTER[5], ANTRUTER[6]);
printf("\t | | | |\n");
printf("\t | | | |\n");
printf("\t---%c-----%c-----%c---\n", ANTRUTER[7], ANTRUTER[8], ANTRUTER[9]);
printf("\t | | | |\n");
printf("\t | | | |\n");
printf("\t ----------------------\n");
}
----
bool kontrolleraVinnar(){}
int returnValue= 0;
if (ANTRUTER[1] == ANTRUTER[2] && ANTRUTER[2] == ANTRUTER[3])
{
returnValue= 1;
}
else if (ANTRUTER[4] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[6])
returnValue = 1;
else if (ANTRUTER[7] == ANTRUTER[8] && ANTRUTER[8] == ANTRUTER[9])
returnValue = 1;
else if (ANTRUTER[1] == ANTRUTER[4] && ANTRUTER[4] == ANTRUTER[7])
returnValue = 1;
else if (ANTRUTER[2] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[8])
returnValue = 1;
else if (ANTRUTER[3] == ANTRUTER[6] && ANTRUTER[6] == ANTRUTER[9])
returnValue = 1;
else if (ANTRUTER[1] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[9])
returnValue = 1;
else if (ANTRUTER[3] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[7])
returnValue = 1;
else if (ANTRUTER[1] != '1' && ANTRUTER[2] != '2' && ANTRUTER[3] != '3' &&
ANTRUTER[4] != '4' && ANTRUTER[5] != '5' && ANTRUTER[6] != '6' && ANTRUTER[7]
!= '7' && ANTRUTER[8] != '8' && ANTRUTER[9] != '9')
returnValue = 0;
else
returnValue = -1;
return returnValue;
En god start, men funktionerna uppfyller inte kraven. kontrolleraVinnar() ska returnera false (noll) om ingen vunnit och true (något annat än noll) om någon vunnit. Koden returnerar true (-1) om ingen av if-satserna är true.
Datastrukturen verkar vara en array med nio element. En sådan ska indexeras 0-8, inte 1-9 som koden är nu.
Spelbrädet är 3x3 rutor och representeras mer logiskt som en tvådimensionell array.
Oavsett datastruktur bör varje spelares pjäs ('X' eller 'O') placeras i den strukturen, inte siffror.
Att en funktion som är deklarerad som bool returnerar tre olika värden är konstigt.
Lindehaven skrev:En god start, men funktionerna uppfyller inte kraven. kontrolleraVinnar() ska returnera false (noll) om ingen vunnit och true (något annat än noll) om någon vunnit. Koden returnerar true (-1) om ingen av if-satserna är true.
Datastrukturen verkar vara en array med nio element. En sådan ska indexeras 0-8, inte 1-9 som koden är nu.
Spelbrädet är 3x3 rutor och representeras mer logiskt som en tvådimensionell array.
Oavsett datastruktur bör varje spelares pjäs ('X' eller 'O') placeras i den strukturen, inte siffror.
Aha men jag kan bara byta från -1 till 0?
sen ändrar jag alla värdena från 1-9, och till 0-8.
men min fråga är hur använder jag X och O till att markera ?
Laguna skrev:Att en funktion som är deklarerad som bool returnerar tre olika värden är konstigt.
asså, det är vår lärare som vill att vi ska använda bool 🤔 och jag måste ha true/falsk, så blir då 3 olika värden då eller hur..?
true/falsk är väl två värden. Vad ska det tredje värdet betyda?
Ska du använda bool
i C behöver du även inkludera stdbool.h
och verkligen använda värdena true
eller false
. En bool
kan endast ha de två olika värdena.
C kan utvärdera andra datatyper till sant eller falskt. Värden som är noll är falska, andra värden är sanna. Att ändra från -1 till 0 innebär att du ändrar från sann till falsk, är det vad du vill? Använd true
eller false
så blir koden tydligare.
I din datastruktur för spelbrädet kan du förslagsvis markera spelarnas placering av pjäser med 'X' respektive 'O'. En tom ruta (utan någon pjäs) bör markeras med ett annat tecken, kanske ' '? Ex:
// Om spelbrädets datastruktur deklarerats så här:
char board[3][3] =
{
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
};
// Läs in på vilken rad och kolumn som spelarens
// pjäs X ska placeras och placera den där:
board[row][col] = 'X';
Måste jag då ändra första och sista returnValue, eller på alla?
tex.
bool kontrolleraVinnar(){}
int returnValue= 1;
if (ANTRUTER[1] == ANTRUTER[2] && ANTRUTER[2] == ANTRUTER[3])
{
returnValue= 1;
}
else if (ANTRUTER[4] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[6])
returnValue = 1;
else if (ANTRUTER[7] == ANTRUTER[8] && ANTRUTER[8] == ANTRUTER[9])
returnValue = 1;
else if (ANTRUTER[1] == ANTRUTER[4] && ANTRUTER[4] == ANTRUTER[7])
returnValue = 1;
else if (ANTRUTER[2] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[8])
returnValue = 1;
else if (ANTRUTER[3] == ANTRUTER[6] && ANTRUTER[6] == ANTRUTER[9])
returnValue = 1;
else if (ANTRUTER[1] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[9])
returnValue = 1;
else if (ANTRUTER[3] == ANTRUTER[5] && ANTRUTER[5] == ANTRUTER[7])
returnValue = 1;
else if (ANTRUTER[1] != '1' && ANTRUTER[2] != '2' && ANTRUTER[3] != '3' &&
ANTRUTER[4] != '4' && ANTRUTER[5] != '5' && ANTRUTER[6] != '6' && ANTRUTER[7]
!= '7' && ANTRUTER[8] != '8' && ANTRUTER[9] != '9')
returnValue = 0;
else
returnValue = 0;
return returnValue;
Sen undrar jag hur jag gör dom andra funktionene också.
Tex: void resetSpel ()
Alla element / mellanslag / "rutor" i gSpel är inställda på " " (blank / mellanslag)
Vad borde jag göra vidare ?
void resetSpel(){
for(gSpel [i] = ' ')
}
#include <stdio.h> // printf, scanf
#include <stdbool.h> // bool
#include <ctype.h> // toupper
#define ANTRUTER 9 ///< Antall rutor på spelet
const int STRLEN = 80; ///< textlengd
void resetSpel();
bool kontrolleraSpel(const int n);
bool kontrolleraVinnar();
void ritaSpel();
int spelSpelet();
char gSpel[ANTRUTER]; ///< Spelet.
/**
* huvudprogram.
*/
int main() {
char spelar1[STRLEN]; // spalar namn.
char spelar2[STRLEN];
char nyttSpel; // kör program/spelet EN gång till.
int vinnar; // Evt. spelnummer som har vunnit.
do {
resetSpel();
ritaSpel();
printf("\n\nNavn på spelar 1: "); gets(spelar1);
printf("Navn på spelar 2: "); gets(spelar2); printf("\n");
vinnar = spelSpelet();
if (vinnar == 1) printf("\Grattis %s!!\n\n", spelar1);
else if (vinnar == 2) printf("\Grattis %s!!\n\n", spelar2);
// 'vinnar' == 0:
else printf("\nIngen vinnare denne her gång tyvärr.\n\n");
printf("\n\nen ny omgång (N/J): ");
scanf(" %c", &nyttSpell); nyttSpel = toupper(nyttSpel);
getchar();
} while (nyttSpel == 'J');
return 0;
}
Det här är min main. Sen ska jag ha 5 funktioner utanför main.
Du har ändrat ANTRUTER
från en array till en int. Du har skapat en gSpel
som är en array. Därmed kan du inte indexera ANTRUTER
utan behöver indexera gSpel
i stället.
Funktionen kontrolleraVinnar()
behöver kontrollera de åtta olika kombinationer som kan ge vinst. Det kan göras på olika sätt. Om tomma rutor representeras med ett blanktecken kan du exempelvis skriva:
bool kontrolleraVinnar()
{
return ( (gSpel[0] != ' ' && gSpel[0] == gSpel[1] && gSpel[1] == gSpel[2])
|| (gSpel[3] != ' ' && gSpel[3] == gSpel[4] && gSpel[4] == gSpel[5])
|| (gSpel[6] != ' ' && gSpel[6] == gSpel[7] && gSpel[7] == gSpel[8])
/* o s v för resterande fem kombinationer */
);
}
Funktionen resetSpel()
behöver rensa brädet från spelpjäser. Med andra ord ska alla 'X' och 'O' bort. Om tomma rutor representeras med ett blanktecken så behöver du endast tilldela elementen i din datastruktur så här:
for (int i = 0; i < ANTRUTER; i++)
gSpel[i] = ' ';
Ditt program kompilerar inte. Skriv det så att det går att kompilera.
Lindehaven skrev:Du har ändrat
ANTRUTER
från en array till en int. Du har skapat engSpel
som är en array. Därmed kan du inte indexeraANTRUTER
utan behöver indexeragSpel
i stället.Funktionen
kontrolleraVinnar()
behöver kontrollera de åtta olika kombinationer som kan ge vinst. Det kan göras på olika sätt. Om tomma rutor representeras med ett blanktecken kan du exempelvis skriva:bool kontrolleraVinnar() { return ( (gSpel[0] != ' ' && gSpel[0] == gSpel[1] && gSpel[1] == gSpel[2]) || (gSpel[3] != ' ' && gSpel[3] == gSpel[4] && gSpel[4] == gSpel[5]) || (gSpel[6] != ' ' && gSpel[6] == gSpel[7] && gSpel[7] == gSpel[8]) /* o s v för resterande fem kombinationer */ ); }
Ska jag ha dom värdene efter return?
Ja, mellan parenteserna för return
, som mitt kodexempel visar. Jag antog att du känner till logiska operatorer.
Och varför är det bara [0], [3], [6] osv som inte kan vara ' '.
Måste jag inte ha alla tall [1] != ' ' ?
Den raden/kolumnen/diagonalen man kontrollerar kan inte ge en vinst för någon spelare om någon ruta på den raden/kolumnen/diagonalen är tom.
Aha okej, tack.
Så blir det såhär då?
bool kontrolleraVinnar(){
{
return ( (gSpel[0] != ' ' && gSpel[0] == gSpel[1] && gSpel[1] == gSpel[2])
|| (gSpel[3] != ' ' && gSpel[3] == gSpel[4] && gSpel[4] == gSpel[5])
|| (gSpel[6] != ' ' && gSpel[6] == gSpel[7] && gSpel[7] == gSpel[8])
|| (gSpel[2] != ' ' && gSpel[2] == gSpel[5] && gSpel[5] == gSpel[8])
|| (gSpel[1] != ' ' && gSpel[1] == gSpel[4] && gSpel[4] == gSpel[7])
|| (gSpel[0] != ' ' && gSpel[0] == gSpel[3] && gSpel[3] == gSpel[6])
|| (gSpel[2] != ' ' && gSpel[2] == gSpel[4] && gSpel[4] == gSpel[6])
|| (gSpel[0] != ' ' && gSpel[0] == gSpel[4] && gSpel[4] == gSpel[8])
)
}
void ritaSpel() {
printf("\t\nTic Tac Toe\n");
printf("\t---1-----2-----3---\n");
printf("\t| %c | %c | %c |\n",ANTRUTER[0], ANTRUTER[1], ANTRUTER[2]);
printf("\t---4-----5-----6---\n");
printf("\t| %c | %c | %c |\n",ANTRUTER[3], ANTRUTER[4], ANTRUTER[5]);
printf("\t---7-----8-----9---\n");
printf("\t| %c | %c | %c |\n",ANTRUTER[6], ANTRUTER[7], ANTRUTER[8]);
printf("\t ----------------------\n");
}
void resetSpel (){
for (int i = 0; i < ANTRUTER; i++)
gSpel[i] = ' ';
}
Jag behöver då bara
spelSpelet och kontrolleraSpel.
Har du nån tips till det?
Blir det första nåt som det här?
spelar = (spelar % 2) ? 1 : 2;
printf("Speler %d, Välj et tal: ", spelar);
scanf("%d", &val);
merk = (spelar== 1) ? 'X' : 'O';
if (val == 1 && ANTRUTER[0] == '1')
ANTRUTER[0] = merk;
else if (valg == 2 && ANTRUTER[1] == '2')
ANTRUTER[1] = merk;
osv...
Prova att kompilera. Läs sedan vad jag tidigare skrev om ANTRUTER och gSpel.
Går inte att kompilera nu pga det är så många errors.
Men aha så jag använder gSpel och inte ANRUTER?
Ska jag också använde gSpel i ritaSpel också istället för ANRUTER?
den bool kontrolleraVinnar blir bara errors.. Fattar inte hur den kan bli riktig när den är skrevet så :(
Rätta kompileringsfelen ett efter ett. Till slut är det inga kvar.
Men det står på kontrolleraVinnar()
"error: expected '=', ',', ';', 'asm' or '__attribute__' before '/' token|"
bool kontrolleraVinnar(){
{
return ( (gSpel[0] != ' ' && gSpel[0] == gSpel[1] && gSpel[1] == gSpel[2])
|| (gSpel[3] != ' ' && gSpel[3] == gSpel[4] && gSpel[4] == gSpel[5])
|| (gSpel[6] != ' ' && gSpel[6] == gSpel[7] && gSpel[7] == gSpel[8])
|| (gSpel[2] != ' ' && gSpel[2] == gSpel[5] && gSpel[5] == gSpel[8])
|| (gSpel[1] != ' ' && gSpel[1] == gSpel[4] && gSpel[4] == gSpel[7])
|| (gSpel[0] != ' ' && gSpel[0] == gSpel[3] && gSpel[3] == gSpel[6])
|| (gSpel[2] != ' ' && gSpel[2] == gSpel[4] && gSpel[4] == gSpel[6])
|| (gSpel[0] != ' ' && gSpel[0] == gSpel[4] && gSpel[4] == gSpel[8])
)
}
Oftast är felmeddelanden tydliga men detta är inte ett av dem. Jag gissar att det beror på dubbla curly braces i funktionsdefinitionen. Lägg även till ett semikolon efter return-satsen.