
Het grootste verschil in deze versie is dat je nu ook tegen de computer kan spelen!!
Jaja, niet langer enkel tegen jezelf (of een ander slachtoffer) spelen, de PC is er voor je

Dit is nog maar de eerste versie van mijn computertegenstander en hij doet af en toe nog al eens wat domme zetten, maar geen paniek, hij wordt af an toe nog wel eens geüpdate

OXO.Mod
Code: Select all
(*
Description: Een OXO spelletje
Author: Nick De Frangh
Date Created: 10/01/2006
Versie : 2.0
*)
MODULE OXO;
IMPORT
OutExt, In, Input, Files, RandomNumbers;
TYPE
Speler =
RECORD
Naam : ARRAY 20 OF CHAR;
Score : INTEGER;
Kleur : INTEGER;
END;
SpelerPointer = POINTER TO SpelerArr;
SpelerArr = ARRAY OF Speler;
Celeig =
RECORD
character : CHAR;
kleur : INTEGER;
END;
BordPointer = POINTER TO BordArr;
BordArr = ARRAY OF Celeig;
AIBordPointer = POINTER TO AIBordArr;
AIBordArr = ARRAY OF INTEGER;
VAR
breedte: INTEGER;
lengte: INTEGER;
speelbord : BordPointer;
AI : AIBordPointer;
beurt : INTEGER;
speler : SpelerPointer;
aantal : INTEGER;
totaal: INTEGER;
zetten: INTEGER;
winnaar: Speler;
PROCEDURE StartNew*;
VAR
x, y, z: INTEGER;
BEGIN
In.Open();
OutExt.Open();
OutExt.Clear;
In.Int(breedte);
In.Int(lengte);
In.Int(aantal);
NEW(speler, aantal);
DEC(aantal);
NEW(speelbord, (breedte * lengte));
NEW(AI, (breedte * lengte));
FOR z := 0 TO aantal DO
In.String(speler^[z].Naam);
speler^[z].Score := 0;
speler^[z].Kleur := (z + 7);
END;
FOR y := 0 TO ((lengte * breedte) - 1) DO
speelbord^[y].character := ".";
speelbord^[y].kleur := 12;
END;
totaal := 0;
zetten := 0;
Print;
END StartNew;
PROCEDURE Print*;
VAR
x, y, z, count : INTEGER;
temp : CHAR;
bestandsnaam : ARRAY 30 OF CHAR;
BEGIN
OutExt.Clear;
OutExt.String(" ");
FOR z := 0 TO (breedte - 1) DO
OutExt.String("+---");
END;
OutExt.String("+"); OutExt.Ln;
count := 0;
FOR y := 0 TO (lengte - 1) DO
OutExt.Int((lengte - y - 1), 2);
OutExt.String(" |");
FOR x := 0 TO (breedte - 1) DO
OutExt.Char(" ");
OutExt.Color(speelbord^[count].kleur);
OutExt.Char(speelbord^[count].character);
OutExt.Color(15);
OutExt.String(" |");
INC(count);
END;
OutExt.Ln;
OutExt.String(" ");
FOR z := 0 TO (breedte - 1) DO
OutExt.String("+---");
END;
OutExt.String("+"); OutExt.Ln;
END;
OutExt.String(" ");
FOR z := 0 TO (breedte - 1) DO
OutExt.Int(z, 1);
OutExt.String(" ");
END;
OutExt.Ln; OutExt.Ln;
FOR z := 0 TO aantal DO
OutExt.Color(speler^[z].Kleur);
OutExt.String(speler^[z].Naam);
OutExt.String(": ");
OutExt.Int(speler^[z].Score, 2);
OutExt.Ln;
END;
OutExt.Color(15);
OutExt.Ln;
IF (zetten # (breedte * lengte)) & (speler^[beurt].Naam # "PC") THEN
OutExt.String("De Volgende beurt is voor: ");
OutExt.Color(speler^[beurt].Kleur);
OutExt.String(speler^[beurt].Naam);
OutExt.Color(12);
OutExt.Ln; OutExt.Ln;
OutExt.String(" - Druk op 'P' voor Pauze"); OutExt.Ln;
OutExt.String(" - Druk op 'S' om te saven"); OutExt.Ln;
OutExt.String(" - Druk op een andere toets om de volgende zet te beginnen"); OutExt.Ln;
OutExt.Color(15);
Input.Read(temp);
IF (temp = "p") OR (temp = "P") THEN
OutExt.String(" Het spel is gepauzeerd"); OutExt.Ln;
OutExt.String(" Voer een commando uit in de Tool file om verder te gaan"); OutExt.Ln;
ELSIF (temp = "s") OR (temp = "S") THEN
OutExt.Clear;
OutExt.String("Geef een naam in onder welke je het bestand wil opslaan:"); OutExt.Ln;
OutExt.Color(12);
OutExt.String(" (druk op enter om je naam te bevestigen)"); OutExt.Ln;
OutExt.Color(15);
x := 0;
LOOP
Input.Read(bestandsnaam[x]);
IF (ORD(bestandsnaam[x]) = 13) THEN
bestandsnaam[x] := 0X;
OutExt.Ln;
EXIT;
END;
OutExt.Char(bestandsnaam[x]);
INC(x);
END;
Save(bestandsnaam);
ELSE
Zet;
END;
ELSIF (zetten # (breedte * lengte)) & (speler^[beurt].Naam = "PC") THEN
ComputerMove;
ELSE
winnaar := speler^[0];
FOR x := 1 TO aantal DO
IF speler^[x].Score > winnaar.Score THEN
winnaar := speler^[x];
END;
END;
OutExt.String("Het spel is be’ndigd!"); OutExt.Ln;
OutExt.String(" De winnaar is:"); OutExt.Ln;
OutExt.Color(winnaar.Kleur);
OutExt.String(" "); OutExt.String(winnaar.Naam); OutExt.Ln;
OutExt.Color(15);
OutExt.String(" Met een score van:"); OutExt.Ln;
OutExt.Color(winnaar.Kleur);
OutExt.String(" "); OutExt.Int(winnaar.Score, 0); OutExt.Ln;
OutExt.Color(15);
END;
END Print;
PROCEDURE Zet*;
VAR
x, coord1, coord2, tempcoord : INTEGER;
temp, symbool : CHAR;
done : BOOLEAN;
mult : INTEGER;
BEGIN
OutExt.Ln;
x := 0;
done := FALSE;
REPEAT
IF x = 0 THEN
OutExt.String("Geef je symbool in:"); OutExt.Ln;
Input.Read(symbool);
IF (ORD(symbool) # 79) & (ORD(symbool) # 88) & (ORD(symbool) # 111) & (ORD(symbool) # 120) THEN
OutExt.Color(1);
OutExt.String(" ERROR: Gelieve een X of een O in te geven, probeer opnieuw"); OutExt.Ln;
OutExt.Color(15);
ELSE
IF symbool = "x" THEN
symbool := "X";
ELSIF symbool = "o" THEN
symbool := "O";
END;
OutExt.String(" Je hebt volgend symbool gekozen: ");
OutExt.Char(symbool); OutExt.Ln;
INC(x);
END;
ELSE
IF x = 1 THEN
OutExt.String("Geef je eerste co„rdinaat op: "); OutExt.Ln;
OutExt.String(" ");
mult := 0;
coord1 := 0;
Input.Read(temp);
WHILE ORD(temp) # 13 DO
tempcoord := (ORD(temp) - 48);
OutExt.Int(tempcoord, 0);
coord1 := ((coord1 * (mult * 10)) + tempcoord);
INC(mult);
Input.Read(temp);
END;
OutExt.Ln;
ELSE
OutExt.String("Geef je tweede co„rdinaat op: "); OutExt.Ln;
OutExt.String(" ");
mult := 0;
coord2 := 0;
Input.Read(temp);
WHILE ORD(temp) # 13 DO
tempcoord := (ORD(temp) - 48);
OutExt.Int(tempcoord, 0);
coord2 := ((coord2 * (mult * 10)) + tempcoord);
INC(mult);
Input.Read(temp);
END;
OutExt.Ln;
coord2 := (lengte - coord2) - 1;
END;
IF (coord1 < 0) OR (coord1 > (breedte - 1)) THEN
OutExt.Color(1);
OutExt.String(" ERROR: Gelieve een getal van 0 tot ");
OutExt.Int((breedte - 1), 0);
OutExt.String(" in te geven"); OutExt.Ln;
OutExt.Color(15);
ELSIF (coord2 < 0) OR (coord2 > (lengte - 1)) THEN
OutExt.Color(1);
OutExt.String(" ERROR: Gelieve een getal van 0 tot ");
OutExt.Int((lengte - 1), 0);
OutExt.String(" in te geven"); OutExt.Ln;
OutExt.Color(15);
ELSE
IF x = 1 THEN
OutExt.String(" Je hebt volgende co„rdinaat in gegeven: ");
OutExt.Int(coord1, 0); OutExt.Ln;
INC(x);
ELSE
OutExt.String(" Je hebt volgende co„rdinaat in gegeven: ");
OutExt.Int((lengte - coord2), 0); OutExt.Ln;
INC(x);
END;
END;
END;
IF x = 3 THEN
IF speelbord^[(coord1 + (coord2 * breedte))].character # "." THEN
OutExt.Color(1);
OutExt.String(" ERROR: Er staat al een symbool op deze plaats!"); OutExt.Ln;
OutExt.Color(15);
x := 1;
ELSE
done := TRUE;
speelbord^[(coord1 + (coord2 * breedte))].character := symbool;
speelbord^[(coord1 + (coord2 * breedte))].kleur := (beurt + 7);
CheckScore;
INC(zetten);
END;
END;
UNTIL done;
Print;
END Zet;
PROCEDURE Opslaan*;
VAR
bestandsnaam : ARRAY 30 OF CHAR;
BEGIN
In.Open();
In.String(bestandsnaam);
Save(bestandsnaam);
END Opslaan;
PROCEDURE Save(bestandsnaam : ARRAY OF CHAR);
VAR
bestand: Files.File;
bestandLoper: Files.Rider;
temp, x, y: INTEGER;
BEGIN
IF bestandsnaam[0] = 0X THEN
OutExt.Clear;
OutExt.String("Geef een naam in onder welke je het bestand wil opslaan:"); OutExt.Ln;
OutExt.Color(12);
OutExt.String(" (druk op enter om je naam te bevestigen)"); OutExt.Ln;
OutExt.Color(15);
x := 0;
LOOP
Input.Read(bestandsnaam[x]);
IF (ORD(bestandsnaam[x]) = 13) THEN
bestandsnaam[x] := 0X;
OutExt.Ln;
EXIT;
END;
OutExt.Char(bestandsnaam[x]);
INC(x);
END;
Save(bestandsnaam);
ELSE
bestand := Files.New(bestandsnaam);
Files.Set(bestandLoper, bestand, 0);
Files.WriteInt(bestandLoper, breedte);
Files.WriteInt(bestandLoper, lengte);
Files.WriteInt(bestandLoper, aantal);
Files.WriteInt(bestandLoper, beurt);
Files.WriteInt(bestandLoper, totaal);
Files.WriteInt(bestandLoper, zetten);
FOR temp := 0 TO aantal DO
Files.WriteString(bestandLoper, speler^[temp].Naam);
Files.WriteInt(bestandLoper, speler^[temp].Score);
END;
FOR y := 0 TO ((breedte * lengte) - 1) DO
Files.WriteInt(bestandLoper, ORD(speelbord^[y].character));
Files.WriteInt(bestandLoper, speelbord^[y].kleur);
END;
Files.Register(bestand);
OutExt.String("Spel opgeslagen onder de naam: ");
OutExt.String(bestandsnaam);
END;
END Save;
PROCEDURE Laden*;
VAR
bestandsnaam : ARRAY 30 OF CHAR;
BEGIN
In.Open();
In.String(bestandsnaam);
Load(bestandsnaam);
END Laden;
PROCEDURE Load(bestandsnaam : ARRAY OF CHAR);
VAR
bestand: Files.File;
bestandLoper: Files.Rider;
temp, x, y: INTEGER;
BEGIN
IF bestandsnaam[0] = 0X THEN
OutExt.Clear;
OutExt.String("Geef de naam in van het bestand dat je wil openen:"); OutExt.Ln;
OutExt.Color(12);
OutExt.String(" (druk op enter om je naam te bevestigen)"); OutExt.Ln;
OutExt.Color(15);
x := 0;
LOOP
Input.Read(bestandsnaam[x]);
IF (ORD(bestandsnaam[x]) = 13) THEN
bestandsnaam[x] := 0X;
OutExt.Ln;
EXIT;
END;
OutExt.Char(bestandsnaam[x]);
INC(x);
END;
Load(bestandsnaam);
ELSE
bestand := Files.Old(bestandsnaam);
IF (bestand # NIL) THEN
Files.Set(bestandLoper, bestand, 0);
Files.ReadInt(bestandLoper, breedte);
Files.ReadInt(bestandLoper, lengte);
Files.ReadInt(bestandLoper, aantal);
Files.ReadInt(bestandLoper, beurt);
Files.ReadInt(bestandLoper, totaal);
Files.ReadInt(bestandLoper, zetten);
NEW(speelbord, (breedte * lengte));
NEW(speler, (aantal+1));
FOR temp := 0 TO aantal DO
Files.ReadString(bestandLoper, speler^[temp].Naam);
Files.ReadInt(bestandLoper, speler^[temp].Score);
speler^[temp].Kleur := (temp + 7);
END;
FOR y := 0 TO ((breedte * lengte) - 1) DO
Files.ReadInt(bestandLoper, temp);
speelbord^[y].character := CHR(temp);
Files.ReadInt(bestandLoper, speelbord^[y].kleur);
END;
OutExt.Open();
Print;
ELSE
OutExt.Open();
OutExt.Clear;
OutExt.String("Spel niet gevonden (");
OutExt.Color(1);
OutExt.String(bestandsnaam);
OutExt.Color(15);
OutExt.String(")");
OutExt.Ln();
END;
END;
END Load;
PROCEDURE CheckScore;
VAR
tempscore: INTEGER;
BEGIN
tempscore := totaal;
totaal := 0;
Horizontaal;
Verticaal;
DiagonaalLinks;
DiagonaalRechts;
speler^[beurt].Score := speler^[beurt].Score + (totaal - tempscore);
IF (totaal - tempscore) = 0 THEN
IF (beurt # aantal) THEN
INC(beurt);
ELSE
beurt := 0;
END;
END;
END CheckScore;
PROCEDURE Horizontaal;
VAR
x, y : INTEGER;
BEGIN
FOR y := 0 TO (lengte - 1) DO
FOR x := 0 TO (breedte - 3) DO
IF (speelbord^[((y*breedte) + x)].character = "O")
& (speelbord^[((y*breedte) + x) + 1].character = "X")
& (speelbord^[((y*breedte) + x) + 2].character = "O") THEN
INC(totaal);
END;
END;
x := x + 3;
END;
END Horizontaal;
PROCEDURE Verticaal;
VAR
x, y : INTEGER;
BEGIN
FOR y := 0 TO (lengte - 3) DO
FOR x := 0 TO (breedte - 1) DO
IF (speelbord^[((y*breedte) + x)].character = "O")
& (speelbord^[((y*breedte) + x + breedte)].character = "X")
& (speelbord^[((y*breedte) + x + (2 * breedte))].character = "O") THEN
INC(totaal);
END;
END;
END;
END Verticaal;
PROCEDURE DiagonaalLinks;
VAR
x, y : INTEGER;
BEGIN
FOR y := 2 TO (lengte - 1) DO
FOR x := 2 TO (breedte - 1) DO
IF (speelbord^[((y*breedte) + x)].character = "O")
& (speelbord^[((y*breedte) + x - (breedte + 1))].character = "X")
& (speelbord^[((y*breedte) + x - 2 * (breedte + 1))].character = "O") THEN
INC(totaal);
END;
END;
END;
END DiagonaalLinks;
PROCEDURE DiagonaalRechts;
VAR
x, y : INTEGER;
BEGIN
FOR y := 2 TO (lengte - 1) DO
FOR x := 0 TO (breedte - 3) DO
IF (speelbord^[((y*breedte) + x)].character = "O")
& (speelbord^[((y*breedte) + x - (breedte -1))].character = "X")
& (speelbord^[((y*breedte) + x - 2 * (breedte - 1))].character = "O") THEN
INC(totaal);
END;
END;
END;
END DiagonaalRechts;
PROCEDURE ComputerMove;
VAR
(* count : INTEGER; *)
x, y, positie, teken : LONGINT;
win : BOOLEAN;
BEGIN
SearchO;
SearchArea;
win := CheckWin(positie);
IF (win) THEN
speelbord^[positie].character := "O";
speelbord^[positie].kleur := (beurt + 7);
CheckScore;
INC(zetten);
ELSE
REPEAT
x := ENTIER(RandomNumbers.Uniform() * (breedte));
y := ENTIER(RandomNumbers.Uniform() * (lengte));
positie := ((y*breedte) + x);
UNTIL (speelbord^[positie].character = ".");
teken := ENTIER(RandomNumbers.Uniform() * 2);
IF teken = 0 THEN
speelbord^[positie].character := "O";
speelbord^[positie].kleur := (beurt + 7);
CheckScore;
INC(zetten);
ELSE
speelbord^[positie].character := "X";
speelbord^[positie].kleur := (beurt + 7);
CheckScore;
INC(zetten);
END;
END;
Print;
END ComputerMove;
PROCEDURE SearchO;
VAR
x, y: INTEGER;
BEGIN
FOR y := 0 TO (lengte - 1) DO
FOR x := 0 TO (breedte - 1) DO
IF (speelbord^[((y*breedte) + x)].character = "O") THEN
AI^[((y*breedte) + x)] := 1;
ELSE
AI^[((y*breedte) + x)] := 0;
END;
END;
END;
END SearchO;
PROCEDURE SearchArea;
VAR
x, y: INTEGER;
BEGIN
FOR y := 0 TO (lengte - 1) DO
FOR x := 0 TO (breedte - 1) DO
IF (AI^[((y*breedte) + x)] = 1) THEN
IF (x > 1) & (speelbord^[((y*breedte) + x) - 1].character = "X") & (speelbord^[((y*breedte) + x) - 2].character = ".") THEN (* Links *)
AI^[((y*breedte) + x) - 2] := 2;
END;
IF (x < (breedte - 2)) & (speelbord^[((y*breedte) + x) + 1].character = "X") & (speelbord^[((y*breedte) + x) + 2].character = ".") THEN (* rechts *)
AI^[((y*breedte) + x) + 2] := 2;
END;
IF (x > 1) & (y > 1) & (speelbord^[((y*breedte) + x) - (breedte + 1)].character = "X") & ((speelbord^[((y*breedte) + x) - 2 * (breedte + 1)].character = ".")) THEN (* Links boven*)
AI^[((y*breedte) + x) - 2 * (breedte + 1)] := 2;
END;
IF (x > 1) & (y < (lengte - 2)) & (speelbord^[((y*breedte) + x) + (breedte - 1)].character = "X") & (speelbord^[((y*breedte) + x) + 2 * (breedte - 1)].character = ".") THEN (* Links onder *)
AI^[((y*breedte) + x) + 2 * (breedte - 1)] := 2;
END;
IF (y > 1) & (speelbord^[((y*breedte) - breedte) - 1].character = "X") & (speelbord^[((y*breedte) + x) - 2 * breedte].character = ".") THEN (* boven *)
AI^[((y*breedte) + x) - 2 * breedte] := 2;
END;
IF (y < (lengte - 2)) & (speelbord^[((y*breedte) + x) + breedte].character = "X") & (speelbord^[((y*breedte) + x) + 2 * breedte].character = ".") THEN (* onder *)
AI^[((y*breedte) + x) + 2 * breedte] := 2;
END;
IF (x < (breedte - 2)) & (y > 1) & (speelbord^[((y*breedte) + x) - (breedte - 1)].character = "X") & (speelbord^[((y*breedte) + x) - 2 * (breedte - 1)].character = ".") THEN (* rechts boven *)
AI^[((y*breedte) + x) - 2 * (breedte - 1)] := 2;
END;
IF (x < (breedte - 2)) & ( y < (lengte - 2)) & (speelbord^[((y*breedte) + x) + (breedte + 1)].character = "X") & (speelbord^[((y*breedte) + x) + 2 *(breedte + 1)].character = ".") THEN (* Rechts onder *)
AI^[((y*breedte) + x) + 2 * (breedte + 1)] := 2;
END;
END;
END;
END;
END SearchArea;
PROCEDURE CheckWin(VAR positie: LONGINT) : BOOLEAN;
VAR x, y : INTEGER;
BEGIN
FOR y := 0 TO (lengte - 1) DO
FOR x := 0 TO (breedte - 1) DO
IF (AI^[((y*breedte) + x)] = 2) THEN
positie := ((y*breedte) + x);
RETURN(TRUE);
END;
END;
END;
RETURN(FALSE);
END CheckWin;
BEGIN
END OXO.
Code: Select all
(*
Description: Een OXO spelletje
Author: Nick De Frangh
Date Created: 10/01/2006
Versie : 2.0
----------------
Future features;
- Code verduidelijken en optimalizeren
- Hight scores bijhouden
- Speler kan kleur zelf kiezen?
- Verbeteren van AI
Suggesties: Mail naar Nickman@pandora.be
Of post op brandless
----------------
ChangeLog V2.0
- Minimale AI toegevoegd
----------------
ChangeLog V1.5.1
- Bug voor einde van het spel er uit gehaald
----------------
ChangeLog V1.5:
- Variabele veldgrootte (in te stellen via parameter)
- Raster verbeterd
- Output verbeterd
- Input intuitiever gemaakt
----------------
ChangeLog V1.3:
- Eind van het spel voorzien
- Elke speler heeft nu een eigen spelkleur
- Kleine code optimalizatie
- Output verbeterd
----------------
ChangeLog V1.2:
- Menu opties toegevoegd na elke zet
- Mogelijkheid om je spel na elke zet makkelijk te saven
- Kleuroutput voor reed ingegeven karakters
- bug voor negatieve scrore uitgehaald (vermoedelijk)
*)
Builder.Compile \s2
OutExt.Mod
OXO.Mod
~
Builder.Compile \f2*
System.Free
OXO.Mod
OutExt.Mod
OXO.StartNew 4 3 2 "Nickman" "PC"~
OXO.Zet
OXO.Opslaan "Nickman.sav"~
OXO.Laden "Nickman.sav"~
OXO.Print~
