logo

Kleurenschema: blauw - grijs


Tic tac toe

tictactoe

Boter, kaas en eieren

Op school speelde ik altijd boter, kaas en eieren met mijn buurman of buurvrouw. Ik doe het nog steeds graag. Om mijzelf te leren programmeren in C heb ik in 2004 een programma gemaakt waarmee je tegen de computer boter, kaas en eieren kunt spelen. Het programma is niet zo goed dat je helemaal niet kunt winnen, want ergens in het doorberekenen gaat er nog iets fout (er is geen echte recursie). En dat laat ik zo - het was tenslotte slechts een leeroefening. Hieronder zie je de broncode en je kunt zowel de source als de binary downloaden. Maar als je een mooie interface wilt en lekker online wilt spelen, kun je beter naar http://boulter.com/ttt/index.cgi gaan. Onderstaande code werd via www.bedaux.net/cpp2html van kleur voorzien.


#include <stdio.h>
#include <stdlib.h>

// protos
void resetveld();
void zet (int x, int y, int speler);
void tekenveld();
int evalueer (int verbose);
int evalueer_status (int status1, int status2, int verbose);
int vol();
void ai (int speler);

// vars
char titel[] = "Boter, kaas, en eieren!";
int veld[3][3];
int speler;

int main()
{
	int x, y;
	int spel;
	int doorgaan;
	int ch;
	
	begin:
	
	spel = 0;
	resetveld();
	
	// net zolang doorspelen totdat een der spelers gewonnen heeft
	while ( ! spel )
	{
		// juiste speler bepalen
		if (speler != 1 && speler !=2 ) speler = 1;
				
		// speelveld op scherm tonen
		tekenveld();
		printf ("\n");
		
		// bereken een goede tegenzet
		////if (speler==2) ai(speler);
		ai(speler);
		
		// evalueer of er iemand gewonnen heeft
		spel = evalueer(1);
		
		// controleer of het veld niet vol is
		// (behalve als er al iemand gewonnen heeft)
		if ( ! spel ) spel = vol();
		
		// als het spel nog niet is afgelopen EN
		// als speler = 1, dan mag user nieuwe zet doen
		if ( (! spel) && speler==1 )
		////if ( ! spel )
		{
			// invoer door user
			printf ("\nspeler %d aan zet\n", speler);
			printf("x = "); scanf ("%d", &x);
			printf("y = "); scanf ("%d", &y);
			// eventueel exit
			if ( x==0 || y==0 ) goto end;
			// omrekenen naar interne coordinaten
			x--;
			y = -1 * y + 3;
			zet (x,y,speler);
		}
		
		//volgende speler is aan de beurt
		speler++;
	}
	
	// eindstand tonen
	tekenveld();
	printf ("\n");
	if (evalueer(1)==0) printf("\nGELIJK SPEL!\n");
	
	// nog een spel?
	printf ("\nNog een keer? (0=nee, 1-9=ja) ");
	scanf ("%d", &doorgaan); // hier zit een fout ofzo
	if (doorgaan!=0) goto begin;
	
	end:
	return 0;
}


void resetveld()
{
	// reset veld
	int x,y;
	for (x=0; x<3; x++)
	{
		for (y=0; y<3; y++)
		{
			veld[x][y] = 0;
		}
	}
}

void zet (int x, int y, int speler)
{
	veld[x][y] = speler;
}

void tekenveld()
{
	// clear screen
	system ("clear"); /* Or system ("cls"); for Win32 */
	
	// het veld op het scherm tekenen
	int x,y;
	printf("%s\n\n",titel);
	for (y=0; y<3; y++)
	{
		for (x=0; x<3; x++)
		{
			printf(" %d",veld[x][y]);
		}
		// newline
		printf("\n");
	}
}

int evalueer(int verbose)
{
	// als er drie op een rij staan, dan gewonnen
	// dat is als x=.., als y=.. of een diagonaal
	// returncodes:
	// 0 = geen winnaar
	// 1 = speler 1 heeft gewonnen
	// 2 = speler 2 heeft gewonnen
	
	int x,y;
	int status[3];
	int speler;
	int horizontaal, verticaal, diagonaal;
	int tempreturn = 0;
	
	// horizontaal
	if (verbose) printf ("HORIZONTAAL\n");
	for (y=0; y<3; y++)
	{
		// reset status
		for (speler=1; speler<3; speler++) status[speler] = 0;

		for (x=0; x<3; x++)
		{
			for (speler=1; speler<3; speler++) { if (veld[x][y]==speler) status[speler]++; }
		}
		if (verbose) printf ("y=%d: ", -1*y+3);
		horizontaal = evalueer_status (status[1], status[2], verbose);
		if (horizontaal>0) tempreturn = horizontaal;
	}
	
	// verticaal
	if (verbose) printf ("VERTICAAL\n");
	for (x=0; x<3; x++)
	{
		// reset status
		for (speler=1; speler<3; speler++) status[speler] = 0;
		
		for (y=0; y<3; y++)
		{
			for (speler=1; speler<3; speler++) { if (veld[x][y]==speler) status[speler]++; }
		}
		if (verbose) printf ("x=%d: ", x+1);
		verticaal = evalueer_status (status[1], status[2], verbose);
		if (verticaal>0) tempreturn = verticaal;
	}
	
	// diagonaal
	if (verbose) printf ("DIAGONAAL\n");
	// in de "\" richting
	// reset status
	for (speler=1; speler<3; speler++) status[speler] = 0;
	for (x=0; x<3; x++)
	{
		y = x;
		for (speler=1; speler<3; speler++) { if (veld[x][y]==speler) status[speler]++; }
	}
	if (verbose) printf (" \\ : ");
	diagonaal = evalueer_status (status[1], status[2], verbose);
	if (diagonaal>0) tempreturn = diagonaal;
	// in de "/" richting
	// reset status
	for (speler=1; speler<3; speler++) status[speler] = 0;
	for (x=0; x<3; x++)
	{
		y = -1 * x + 2;
		for (speler=1; speler<3; speler++) { if (veld[x][y]==speler) status[speler]++; }
	}
	if (verbose) printf (" / : ");
	diagonaal = evalueer_status (status[1], status[2], verbose);
	if (diagonaal>0) tempreturn = diagonaal;
	
	// return 'tempreturn' value
	return tempreturn;
}

int evalueer_status (int status1, int status2, int verbose)
{
	// is een subfunctie van de functie evalueer()
	// returncodes:
	// 0 = geen winnaar
	// 1 = speler 1 heeft gewonnen
	// 2 = speler 2 heeft gewonnen
	
	int tempreturn = 0;
	int status[3];
	int speler;
	
	status[1] = status1;
	status[2] = status2;
	
	for (speler=1; speler<3; speler++)
	{
		if (status[speler] == 3)
		{
			if (verbose) printf ("SPELER %d HEEFT GEWONNEN\n", speler);
			tempreturn = speler;
		}
	}
	
	if (tempreturn==0 && verbose==1 ) printf ("nog geen winnaar\n");
	
	// return 'tempreturn' value
	return tempreturn;
}

int vol()
{
	// controleer of het veld wel of niet vol is
	// returncodes:
	// 0 = nog ruimte
	// 1 = vol
	
	int x,y;
	int counter = 0;
	
	// tellen
	for (x=0; x<3; x++)
	{
		for (y=0; y<3; y++)
		{
			if (veld[x][y]) counter++;
		}
	}
	
	// 9 velden is vol
	if (counter==9) return 1;
	else return 0;
}

void ai(int speler)
{
	// Artificial Intellegence
	// this function calculates a smart move
	
	int veldkopie[3][3];
	int lijst[10], xtip[10], ytip[10];
	int i;
	int x, y;
	int resultaat, gezet, score;
	int vijand;
	
	// bepaal vijand
	if (speler==1) vijand=2; else vijand=1;
	
	// kopieer veld[] naar veldkopie[]
	for (x=0; x<3; x++)
	{
		for (y=0; y<3; y++)
		{
			veldkopie[x][y] = veld[x][y];
		}
	}
		
	// maak een lijst met zetten, en bereken voor elke zet of dat winst of verlies oplevert
	// 0 = onuitvoerbaar, 1 = geen winst of verlies, 2 = positieverbetering, 3 = verlies voorkomen, 4 = winnende zet
	i=0;
	for (x=0; x<3; x++)
	{
		for (y=0; y<3; y++)
		{
			if ( veld[x][y] ) lijst[i] = 0; // veld is bezet
			// vijandelijke winnende zetten vinden
			if ( ! veld[x][y] ) // veldvak mag nog niet bezet zijn
			{
				// proefzet doen
				zet(x,y,vijand);
				// als het voor [vijand] winst oplevert, 3 toekennen
				resultaat = evalueer(0);
				if ( resultaat == vijand ) lijst[i] = 3;
				else lijst[i] = 1;
				// bord herstellen
				zet(x,y,0);
			}
			// eigen winnende zetten vinden
			// (overschrijven vijandelijke winnende zetten)
			if ( ! veld[x][y] ) // veldvak mag nog niet bezet zijn
			{
				// proefzet doen
				zet(x,y,speler);
				// als het voor [speler] winst oplevert, 4 toekennen
				resultaat = evalueer(0);
				if
Evert Mouw
 | 
blog
 | 
sitemap