Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Ristinollan tekeminen

juhab [31.03.2011 23:30:34]

#

onko yksinkertaisempia tapoja tehdä seuraava:

RISTINOLLA

/*Ruudun tarkistus ja/tai valinta*/

Valitse numerolla ruutu jonka haluat valita:

|---|---|---|
| 1 | 2 | 3 |
|---|---|---|
| 4 | 5 | 6 |
|---|---|---|
| 7 | 8 | 9 |
|---|---|---|

Valitsemasi ruudun numero: 1
#define TYHJA 0
#define RISTI 1
#define NOLLA 2
#define YY 1
#define KAA 2
#define KOO 3
#define NEE 4
#define VII 5
#define KUU 6
#define SEE 7
#define KASI 8
#define YSI 9

void main(void)

{

int ruutu1 = 0;
int ruutu2 = 0;
int ruutu3 = 0;
int ruutu4 = 0;
int ruutu5 = 0;
int ruutu6 = 0;
int ruutu7 = 0;
int ruutu8 = 0;
int ruutu9 = 0;
int ruudun_valinta = 0;

printf("Anna ruudun numero, jonka haluat valita:");
scanf("%d",&ruudun_valinta);


if (ruudun_valinta == YY)
	{

	if (ruutu1 == TYHJA)
		{
		ruutu1 = RISTI;
		printf("|---|---|---|\n| X | 2 | 3 |\n| 4 | jnejne..");
		printf("Ruutu 1 on nyt X, valitse valitse seuraava ruutu:\n");
		scanf("%d",&ruudun_valinta);
		}
	else if (ruutu1 == RISTI)
		{
		ruutu1 = RISTI;
		printf("|---|---|---|\n| X | 2 | 3 |\n| 4 | jnejne..\n");
		printf("Ruutu 1 on jo X, valitse toinen\n");
		scanf("%d",&ruudun_valinta);
		}
	else
		{
		ruutu1 = NOLLA;
		printf("|---|---|---|\n| O | 2 | 3 |\n| 4 | jnejne..\n");
		printf("Ruutu 1 on O, valitse toinen\n");
		scanf("%d",&ruudun_valinta);
		}
	}

if (ruudun_valinta == KAA)
	{

	if (ruutu2 == TYHJA)
		{
		printf("|---|---|---|\n| X | 2 | 3 |\n| 4 | jnejne..");
		printf("Ruutu 1 on nyt X, valitse valitse seuraava ruutu:\n");
		scanf("%d",&ruudun_valinta);
		}
	else if (ruutu1 == RISTI)
		{
		printf("|---|---|---|\n| X | 2 | 3 |\n| 4 | jnejne..\n");
		printf("Ruutu 1 on jo X, valitse toinen\n");
		scanf("%d",&ruudun_valinta);
		}
	else
		{
		printf("|---|---|---|\n| O | 2 | 3 |\n| 4 | jnejne..\n");
		printf("Ruutu 1 on O, valitse toinen\n");
		scanf("%d",&ruudun_valinta);
		}
	}


}

Mod. lisäsi kooditagit.

Mizou [31.03.2011 23:39:58]

#

En nyt ehdi kummempia miettimään, mutta pari yleistä juttua näin pikaisesti:

ps. Kooditagit jatkossa kiitos

jalski [01.04.2011 00:01:50]

#

Pistä tuo pelilauta 2-ulotteiseen taulukkoon. Taulukosta kannattaa tehdä pari ruutua isompi, kuin pelilauta on ja laittaa pelilaudan ympärille kehys helpottamaan voittotilanteen vertailua.

Torgo [01.04.2011 11:31:47]

#

@jalski: Miksi 2-ulotteiseen? Tavallisella taulukolla alkio on suoraan ruudun_nro-1 tai jos alkuun laittaa dummy-alkion, niin suoraan ruudun_nro. 2-ulotteisella taulukolla tehtäisiin käytännössä n-määrä tavallisia taulukoita ja ruudun numeron perusteella pitäisi aina erikseen laskea minkä taulukon mikäkin alkio on kyseessä. Voittajan löytäminen on joka tapauksessa triviaalia. Kehyksistä ei saada tässä tapauksessa mitään etua.

Eli tee ihan tavallinen 9- tai 10-alkioinen taulukko ja lue arvot siihen silmukassa. Ei peräkkäin kuten teet nyt. Jotain tähän tapaan:

typedef enum pelaaja_t { TYHJA, RISTI, NOLLA, VAIHDA } pelaaja_t;

// ...

int ruudun_valinta;
pelaaja_t ruutu[10] = {TYHJA};
pelaaja_t voittaja = TYHJA;
pelaaja_t pelaaja = RISTI;
while( voittaja == TYHJA ) {
    // Tässä pitää tietenkin vielä tarkistaa lisäksi, että ruutu on laillinen ja tyhjä
    scanf("%d",&ruudun_valinta);
    ruutu[ruudun_valinta] = pelaaja;
    pelaaja ^= VAIHDA;    // Vaihdetaan pelaaja rististä nollaksi ja päinvastoin
    tulosta_peli(ruutu);
    voittaja = tarkasta_voittaja(ruutu);
}
printf("Pelin voitti %s.\n", (voittaja==RISTI ? "risti" : "nolla"));

jalski [01.04.2011 11:55:27]

#

Torgo kirjoitti:

@jalski: Miksi 2-ulotteiseen? Tavallisella taulukolla alkio on suoraan ruudun_nro-1 tai jos alkuun laittaa dummy-alkion, niin suoraan ruudun_nro. 2-ulotteisella taulukolla tehtäisiin käytännössä n-määrä tavallisia taulukoita ja ruudun numeron perusteella pitäisi aina erikseen laskea minkä taulukon mikäkin alkio on kyseessä. Voittajan löytäminen on joka tapauksessa triviaalia. Kehyksistä ei saada tässä tapauksessa mitään etua.

Mitä, jos tuota toteutusta haluaisi laajentaa ja sallia vaikka 20 kertaisen pelialueen ja vaatia voittoon aina viiden suora? Entä, jos lisää grafiikat ja tuen syötteeseen hiireltä?

Mielestäni on loogista ja helppoa käsitellä ruudun koordinaatteja x,y pareina. Vai kumpi on mukavampi lukea:

board[x][y]

vai

board[(y * WIDTH) + x]

Ja mitä tuohon pelilaudan ympäröimiseen kehyksellä tulee, niin miksi tehdä tarkistuksessa useampi tarkastus/ruutu, kun yhdelläkin pärjää? Kehyshän katkaisee aina vertailusilmukan, eikä ole tarvetta erikseen tarkastaa taulukon indeksejä.

Torgo [01.04.2011 12:28:51]

#

jalski kirjoitti:

Mitä, jos tuota toteutusta haluaisi laajentaa ja sallia vaikka 20 kertaisen pelialueen ja vaatia voittoon aina viiden suora? Entä, jos lisää grafiikat ja tuen syötteeseen hiireltä?

Niin mitä sitten?

jalski kirjoitti:

kumpi on mukavampi lukea:

board[frame_w + ruudun_valinta % WIDTH][frame_w + (ruudun_valinta-1) / WIDTH]

vai

board[ruudun_valinta]

jalski kirjoitti:

Kehyshän katkaisee aina vertailusilmukan, eikä ole tarvetta erikseen tarkastaa taulukon indeksejä.

Ensinnäkään esimerkkitapauksessa ei edes tarvitse tarkastella indeksejä. Dynaamisesti skaalautuvassa yleistapauksessakaan se ei mitään katkaise. Joka tapauksessa joudutaan tarkastamaan ollaanko kehyksellä vai ei.

Edit. Unohda tuo. Se oli vain kahvin puutetta. :) Oikeasssa olet tuon kehyksen suhteen siinä, että se säästää yhden vertailun, koska kyseinen vertailu voidaan aina lopettaa jos alkio on TYHJA (oli se sitten kehyksellä tai pelialueella). Kyseinen esimerkkitapaus menee silti näppärämmin ilman kehyksiä ja tuota ruudun valintaa se monimutkaistaa.

juhab [11.04.2011 18:23:53]

#

Kiitos kaikista vastauksista. Yritän lukea lisää kaikista silmukoista sun muista jotta itsekkin oppisin ymmärtämään tämän pelin paremmin :)

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta