22 svar
343 visningar
HiMate123 352
Postad: 21 okt 2021 21:25

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;
Lindehaven 820 – Lärare
Postad: 21 okt 2021 21:58

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.

Laguna Online 30713
Postad: 21 okt 2021 22:01

Att en funktion som är deklarerad som bool returnerar tre olika värden är konstigt.

HiMate123 352
Postad: 21 okt 2021 22:03 Redigerad: 21 okt 2021 22:07
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 ?

HiMate123 352
Postad: 21 okt 2021 22:05
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..?

Laguna Online 30713
Postad: 21 okt 2021 22:06

true/falsk är väl två värden. Vad ska det tredje värdet betyda?

Lindehaven 820 – Lärare
Postad: 22 okt 2021 10:06

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';
HiMate123 352
Postad: 22 okt 2021 11:29

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;
HiMate123 352
Postad: 22 okt 2021 11:33

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] = ' ')

}
HiMate123 352
Postad: 22 okt 2021 11:52 Redigerad: 22 okt 2021 12:13
    #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. 

Lindehaven 820 – Lärare
Postad: 22 okt 2021 14:02 Redigerad: 22 okt 2021 14:06

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.

HiMate123 352
Postad: 22 okt 2021 14:17
Lindehaven skrev:

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 */
            );
}

 

Ska jag ha dom värdene efter return? 

Lindehaven 820 – Lärare
Postad: 22 okt 2021 14:19

Ja, mellan parenteserna för return, som mitt kodexempel visar. Jag antog att du känner till logiska operatorer.

HiMate123 352
Postad: 22 okt 2021 14:20

Och varför är det bara [0], [3], [6] osv som inte kan vara '  '. 
Måste jag inte ha alla tall  [1] != ' ' ?

Lindehaven 820 – Lärare
Postad: 22 okt 2021 14:52

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.

HiMate123 352
Postad: 22 okt 2021 16:07 Redigerad: 22 okt 2021 16:08

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] = ' ';
}
HiMate123 352
Postad: 22 okt 2021 16:16

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...
Lindehaven 820 – Lärare
Postad: 23 okt 2021 11:55

Prova att kompilera. Läs sedan vad jag tidigare skrev om ANTRUTER och gSpel.

HiMate123 352
Postad: 23 okt 2021 14:13

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? 

HiMate123 352
Postad: 23 okt 2021 14:39

den bool kontrolleraVinnar blir bara errors.. Fattar inte hur den kan bli riktig när den är skrevet så :(

Lindehaven 820 – Lärare
Postad: 23 okt 2021 22:29

Rätta kompileringsfelen ett efter ett. Till slut är det inga kvar. 

HiMate123 352
Postad: 24 okt 2021 14:46

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])
            )
}
Lindehaven 820 – Lärare
Postad: 24 okt 2021 19:58

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.

Svara
Close