Ik ben bezig een spelletje in Delphi uit te werken. Het spel heet Kat & Muis en wordt gespeeld op een dambord. Op het bord staan 4 zwarte stenen (de katten), en 1 witte steen (de muis). De muis moet naar de overkant zien door te breken. Als de muis wordt ingesloten door de katten heeft de muis verloren!
Om de computer (de katten) een zet te kunnen laten bepalen wil ik steeds alle mogelijke zetten doorlopen in een tree. De lange paden zijn gunstig voor de kat, de korte paden zijn gunstig voor de muis. (althans dat heb ik bedacht)
Ik heb de volgende recursieve functie in elkaar gedraaid die de tree zou moeten opbouwen. De inbounds functie kan bepalen of een volgende zet een geldige positie oplevert. Waar ik nu tegen aanloop is dat de recursieve functie maar blijft lopen als ik hem niet 'begrens' met een level. Ik denk dat dat komt omdat op een gegeven moment de muis geen zetten meer kan doen, maar de kat daarna weer een zet doet zodat de muis weer een vrije mogelijkheid heeft en zo tot in lengte van dagen (of in ieder geval tot de stack overflow
). Daarbij heb ik dadelijk wel een boompje, maar wat moet ik doen om de boom weer van te kunnen doorlopen? Daar heb ik nu volgens mij geen voorzieningen voor!
Op een bord van 8x8 heb ik 32 zwarte vakjes. Dat zijn de enige vakjes waar stenen op kunnen staan.
Welk vakje bezet is door welke steen houd ik bij in Board: Array of TSteen ;
Om de computer (de katten) een zet te kunnen laten bepalen wil ik steeds alle mogelijke zetten doorlopen in een tree. De lange paden zijn gunstig voor de kat, de korte paden zijn gunstig voor de muis. (althans dat heb ik bedacht)
Ik heb de volgende recursieve functie in elkaar gedraaid die de tree zou moeten opbouwen. De inbounds functie kan bepalen of een volgende zet een geldige positie oplevert. Waar ik nu tegen aanloop is dat de recursieve functie maar blijft lopen als ik hem niet 'begrens' met een level. Ik denk dat dat komt omdat op een gegeven moment de muis geen zetten meer kan doen, maar de kat daarna weer een zet doet zodat de muis weer een vrije mogelijkheid heeft en zo tot in lengte van dagen (of in ieder geval tot de stack overflow
Op een bord van 8x8 heb ik 32 zwarte vakjes. Dat zijn de enige vakjes waar stenen op kunnen staan.
Welk vakje bezet is door welke steen houd ik bij in Board: Array of TSteen ;
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| type TSteen = (sGeen, sKat, sMuis ); TGameBoard = class private NowPlaying: TSteen; // de soort speler (kat of muis) dat aan de beurt is Size: Integer; // de grootte van het bord MoveCount: integer; Moves: array[0..64] of record FromCol : integer; FromRow : integer; ToCol : integer; ToRow : integer; end; public Board: Array of TSteen ; function ToPos(Col, Row: Integer ): Integer ; // functie die de column en rij van een vak omrekent naar het vaknummer procedure SetupNewBoard ; procedure Write( Col, Row: Integer; Steen: TSteen); function Read( Col, Row: Integer ): TSteen; procedure DoMove( ColFrom, RowFrom, ColTo, RowTo: Integer ); procedure _DoMove( PosFrom, PosTo: Integer ); procedure UndoMove; function CheckMove( ColFrom, RowFrom, ColTo, RowTo: Integer ): Boolean; function LegalMoves(ACol, ARow: integer): Boolean; function Inbounds(ACol, ARow: integer): Boolean; constructor Create; end; TNode = class Board: TGameBoard; Level: integer; LastMove: TPoint; procedure Assign(Node: TNode); end; function TfMain.Search(Node: TNode): integer; var Foo: TNode; Value, Temp: integer; i, j: integer; begin if Node.Level mod 2 = 1 then begin Node.Board.NowPlaying := sKat; end else begin Node.Board.NowPlaying := sMuis; end; for i := 0 to Pred(Node.Board.Size) do for j := 0 to Pred(Node.Board.Size) do if Odd(i+j) and (Node.Board.Board[Node.Board.ToPos(i, j)] = Node.Board.NowPlaying) then Node.Board.LegalMoves(i, j); // genereer een lijst van legal moves voor deze steen if Node.Board.MoveCount > 0 then begin for i := 0 to Node.Board.MoveCount do begin Foo := TNode.Create; // een nieuwe child creeren Foo.Assign(Node); Inc(Foo.Level); Foo.Board.DoMove(Node.Board.Moves[i].FromCol, Node.Board.Moves[i].FromRow, Node.Board.Moves[i].ToCol, Node.Board.Moves[i].ToRow); // de move uitvoeren op de nieuwe node Foo.LastMove.x := Node.Board.Moves[i].FromCol; Foo.LastMove.y := Node.Board.Moves[i].FromRow; // anders stapt ie heen en weer if (Node.LastMove.x <> Node.Board.Moves[i].ToCol) and (Node.LastMove.y <> Node.Board.Moves[i].ToRow) and (Node.Level < 20) then Search(Foo); end; end; |
[ Voor 7% gewijzigd door wizl op 03-04-2005 19:34 ]