Fel på kod. Hjälp
Hej,
Mitt spel fungerar till 90% bra, men när det blir oavgjort skrivs inte meddelandet ut:
"Ingen vinner den här gången tyvärr."
Någon som vet vad jag kan göra?
Motorn/hjärnan i spelet är spelSpelet-funktionen.
Tic Tac Toe med 5 funktioner:
#include <stdio.h> // printf, scanf
#include <stdbool.h> // bool
#include <ctype.h> // toupper
#define ANTRUTER 9 ///< Antal rutor på spelet
const int STRLEN = 80; ///< Textlengd
void nullstillBrett();
bool sjekkBrett(const int n);
bool sjekkVinner();
void skrivBrett();
int spillSpillet();
char gBrett[ANTRUTER]; ///< spel.
/**
* Hovudprogram
*/
int main()
{
char spelar1[STRLEN];
char spelar2[STRLEN];
char nyttSpel; // Kör programmet / spelet EN gång till.
int vinner; // Alla spelarnummer som har vunnit.
do {
resetSpel();
ritaSpel();
printf("\n\nNamn på spelar 1: "); gets(spelar1);
printf("Namn på spelar 2: "); gets(spelar2); printf("\n");
vinner = spelSpelet();
if (vinnar == 1) printf("\Grattis %s!!\n\n", spelar1);
else if (vinnar == 2) printf("\Grattis%s!!\n\n", spelar2);
// 'vinner' == 0:
else printf("\nIngen vinner den här gången tyvärr.\n\n");
printf("\n\nEn ny omgång (N/J): ");
scanf(" %c", &nyttSpel); nyttSpel = toupper(nyttSpel);
getchar();
} while (nyttSpel == 'J');
return 0;
}
/* -------------------------------------------------------------------*/
void ritaSpel() {
printf("\n\t Tic Tac Toe \n");
printf("\t---1-----2-----3---\n");
printf("\t| %c | %c | %c |\n",gBrett[0], gBrett[1], gBrett[2]);
printf("\t---4-----5-----6---\n");
printf("\t| %c | %c | %c |\n",gBrett[3], gBrett[4], gBrett[5]);
printf("\t---7-----8-----9---\n");
printf("\t| %c | %c | %c |\n",gBrett[6], gBrett[7], gBrett[8]);
printf("\t-------------------\n");
}
/* -------------------------------------------------------------------*/
void resetSpel(){
for (int i = 0; i < ANTRUTER; i++)
gBrett[i] = ' '; //
}
// Återställer spel så att alla rutor är tomma.
/* -------------------------------------------------------------------*/
bool kontrolleraSpel(const int n){
if(gBrett[n-1]== ' '){
return 1;
}else return 0;
while(!(n < 1 || n > 9));
}
/* Kontrollerar om en plats är ledig eller upptagen.
n-1 för att kompensera för arrayen som börjar med noll,
men att spelet börjar med en */
/* -------------------------------------------------------------------*/
bool kontrolleraVinnar(){
if (gBrett [0] != ' ' && gBrett[0] == gBrett[1] && gBrett[1] == gBrett[2] )
return 1;
else if (gBrett [3] != ' ' && gBrett[3] == gBrett[4] && gBrett[4] == gBrett[5])
return 1;
else if (gBrett [6] != ' ' && gBrett[6] == gBrett[7] && gBrett[7] == gBrett[8])
return 1;
else if (gBrett [2] != ' ' && gBrett[2] == gBrett[5] && gBrett[5] == gBrett[8])
return 1;
else if (gBrett [1] != ' ' && gBrett[1] == gBrett[4] && gBrett[4] == gBrett[7])
return 1;
else if (gBrett [0] != ' ' && gBrett[0] == gBrett[3] && gBrett[3] == gBrett[6])
return 1;
else if (gBrett [2] != ' ' && gBrett[2] == gBrett[4] && gBrett[4] == gBrett[6])
return 1;
else if (gBrett [0] != ' ' && gBrett[0] == gBrett[4] && gBrett[4] == gBrett[8])
return 1;
else if (gBrett[0] != '1' && gBrett[1] != '2' && gBrett[2] != '3' &&
gBrett[3] != '4' && gBrett[4] != '5' && gBrett[5] != '6' && gBrett[6]
!= '7' && gBrett[7] != '8' && gBrett[8] != '9');
return 0;
}
/*Kontrollerar alla möjliga kombinationer, dvs horisontell, horisontell och tvär.
Totalt 8 möjligheter.
Om någon av dem är lika, exklusive blank, indikeras true för alla
och en spelare vinnar*/
/* -------------------------------------------------------------------*/
int spelSpelet(){ //namnpå funktion.
int spelarVal = 1; //Indikerar om det är spelare 1 eller spelare 2:s val.
int antalVal = 0; // börjar med 0.
char val; //Tallet bruker taser inn lagres her som valg.
char merk; //Markera med X eller O.
while (antalVal < 9){
ritaSpel();
antalVal++;
/* Indikerar att användarinmatning (antal val) kan vara maximalt 9.
Vid varje användarinmatning läggs en till tills vi når 9.
Efter varje användarinmatning läggs en tur till. */
if(kontrolleraVinnar())return spelerVal;
/* Kontrollerar först om urvalet resulterar i en vinnare.
Om inte, återgår den till nästa spelares val*/
if(spelerVal == 1) spelerVal = 2;
else spelerVal = 1;
// Växlar mellan spelare 1 och spelare 2
do {
printf("Spelar %d, ditt Val: ", spelarVal);
scanf("%i", &val);
merk = (spelerVal == 1) ? 'X' : 'O';
} while (!kontrolleraSpel(val));
gBrett[val-1] = merk;
} return 0;
}
// looper tills 9 val görs, oavgjort eller en spelare vinner
Programmet kompilerar inte.
Nu ska det vara Ok :)
#include <stdio.h> // printf, scanf
#include <stdbool.h> // bool
#include <ctype.h> // toupper
#define ANTRUTER 9 ///< Antal rutor på spelet
const int STRLEN = 80; ///< Textlengd
void resetSpel();
bool kontrolleraSpel(const int n);
bool kontrolleraVinnar();
void ritaSpel();
int spelSpelet();
char gBrett[ANTRUTER]; ///< spel.
/**
* Hovudprogram
*/
int main()
{
char spelar1[STRLEN];
char spelar2[STRLEN];
char nyttSpel; // Kör programmet / spelet EN gång till.
int vinnar; // Alla spelarnummer som har vunnit.
do {
resetSpel();
ritaSpel();
printf("\n\nNamn på spelar 1: "); gets(spelar1);
printf("Namn 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);
// 'vinner' == 0:
else printf("\nIngen vinner den här gången tyvärr.\n\n");
printf("\n\nEn ny omgång (N/J): ");
scanf(" %c", &nyttSpel); nyttSpel = toupper(nyttSpel);
getchar();
} while (nyttSpel == 'J');
return 0;
}
/* -------------------------------------------------------------------*/
void ritaSpel() {
printf("\n\t Tic Tac Toe \n");
printf("\t---1-----2-----3---\n");
printf("\t| %c | %c | %c |\n",gBrett[0], gBrett[1], gBrett[2]);
printf("\t---4-----5-----6---\n");
printf("\t| %c | %c | %c |\n",gBrett[3], gBrett[4], gBrett[5]);
printf("\t---7-----8-----9---\n");
printf("\t| %c | %c | %c |\n",gBrett[6], gBrett[7], gBrett[8]);
printf("\t-------------------\n");
}
/* -------------------------------------------------------------------*/
void resetSpel(){
for (int i = 0; i < ANTRUTER; i++)
gBrett[i] = ' '; //
}
// Återställer spel så att alla rutor är tomma.
/* -------------------------------------------------------------------*/
bool kontrolleraSpel(const int n){
if(gBrett[n-1]== ' '){
return 1;
}else return 0;
while(!(n < 1 || n > 9));
}
/* Kontrollerar om en plats är ledig eller upptagen.
n-1 för att kompensera för arrayen som börjar med noll,
men att spelet börjar med en */
/* -------------------------------------------------------------------*/
bool kontrolleraVinnar(){
if (gBrett [0] != ' ' && gBrett[0] == gBrett[1] && gBrett[1] == gBrett[2] )
return 1;
else if (gBrett [3] != ' ' && gBrett[3] == gBrett[4] && gBrett[4] == gBrett[5])
return 1;
else if (gBrett [6] != ' ' && gBrett[6] == gBrett[7] && gBrett[7] == gBrett[8])
return 1;
else if (gBrett [2] != ' ' && gBrett[2] == gBrett[5] && gBrett[5] == gBrett[8])
return 1;
else if (gBrett [1] != ' ' && gBrett[1] == gBrett[4] && gBrett[4] == gBrett[7])
return 1;
else if (gBrett [0] != ' ' && gBrett[0] == gBrett[3] && gBrett[3] == gBrett[6])
return 1;
else if (gBrett [2] != ' ' && gBrett[2] == gBrett[4] && gBrett[4] == gBrett[6])
return 1;
else if (gBrett [0] != ' ' && gBrett[0] == gBrett[4] && gBrett[4] == gBrett[8])
return 1;
else if (gBrett[0] != '1' && gBrett[1] != '2' && gBrett[2] != '3' &&
gBrett[3] != '4' && gBrett[4] != '5' && gBrett[5] != '6' && gBrett[6]
!= '7' && gBrett[7] != '8' && gBrett[8] != '9');
return 0;
}
/*Kontrollerar alla möjliga kombinationer, dvs horisontell, horisontell och tvär.
Totalt 8 möjligheter.
Om någon av dem är lika, exklusive blank, indikeras true för alla
och en spelare vinnar*/
/* -------------------------------------------------------------------*/
int spelSpelet(){ //namnpå funktion.
int spelarVal = 1; //Indikerar om det är spelare 1 eller spelare 2:s val.
int antalVal = 0; // börjar med 0.
char val; //Tallet bruker taser inn lagres her som valg.
char merk; //Markera med X eller O.
while (antalVal < 9){
ritaSpel();
antalVal++;
/* Indikerar att användarinmatning (antal val) kan vara maximalt 9.
Vid varje användarinmatning läggs en till tills vi når 9.
Efter varje användarinmatning läggs en tur till. */
if(kontrolleraVinnar())return spelarVal;
/* Kontrollerar först om urvalet resulterar i en vinnare.
Om inte, återgår den till nästa spelares val*/
if(spelarVal == 1) spelarVal = 2;
else spelarVal = 1;
// Växlar mellan spelare 1 och spelare 2
do {
printf("Spelar %d, ditt Val: ", spelarVal);
scanf("%i", &val);
merk = (spelarVal == 1) ? 'X' : 'O';
} while (!kontrolleraSpel(val));
gBrett[val-1] = merk;
} return 0;
}
Koden kompilerar inte.
Varför har du en vinner och en vinnar variabel?
spelerVal? Inte initialiserat.
Du kan behöva sätta brytpunkter och/eller göra spårutskrifter för att se vad som händer.
Det jag kan se är att denna kod troligen inte gör vad du förväntar dig att den ska göra:
else if (gBrett[0] != '1' && gBrett[1] != '2' && gBrett[2] != '3' &&
gBrett[3] != '4' && gBrett[4] != '5' && gBrett[5] != '6' && gBrett[6]
!= '7' && gBrett[7] != '8' && gBrett[8] != '9'); /* <-- detta semikolon ska troligen inte finnas här */
return 0;
/* här behöver du troligen en else-sats med en return */
Lös detta
Tänk på att main använder bland annat resetSpel() innan resetSpel är initialiserad. Så fungerar inte kompilatorn i C. Lägg main längst ner isf.
Det ser ut som om @beerger inte kompilerat det senaste programmet som därför verkar ha för många fel och varningar. Kompilerar man det senast programmet finns inga syntaxfel men dock varningar om logiska fel. Ta för vana att skriva lite kod, kompilera, åtgärda alla fel, åtgärda alla varningar, skriv testkod, testa och repetera detta tills dess du har ett fungerande program.
Några fler tips:
Denna kodrad (72?) kommer aldrig att exekveras och bör tas bort: while(!(n < 1 || n > 9));
Funktionen kontrolleraSpel()
har returtypen bool
och då bör den returnera true
eller false
(inte numeriska värden).
Funktionen kontrolleraVinnar()
har returtypen bool
och då bör den returnera true
eller false
(inte numeriska värden). Den kan skrivas kortare som jag tidigare visat i denna tråd.
Lindehaven skrev:Det ser ut som om @beerger inte kompilerat det senaste programmet som därför verkar ha för många fel och varningar. Kompilerar man det senast programmet finns inga syntaxfel men dock varningar om logiska fel. Ta för vana att skriva lite kod, kompilera, åtgärda alla fel, åtgärda alla varningar, skriv testkod, testa och repetera detta tills dess du har ett fungerande program.
Några fler tips:
Denna kodrad (72?) kommer aldrig att exekveras och bör tas bort:
while(!(n < 1 || n > 9));
Funktionen
kontrolleraSpel()
har returtypenbool
och då bör den returneratrue
ellerfalse
(inte numeriska värden).Funktionen
kontrolleraVinnar()
har returtypenbool
och då bör den returneratrue
ellerfalse
(inte numeriska värden). Den kan skrivas kortare som jag tidigare visat i denna tråd.
Oj, måste ha råkat kopierat in ursprungskoden på något vänster. Här är de varningar man får nu iaf.
Tack, gjorde alt ni sa och nu fungerar den :)
Med tydligen, så var det att på sluttet så var val en "char" och inte "int". Jag ändrade til int och da fungerade det.
Men en fråga, varför fungerade inte som "char val"? det läste ju in när jag tastade et tal?
Lindehaven skrev:Det ser ut som om @beerger inte kompilerat det senaste programmet som därför verkar ha för många fel och varningar. Kompilerar man det senast programmet finns inga syntaxfel men dock varningar om logiska fel. Ta för vana att skriva lite kod, kompilera, åtgärda alla fel, åtgärda alla varningar, skriv testkod, testa och repetera detta tills dess du har ett fungerande program.
Några fler tips:
Denna kodrad (72?) kommer aldrig att exekveras och bör tas bort:
while(!(n < 1 || n > 9));
Funktionen
kontrolleraSpel()
har returtypenbool
och då bör den returneratrue
ellerfalse
(inte numeriska värden).Funktionen
kontrolleraVinnar()
har returtypenbool
och då bör den returneratrue
ellerfalse
(inte numeriska värden). Den kan skrivas kortare som jag tidigare visat i denna tråd.
while(!(n < 1 || n > 9));
om jag inte har det, så kan ju spelar skriva in tex 10. alltså ogiltiga tal. Hur annars ska jag göra så at spelar inte kan göra det?
Kanske blir tydligare med denna indentering och kommentarer:
bool kontrolleraSpel(const int n)
{
if(gBrett[n-1]== ' ')
return 1; /* Borde vara return true; eftersom funktionen är bool */
else
return 0; /* Borde vara return false; eftersom funktionen är bool */
/* En av ovanstående return kommer alltid att exekveras vilket innebär att nästa kodrad aldrig kommer att exekvera */
while(!(n < 1 || n > 9));
}
EDIT: Jag skulle ha skrivit funktionen lite kortare, så här:
bool kontrolleraSpel(const int n)
{
return (gBrett[n-1] == ' ');
}
Har du provat att ange en bokstav istället för siffra? Då händer något, prova o försök se varför det blir som det blir
ah men det gick nu. en annan problem är att spelar 2 börjar först. Men spelar 1 borde börja spelet.
jag testade med
spelarVal = (spelarVal == 1) ? 1 : 2;
och
spelarVal = (spelarVal % 1) ? 1 : 2;
Men båda blir också fel...
int spelarVal = 0;
/* ...annan kod...*/
while (antalVal < 9)
{
/* ...annan kod...*/
spelarVal = (1 + spelarVal % 2);
Att skriva %1 är ett fel jag också gör ibland. Det är i stort sett alltid fel.
Men dina försök (om man rättar det andra) sätter spelarVal till 1 om det är 1, och 2 om det är 2, dvs. ändrar aldrig.