Kunstig Intelligens til Brætspillet Taiji - Danmarks Tekniske Universitet
Kunstig Intelligens til Brætspillet Taiji - Danmarks Tekniske Universitet
Kunstig Intelligens til Brætspillet Taiji - Danmarks Tekniske Universitet
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Kunstig</strong> <strong>Intelligens</strong> <strong>til</strong> <strong>Brætspillet</strong><br />
<strong>Taiji</strong><br />
Morten Rask<br />
Kongens Lyngby 2009<br />
IMM-MSC-2009-66
Technical University of Denmark<br />
Informatics and Mathematical Modelling<br />
Building 321, DK-2800 Kongens Lyngby, Denmark<br />
Phone +45 45253351, Fax +45 45882673<br />
reception@imm.dtu.dk<br />
www.imm.dtu.dk
Summary<br />
This project concerns the development of several artificial intelligences to the<br />
board game <strong>Taiji</strong>. <strong>Taiji</strong> is a fully observable abstract strategic game where two<br />
opponents each will try to score the most points by forming a larger figure on<br />
the board than the opponent’s figure.<br />
<strong>Taiji</strong> is a relatively new game released in the year 2007 and therefore there<br />
has not yet been developed an effective artificial intelligence (AI) for the game.<br />
The game’s designer, Néstor Romeral Andrés, has developed a simple AI for the<br />
game, but it requires great computing power at the high difficulty levels without<br />
even necessarily defeating a human opponent.<br />
The project aims to develop an effective AI to <strong>Taiji</strong>. In the first phase is implemented<br />
a classical AI-based search in a Minimax game tree. This involves,<br />
among other, construction of an appropriate heuristics for the game. The next<br />
stage is to examine further opportunities for improvement and development of<br />
more advanced AI’er. This includes, inter alia, an upgrade from game tree to<br />
game graph. Game tree gives as the name indicates only the opportunity to<br />
follow structure of the path, while the game graph allows move across structure<br />
of the path and thus is considerably more comprehensive.<br />
The project also includes an analysis of the game’s complexity and a score<br />
of winning strategies for different board sizes.<br />
The physical implementation of the game and the artificial intelligences have<br />
been made in Java.
Resumé<br />
Dette projekt omhandler udviklingen af flere kunstige intelligenser <strong>til</strong> brætspillet<br />
<strong>Taiji</strong>. <strong>Taiji</strong> er et fuldt observerbart abstrakt strategisk spil, hvor to modstander<br />
hver især forsøger at score flest point ved at danne en større figur p˚a brættet<br />
end modstanderens figur.<br />
<strong>Taiji</strong> er et forholdsvis nyt spil udgivet i ˚ar 2007 og derfor er der endnu ikke<br />
blevet udviklet en effektiv Artificial intelligence (AI) <strong>til</strong> spillet. Spillets designer,<br />
Néstor Romeral Andrés, har udviklet en simpel AI <strong>til</strong> spillet, men den kræver<br />
stor computerkraft p˚a de høje sværhedsgrader uden nødvendigvis at besejre en<br />
menneskelig modstander.<br />
M˚alet med projektet er at udvikle en effektiv AI <strong>til</strong> <strong>Taiji</strong>. I første fase implementeres<br />
en klassisk AI baseret p˚a minimax søgning i et spiltræ. Dette involvere<br />
blandt andet konstruktion af en passende heuristik for spillet. I næste fase undersøges<br />
yderligere muligheder for forbedringer og udvikling af mere avancerede<br />
AI’er. Dette inkludere blandt andet en opgradering fra spiltræ <strong>til</strong> spilgraf. Spiltræ<br />
giver som navnet angiver kun mulighed for at følge stistruktur, mens spilgraf<br />
giver mulighed for g˚a p˚a tværs af stistruktur og dermed er væsentligt mere omfattende.<br />
Projektet indeholder ogs˚a en analyse af spillets kompleksitet og en vurdering<br />
af vinderstrategier for forskellige brætstørrelser.<br />
Den fysiske Implementeringen af spillet og de kunstige intelligenser er blevet<br />
foretaget i Java.
Forord<br />
Dette speciale er udarbejdet ved Institut for Informatik og Matematisk Modellering,<br />
<strong>Danmarks</strong> <strong>Tekniske</strong> <strong>Universitet</strong>, som en del af kravene <strong>til</strong> færdiggørelsen<br />
af kandidatuddannelsen.<br />
Dette speciale omhandler kunstig intelligens i brætspillet <strong>Taiji</strong> og en analyse<br />
af spillet.<br />
Dette projekt blev lavet i perioden fra den 6. april 2009 <strong>til</strong> den 5. oktober<br />
2009 under vejledning af Thomas Bolander.<br />
Jeg vil gerne takke Thomas Bolander for hjælp og vejledning gennem hele<br />
forløbet, og David Christian Askirk for feedback p˚a rapporten. Rapporten kunne<br />
ikke være udført uden bogen ”Artificial Intelligence - A Modern Approach”af<br />
Stuart J. Russel og Peter Norvig. Og sidst, men ikke mindst et tak <strong>til</strong> Néstor<br />
Romeral Andrés for at have bragt brætspillet <strong>Taiji</strong> <strong>til</strong> verden.<br />
Lyngby, oktober 2009<br />
Morten Rask<br />
s031736
Indhold<br />
Summary i<br />
Resumé iii<br />
Forord v<br />
1 <strong>Taiji</strong> 1<br />
1.1 Spillets regler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />
1.2 Néstors AI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />
1.3 Generele egenskaber for <strong>Taiji</strong> . . . . . . . . . . . . . . . . . . . . 4<br />
1.4 Spillets kompleksitet . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />
2 Design og brugervenlighed 21<br />
2.1 Vurdering af Néstors Interface . . . . . . . . . . . . . . . . . . . . 21<br />
2.2 Design af eget Interface . . . . . . . . . . . . . . . . . . . . . . . 26<br />
3 <strong>Kunstig</strong> <strong>Intelligens</strong> 31<br />
3.1 Programmet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />
3.2 Generelle datastrukturer og metoder . . . . . . . . . . . . . . . . 35<br />
3.3 Heuristik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
4 Minimax 39<br />
4.1 Beskrivelse af Minimax med brede-først søgning . . . . . . . . . . 40<br />
4.2 Beskrivelse af Minimax med dybde-først søgning . . . . . . . . . 41<br />
4.3 Spilgraf for 3x3 <strong>Taiji</strong> spil: . . . . . . . . . . . . . . . . . . . . . . 42<br />
5 Optimering af Minimax 51<br />
5.1 Spilgraf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />
5.2 Rotationer og spejlinger . . . . . . . . . . . . . . . . . . . . . . . 53
viii INDHOLD<br />
5.3 Hash funktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />
5.4 Alpha-beta pruning . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />
6 Begrænsning af antallet af undersøgte træk 71<br />
6.1 Local Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71<br />
6.2 Growth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />
7 Test og sammenligning af de implementerede AI’er 77<br />
7.1 Test af Néstor’s AI . . . . . . . . . . . . . . . . . . . . . . . . . . 77<br />
7.2 Test af AlphaBeta AI (udviklet af Morten Rask) . . . . . . . . . 81<br />
7.3 Test af LocalArea AI (designet og udviklet af Morten Rask) . . . 85<br />
7.4 Test af Growth AI (designet og udviklet af Morten Rask) . . . . 87<br />
7.5 Sammenligning af AI’erne . . . . . . . . . . . . . . . . . . . . . . 90<br />
8 Konklusion 91<br />
A Kildekode 95<br />
A.1 AI<strong>Taiji</strong>AlphaBeta.java . . . . . . . . . . . . . . . . . . . . . . . . 95<br />
A.2 AI<strong>Taiji</strong>Growth.java . . . . . . . . . . . . . . . . . . . . . . . . . . 106<br />
A.3 AI<strong>Taiji</strong>LocalAreaAB.java . . . . . . . . . . . . . . . . . . . . . . 130<br />
A.4 AI<strong>Taiji</strong>Minimax.java . . . . . . . . . . . . . . . . . . . . . . . . . 142<br />
A.5 Board.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155<br />
A.6 FigureMap.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162<br />
A.7 Node.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />
A.8 <strong>Taiji</strong>Driver.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173<br />
A.9 <strong>Taiji</strong>Frame.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173<br />
A.10 <strong>Taiji</strong>Hash.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174<br />
A.11 <strong>Taiji</strong>Listeners.java . . . . . . . . . . . . . . . . . . . . . . . . . . 176<br />
A.12 <strong>Taiji</strong>Menu.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182<br />
A.13 <strong>Taiji</strong>Model.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183<br />
A.14 <strong>Taiji</strong>Panels.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200<br />
A.15 <strong>Taiji</strong>Print.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204<br />
A.16 <strong>Taiji</strong>Settings.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 225<br />
A.17 Tree.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228<br />
B Kildeliste 231<br />
B.1 Hjemmesider: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231<br />
B.2 Bøger: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Kapitel 1<br />
<strong>Taiji</strong><br />
<strong>Taiji</strong> er kinesisk og kan oversættes <strong>til</strong> Den Store Absolut. <strong>Taiji</strong> opfattes som det<br />
størst tænkelige princip, der indeholder yin og yang, hvor af alt udspringer. Yin<br />
og yang, lyset og mørket, modstandere, der ikke kan eksister uden hinanden.<br />
Deraf udspringer ideen i spillet <strong>Taiji</strong>. For hver brik du lægger, lægger du b˚ade<br />
en lys og en mørk side, den ene vil hjælpe dig og den anden vil kunne hjælpe<br />
din modstander. <strong>Taiji</strong> er designet af Néstor Romeral Andrés og udgivet af Blue<br />
Panther Games i 2007. Her under ses <strong>Taiji</strong>-brættet p˚a ni gange ni felter og en<br />
<strong>Taiji</strong>-brik:
2 <strong>Taiji</strong><br />
Figur 1.1: Standard <strong>Taiji</strong> bræt p˚a 9x9 felter og en <strong>Taiji</strong>-brik.<br />
1.0.1 Kildemateriale for <strong>Taiji</strong><br />
Da <strong>Taiji</strong> er et forholdsvis nyt spil, har det eneste <strong>til</strong>gængelige kildemateriale<br />
omkring <strong>Taiji</strong>, været de officielle regler <strong>til</strong> spillet. Det er heller ikke lykkedes at<br />
finde et ældre spil, der i sin natur ligger s˚a tæt opad <strong>Taiji</strong>, at materiale om et<br />
s˚adan spil har kunne anvendes direkte p˚a <strong>Taiji</strong> eller som inspiration <strong>til</strong> skabelsen<br />
af en effektiv AI for spillet <strong>Taiji</strong>.<br />
Dette betyder at konklusioner draget omkring spillet <strong>Taiji</strong> er baseret p˚a mine<br />
egne undersøgelser og ideer, medmindre andet er angivet.
1.1 Spillets regler 3<br />
1.1 Spillets regler<br />
<strong>Taiji</strong> spilles af to spiller p˚a en plade af ni gange ni felter. Spillerne skiftes <strong>til</strong> at<br />
lægge en brik p˚a brættet. N˚ar en brik bliver lagt p˚a brættet er den endeligt lagt,<br />
der bliver hverken fjernet eller flyttet brikker undervejs i spillet. Brikkerne har<br />
en størrelse der svare <strong>til</strong> to felter p˚a spillepladen. Disse brikker har alle en lys<br />
og en mørk ende og er ens for begge spillere. Selvom de to spillere spiller med<br />
samme brikker, spiller den ene som hvid og den anden som sort. Det gælder<br />
for begge spillere om at bygge de to største figurer i sin farve. En figur best˚ar<br />
af sammenhængende felter i én farve. To felter skal ligge opad hinanden enten<br />
lodret eller vandret for at kunne siges at hænge sammen, diagonalt tæller ikke.<br />
Scoren tælles op for hver spiller ved at tælle antallet af felter, der indg˚ar i spillerens<br />
to største figurer. Den spiller der har den højeste score, n˚ar der ikke kan<br />
lægges flere brikker, har vundet. Et eksempel p˚a et afsluttet spil kan se s˚aledes<br />
ud:<br />
Figur 1.2: Afsluttet spil med score.<br />
I dette <strong>til</strong>fælde er det sort som vinder med 17 point mod hvids 15 point.
4 <strong>Taiji</strong><br />
1.1.1 Forskelle mellem de officielle regler og mine<br />
Ifølge de officielle regler skal brætstørrelsen være minimum ni gange ni, kvadratisk<br />
og side længden skal være p˚a et ulige tal. Jeg ser derimod p˚a alle<br />
brætstørrelser, med lige sider, rektangulære og mindre end ni gange ni.<br />
De officielle regler siger ogs˚a at et spil, hvor scoren ender lige, tæller som en<br />
sejr <strong>til</strong> sort. Som udgangspunkt i denne opgave ser jeg p˚a et lige resultat som<br />
et uafgjort resultat. Det vil undervejs blive set p˚a hvilke forskelle dette har for<br />
spillet.<br />
1.2 Néstors AI<br />
Néstor skaberen af <strong>Taiji</strong> har selv lavet en AI <strong>til</strong> spillet med fire sværhedsgrader.<br />
Néstor har dog ikke oplyst hvordan disse AI er lavet og der vides derfor<br />
hvordan de faktisk fungerer. P˚a den højeste sværhedsgrad bruger AI’en godt og<br />
vel 30 sekunder p˚a at beregne sit træk. Beregningstiden bliver dog lavere som<br />
spillet nærmere sig sin afslutning, og de mulige træk bliver færre. Selvom programmet<br />
bruger forholdsvis megen computerkraft - deraf den forholdsvis lange<br />
beregningstid - er det muligt for en rutineret <strong>Taiji</strong>-spiller at sl˚a af den kunstige<br />
intelligens og s˚a endda rimeligt overbevisende. Efter selv at have arbejdet<br />
med spillet gennem længere tid lykkedes det mig at sl˚a Néstors AI p˚a højeste<br />
sværhedsgrad med scoren 19-8.<br />
1.3 Generele egenskaber for <strong>Taiji</strong><br />
Der er et begrænset antal træk i ét <strong>Taiji</strong>-spil. Dette skyldes, at der hverken fjernes<br />
eller flyttes brikker undervejs i spillet og det er derfor begrænset hvor mange<br />
træk, der kan fortages i et spil. Antallet af brikker, der kan lægges bestemmes<br />
fra start af brætstørrelsen, men som spillet skrider frem vil dette antal oftest<br />
falde yderligere, da spillerne kun kan lægge deres brikker som dækker to felter,<br />
s˚a nogle de fri felter p˚a brættet bliver uanvendelige.
1.3 Generele egenskaber for <strong>Taiji</strong> 5<br />
1.3.1 Maksimum antal træk<br />
Da der hverken fjernes eller flyttes brikker undervejs i spillet, er spillets længde<br />
udelukkende styret af hvor mange brikker det er muligt at lægge p˚a brættet.<br />
Hver brik fylder to fletter og spillepladen er normalt er p˚a 9 gange 9 felter.<br />
Dette betyder at det maksimale antal brikker der ville kunne lægges og dermed<br />
det maksimale antal træk, vil være brættets størrelse divideret med brikkernes<br />
størrelse. I <strong>til</strong>fælde af decimaltal vil der naturligvis skulle rundes ned, da det<br />
ikke er <strong>til</strong>ladt at lægge halve eller p˚a anden m˚ade delte brikker. For en standardspilleplade<br />
betyder dette at spillet vil strække sig over maksimalt 40 træk.<br />
Alts˚a ni gange ni divideret med to og rundet ned ((9·9)/2 = 81/2 = 40, 5 ∼ 40).<br />
Brætlængde x Brætbredde / 2 ≥ antallet af træk<br />
Som spillet skrider frem kan det maksimale antal <strong>til</strong>bageværende træk falde.<br />
Selvfølgelig vil antallet af træk blive reduceret med en for hver brik der bliver<br />
lagt. Derudover vil nogle træk tage pladsen for mere end en brik. Dette sker n˚ar<br />
brikker placeres s˚aledes, at de efterlader tomme omr˚ader der ikke er store nok<br />
<strong>til</strong> at en brik kan placeres i dem. Ud fra dette er det muligt undervejs i spillet<br />
at beregne et opdateret og derved mere præcist upper-bound for antallet af<br />
<strong>til</strong>bageværende træk. Denne nye beregning tager udgangspunkt i den foreg˚aende<br />
beregning og <strong>til</strong>føjer en reducering af antal af træk baseret p˚a antal af brikker<br />
p˚a brættet og antal af tomme omr˚ader, hvor det ikke længere er muligt at lægge<br />
brikker. Da brikkerne er p˚a et gange to felter, vil et frit omr˚ade der ikke længere<br />
kan spilles p˚a altid kun være p˚a et enkelt flet.<br />
( Brætlængde x Brætbredde / 2) - antallet af træk - ( enkeltst˚aende frie felter<br />
/ 2 ) ≤ <strong>til</strong>bageværende træk<br />
eks:<br />
(4 x 4 / 2) - 3 - (1 / 2) = 4,5<br />
Figur 1.3: 4x4 <strong>Taiji</strong>-plade med 3 brikker.
6 <strong>Taiji</strong><br />
Alts˚a kan der maksimalt fortages yderligere 4 træk.<br />
1.3.2 Minimum antal træk<br />
Den mindste forekomst af <strong>Taiji</strong>, hvor mængden af træk kan reduceres undervejs,<br />
er 3x2. Her er det muligt at reducere antallet af træk fra 3 <strong>til</strong> 2. Dette sker ved<br />
at brikkerne lægges s˚aledes at der opst˚ar to indelukkede tomme felter:<br />
Figur 1.4: 3x2 <strong>Taiji</strong>-plade afsluttet med minimum antal brikker.<br />
Der bruges her en brik per indelukket tomt felt.<br />
For 4x2 felter er det kun muligt at lave to tomme indelukkede felter:<br />
Figur 1.5: To 4x2 <strong>Taiji</strong>-plader afsluttet med minimum antal brikker.<br />
I dette <strong>til</strong>fæde er det dog ikke muligt at skabe et tomt felt per brik, men der<br />
bruges stadig minimum en brik per tomt indelukket felt.<br />
For 3x3 felter:<br />
Figur 1.6: En 3x3 <strong>Taiji</strong>-plade afsluttet med minimum antal brikker.
1.3 Generele egenskaber for <strong>Taiji</strong> 7<br />
Resultatet er her et tomt felt per brik.<br />
For 4x3 felter:<br />
Figur 1.7: To 4x3 <strong>Taiji</strong>-plader afsluttet med minimum antal brikker.<br />
Resultatet er igen et tomt felt per brik.<br />
For at bevise at det ikke er muligt at danne et tomt felt per brik, ses der p˚a det<br />
mest repræsentative eksempel p˚a et bræt, hvor der skal absolut mindst <strong>til</strong> for<br />
at danne et indelukket tomt felt, nemlig et bræt der kun har et felt p˚a den ene<br />
led:<br />
Figur 1.8: En vilk˚arligt lang og en høj <strong>Taiji</strong>-plade med minimum antal brikker.<br />
Her er det tydeligt at der skal en brik <strong>til</strong> for at danne et nyt indelukket tomt<br />
felt. Hvis det forsøges med færre brikker, vil hulerne blive s˚a store, at der kan<br />
placeres brikker i dem. Det er simpelthen ikke muligt at danne tomme felter<br />
med mindre en brik per tomt felt.<br />
Derfor bliver det minimale antal træk følgende:<br />
Brætlængde x Brætbredde / (2 + 1) ≤ = antallet af træk<br />
Et standard spil, hvor brætstørrelsen er p˚a ni gange ni felter, vil derfor ikke<br />
være slut før minimum 27 brikker er blevet lagt p˚a brættet.<br />
For 9x9 felter er det muligt at lave dette eksempel p˚a et bræt med det minimale<br />
antal træk for denne størrelse:
8 <strong>Taiji</strong><br />
Figur 1.9: Et standard <strong>Taiji</strong>-bræt afsluttet med minimum antal brikker.<br />
Ud fra disse antagelser er det muligt at beregne det minimale antal træk for standardbrætstørrelsen<br />
9x9. Det kan ses som værende blot gentagelser af mønstret<br />
fra brættet p˚a 2x3 felter:
1.3 Generele egenskaber for <strong>Taiji</strong> 9<br />
Figur 1.10: Standard <strong>Taiji</strong>-brættet opdelt i stykker p˚a 3x2.<br />
Med denne metode er det muligt at beregne det minimale antal træk, s˚a længe<br />
3 g˚ar op i enten højden eller bredden af brættet. Det er dog ikke et krav, at 3<br />
skal g˚a op i højden eller bredden, for at det er muligt at opn˚a et tomt felt per<br />
brik. Men da et tomt felt og en brik optager 3 felter, er det et krav at 3 g˚ar op<br />
i det samlede antal felter, før dette er muligt.<br />
X · Y = Z · 3 ⇔<br />
X · Y<br />
3<br />
= Z ⇔ X<br />
3<br />
= Z<br />
Y<br />
3 skal g˚a op i X før X/3 kan blive et helt tal. Er dette ikke <strong>til</strong>fældet skal 3 g˚a op<br />
i Y for at kunne matche X antal tredjedele p˚a den anden side, da 3 er et primtal<br />
og brøken derfor ikke kan reduceres yderligere.<br />
Det er alts˚a kun muligt at opn˚a det minimale antal træk, hvis 3 g˚ar op i enten<br />
højden eller bredden. Dette vil ogs˚a kunne ses i formlen i form af decimaltal.<br />
I disse <strong>til</strong>fælde vil formlen for det minimale antal træk ikke give et helt tal, men<br />
det er ikke helt enkelt om dette resultat s˚a skal rundes op eller ned. Her er nogle<br />
eksempler:<br />
1x5: Formlen giver her 1,67, mens det er ikke muligt at afslutte spillet med<br />
mindre end to brikker.<br />
4x4: Her giver formlen 5,3, hvilket normalt ville være et tal der rundes ned, men<br />
det er ikke muligt at afslutte et spil af denne størrelse med mindre end 6 brikker.
10 <strong>Taiji</strong><br />
Der er dog en række special <strong>til</strong>fælde, hvor det med en brik er muligt at danne<br />
to enkeltst˚aende tomme felter, et p˚a hver side af brikken. Disse er bræt p˚a 1<br />
gange 3 · X + 1 og selvfølgelig ogs˚a 3 · X + 1 gange 1.<br />
Det første eksempel her p˚a er 4x1. Her vil en brik, der placeret i midten af dette<br />
bræt, resultere i to uanvendelige tomme felter:<br />
Figur 1.11: 4x1 <strong>Taiji</strong>-bræt afsluttet med minimum antal brikker.<br />
Resultatet af formlen bliver 1,33, men det er muligt at afslutte spillet med en<br />
enkelt brik.<br />
For et større <strong>til</strong>fælde som f.eks. 13 gange 1:<br />
Figur 1.12: 13x1 <strong>Taiji</strong>-bræt afsluttet med minimum antal brikker.<br />
Resultatet af formlen bliver her 4,33, men igen er det muligt at afslutte spillet<br />
med kun 4 brikker.<br />
Det er en mulighed at runde resultaterne op og se p˚a disse <strong>til</strong>fælde som undtagelser<br />
p˚a formlen, men da formelen skal bruges som et lower-bound estimat,<br />
vil det være en udmærket løsning altid at runde resultatet ned, da det ikke vil<br />
være et problem at nogle brætstørrelser ikke vil kunne n˚a deres beregnede minimum<br />
for antallet af træk. Det ville være langt mere problematisk, hvis nogle<br />
brætstørrelser kunne afsluttes før forventet.<br />
1.3.3 Maksimum antal point<br />
Teoretisk set vil det størst mulige antal point n˚as ved at forbinde alle brikker af<br />
en farve i en eller to figurer. Antallet vil svare <strong>til</strong> halvdelen af brættets størrelse,<br />
da den anden halvdel selvfølgelig vil g˚a <strong>til</strong> modstanderens farve. Her skal antallet<br />
naturligvis ogs˚a rundes ned <strong>til</strong> et helt tal. I praksis viser dette sig ogs˚a at være<br />
<strong>til</strong>fældet. Dette forekommer især ved sm˚a plader. Ved det ekstreme <strong>til</strong>fælde af
1.3 Generele egenskaber for <strong>Taiji</strong> 11<br />
den minimale størrelse p˚a to gange to felter, ville begge spiller altid n˚a topscoren<br />
p˚a to points uanset hvordan de bære sig ad, enten i form af to figurer p˚a hvert<br />
et felt eller en figur p˚a to felter.<br />
Figur 1.13: Mulige afslutninger for et <strong>Taiji</strong>-bræt p˚a 2x2.<br />
Dette gør ogs˚a denne minimale brætstørrelse højst uinteressant at arbejde med.<br />
Men uanset størrelsen vil det altid være muligt at sammensætte et spil der giver<br />
den maksimale score for en eller begge spillere. Dette er muligt ved at fylde et<br />
bræt ud s˚aledes, at alle felter for hver farve er del af en af de to største figurer<br />
for farven. Det er selvfølgelig ogs˚a nødvendigt, at brikkerne ligger s˚a de ikke<br />
skaber uanvendelige tomme felter. Det kan f.eks. gøres s˚aledes:<br />
Figur 1.14: Eksempel p˚a maksimal score for begge spiller.<br />
Det kræver lidt mere variation at opn˚a den højeste score for begge spiller, n˚ar<br />
brættets sider er ulige, men dette kan ogs˚a opn˚as:
12 <strong>Taiji</strong><br />
Figur 1.15: Eksempel p˚a maksimal score for begge spiller p˚a en standardplade.<br />
Disse og lignende mønstre kan altid anvendes <strong>til</strong> at lave den maksimale score,<br />
hvis begge spiller g˚ar efter det. Det kan f.eks. gøres ud fra denne form:<br />
Figur 1.16: Formel for creation af bræt med max point med minimum en lige<br />
side.
1.3 Generele egenskaber for <strong>Taiji</strong> 13<br />
Figur 1.17: Formel for creation af bræt med max point med ulige sider.<br />
1.3.4 Sammenfatning af de generelle træk<br />
Det er muligt fra spillets start at beregne et minimum og maksimum for hvor<br />
mange træk spillet vil strække sig over. Minimum vil være en hjælpende faktor<br />
i at bedømme spillets kompleksitet. Det samme gælder maksimum, men det vil<br />
f.eks. ogs˚a kunne anvendes <strong>til</strong> at bedømme hvorn˚ar det bliver muligt at beregne<br />
en fuldstændig løsning, efter et spil er g˚aet i gang.<br />
Det viste sig at scoren for de to spillere kunne blive s˚a høj, som det overhovedet<br />
kunne forventes, nemlig højden gange bredden divideret med to, da hver brik<br />
fylder to felter og <strong>til</strong>føjer b˚ade et sort og et hvidt felt. Hvor mængden af træk<br />
forholdsvist nemt kan beregnes undervejs i et spil, er det en langt mere krævende<br />
opgave at beregne scorens muligheder inde i spillet, da denne afhænger af alle<br />
brikkerne og deres placeringer, ikke kun antallet af brikker og antallet af uanvendelige<br />
felter p˚a brættet. Det ville ellers give mulighed for at stoppe spillet,<br />
n˚ar f.eks. den ene spillers mulige maksimum bliver overg˚aet af den anden spillers<br />
nuværende score. Disse værdi kunne ogs˚a bruges af en kunstig intelligens,<br />
ved at forsøge at holde sin mulige maksimum score s˚a høj som mulig og øge sin<br />
minimums score, samtidig med at reducere modstanderens mulige maksimum<br />
score og holde den minimums scoren nede.
14 <strong>Taiji</strong><br />
1.4 Spillets kompleksitet<br />
Standard størrelsen for et spil <strong>Taiji</strong> er p˚a ni gange ni felter. Dette lyder m˚aske<br />
ikke <strong>til</strong> at være s˚a stort, men sammenlignes det f.eks. med skak er det et felt<br />
mere p˚a hver led og selvom antallet af træk er begrænset i <strong>Taiji</strong>, s˚a er der færre<br />
restriktioner p˚a hvilke træk, der kan foretages. Forsker har estimeret antal af<br />
lovlige spilstadier i skak <strong>til</strong> at være 10 43 . 1<br />
1.4.1 Upper-bound estimat for antal af spilstadier<br />
Et forholdsvist simpelt upper-bound estimat kan laves ved at se p˚a antallet af<br />
mulige spilstadier, hvis restriktionerne af brikker fjernes, s˚aledes at der er ni<br />
gange ni felt som hvert kan p˚atage sig værdierne sort, hvid og tomt uafhængigt<br />
af hinanden. I s˚a fald bliver antal af mulige spilstadier antallet af værdier per<br />
felt opløftet i antallet af felter.<br />
3 81 = 4, 43 · 10 38<br />
Brikker giver vise restriktioner og derved reduceres dette tal. Restriktionen at<br />
der skal være minimum et hvidt felt opad hvert sort felt og minimum et sort<br />
felt opad alle hvide felter, er meget svær at indføre.<br />
En anden restriktion, der ogs˚a kommer af brikkernes udformning, er at der<br />
for alle spilstadier skal være lige mange sorte og hvide felter. Denne er ogs˚a, i<br />
modsætning <strong>til</strong> forrige restriktion, uafhængig af brættets form, om brættet er 9<br />
gange 9 eller 81 gange 1 er ligegyldigt.<br />
P˚a et bræt med et enkelt felt, hvor der normalt vil være tre kombinationsmuligheder,<br />
vil den eneste mulighed med lige mange hvide og sorte felter, være<br />
et tomt bræt. For et bræt med to felter, hvor der normalt vil være ni kombinationsmuligheder,<br />
vil der være tre gyldige kombinationer, et tomt bræt, to<br />
brætter med et sort og et hvidt felt.<br />
Herunder ses en tabel over antallet af kombinationsmuligheder for op <strong>til</strong> 6 felter<br />
og antallet af kombinations muligheder med og uden restriktionen, at der skal<br />
være lige mange sorte og hvide felter:<br />
1 64!<br />
Tallet kommer af estimatet<br />
32!·8! 2 ·2! 6 ≈ 1043 som er givet af Claude E. Shannon i ”Programming<br />
a Computer for Playing Chess”, Phil. Mag. 41 (1950) 256-275).
1.4 Spillets kompleksitet 15<br />
Antal felter Kombinationer Efter Restriktionen Procentdel<br />
1 3 1 33,3%<br />
2 9 3 33,3%<br />
3 27 7 25,9%<br />
4 81 19 23,5%<br />
5 243 49 20,2%<br />
6 729 137 18,8%<br />
Tabellen viser at procentdelen af gyldige kombinationsmuligheder falder som<br />
antallet af felter stiger. Derfor kan antallet af spilstadier i alle <strong>til</strong>fælde roligt reduceres<br />
med en tredjedel. Ligeledes kan antallet af spilstadier for standardbrættet<br />
p˚a ni gange ni felter roligt reduceres <strong>til</strong> en 20% . Derved kan upper-bound<br />
estimatet reduceres fra 4,43 · 10 38 <strong>til</strong> 10 38 .<br />
1.4.2 Lower-bound estimat for antal af spil forløb<br />
I dette afsnit estimeres der et lower-bound for antal spil forløb, eller kombinationsmuligheder<br />
for trækkene gennem et spil.<br />
I <strong>Taiji</strong> er der med et bræt p˚a ni gange ni felter maksimalt 40 træk, da dette er<br />
det maksimale antal brikker, der kan lægges. Der er ni gange ni felter at gøre<br />
godt med p˚a brættet og hver brik fylder to felter.<br />
9 · 9<br />
2<br />
= 40, 5<br />
Og det er naturligvis ikke muligt at lægge en halv brik. Der vil ikke altid være<br />
40 træk, da det er muligt at lægge brikkerne s˚aledes at de efterlader fri felter<br />
hvor det ikke er muligt at f˚a plads <strong>til</strong> en brik. Dette forekommer n˚ar et enkelt<br />
tomt felt omkredses af brikker og evt. brættets kanter.<br />
Figuren her under illustrerer de mulige træk:
16 <strong>Taiji</strong><br />
Figur 1.18: Alle trækmuligheder for et standardbræt. Hver streg repræsentere<br />
en brik og de to m˚ader, som brikken kan vende p˚a.<br />
Der er ni gange ni felter. Hver sort streg illustrere to mulige træk, nemlig de træk<br />
som kan laves p˚a de to felter stregen indg˚ar i. En sort-hvid brik lagt vandret,<br />
hvis stregen er vandret, og lodret, hvis stregen er lodret og samme brik med<br />
samme placering blot vendt 180 grader.<br />
I dette <strong>til</strong>fælde er der i alt 144 sorte streger (8x9 vandrette og 9x8 lodrette), med<br />
andre ord er der 288 mulige træk. Til sammenligning er der i skak 20 muligheder<br />
for første træk (otte bønder med to mulige træk hver og to springer med hver<br />
to mulige træk).<br />
N˚ar der lægges en brik p˚a brættet udelukkes der maksimalt 14 mulige træk, da<br />
en brik p˚a to felter højst vil overlappe 7 streger:<br />
Figur 1.19: Repræsentation af det største antal træk en brik kan udelukke.<br />
Det minimale antal mulige træk, der kan udelukkes vil, være 2. Dette vil kun<br />
ske i <strong>til</strong>fælde hvor alle felter omkring brikken er optaget:
1.4 Spillets kompleksitet 17<br />
Figur 1.20: Repræsentation af det mindeste antal træk en brik kan udelukke.<br />
Et lower-bound resultat kan udregnes ved at tage de 288 mulige træk og gange<br />
dem sammen med de efterfølgende træk, hvor antallet af mulige træk hver gang<br />
reduceres med de maksimale 14 træk per tur:<br />
eller mere præcist:<br />
288<br />
14<br />
≈ 20, 57<br />
20, 57! · 14 20,57 ≈ 5, 208 · 10 42<br />
288·274·260·246·232·218·204·190·176·162·148·134·120·106·92·78·64·50·36·22·8<br />
≈ 1, 035 · 10 43<br />
Dette minimum vil dog være et godt stykke under det reelle antal mulige trækkombinationer.<br />
Dette lower-bound estimat resulterer f.eks. i at der kun er i alt<br />
21 træk, hvor det tidligere er blevet vist at der minimum vil blive foretaget 27<br />
træk i et spil <strong>Taiji</strong> p˚a et bræt med ni gange ni felter.<br />
Udover at lower-bound estimat har færre træk end et rigtigt spil, reducere det<br />
ogs˚a antallet af mulige træk med de maksimale 14 træk per tur. At reducere<br />
antallet af muligheder med 14 er kun muligt, n˚ar en brik kan lægges uden at<br />
have nogen restriktioner omkring sig. Dette forventes med et bræt p˚a ni gange<br />
ni felter højst at kunne gøres 11 gange, som det ses i eksemplet herunder:
18 <strong>Taiji</strong><br />
Figur 1.21: Denne figur viser en af m˚aderne de 11 brikker kan lægges, hvor de<br />
hver især reducerer antal af mulige træk mest.<br />
Efter at de 11 brikker er blevet lagt, er det ikke længere muligt at finde en<br />
placering hvor en brik kan reducere antallet af mulige træk med mere end 12.<br />
Og der kan ikke foretages mange træk før det bliver mindre end 12.<br />
1.4.3 Estimat af antallet af mulige trækkombinationer i et<br />
gennemsnits spil:<br />
For at lave et estimat p˚a gennemsnits antallet af mulige trækkombinationer i<br />
et standard spil, bør b˚ade antallet af træk og antallet af reducerede muligheder<br />
per træk ligge s˚a tæt p˚a gennemsnittet som muligt.<br />
Gennemsnits antallet af træk kan forventes at ligge lige mellem det maksimale<br />
og det minimale antal af træk!<br />
27 + 40<br />
2<br />
= 33, 5<br />
Og reduceringen af træk per træk kan ogs˚a forventes at ligge lige mellem det<br />
maksimale og minimale.<br />
14 + 2<br />
2<br />
= 8<br />
288<br />
= 36<br />
8<br />
Med en reducering af 8 per træk bliver der i alt 36 træk. Hvilket er et stykke<br />
fra de gennemsnitlige 33,5 træk. Alternativ kan der reduceres med 9 muligheder<br />
per træk, hvilket resultere i 32 træk. Estimatet af træk bliver med en reducering<br />
p˚a 8 følgende:<br />
36! · 8 36 = 1, 207x10 72
1.4 Spillets kompleksitet 19<br />
Estimatet af træk bliver med en reducering p˚a 9 følgende:<br />
32! · 9 32 = 9, 035x10 65<br />
Et mere præcist estimat vil være at starte med et en høj reducering og sænke<br />
den under vejs s˚a den ender ved minimum efter omkring en 33-34 træk.<br />
1.4.4 Sammenfatning af spillets kompleksitet<br />
Selvom <strong>Taiji</strong>’s regler er meget simple og hurtige at sætte sig ind i, sammenlignet<br />
med f.eks. skak, er <strong>Taiji</strong> meget tæt p˚a kompleksitets niveauet for skak, f.eks.<br />
n˚ar det kommer <strong>til</strong> antallet af mulige bræt<strong>til</strong>stande, hvor de ikke er langt fra<br />
hinanden. <strong>Taiji</strong> kan ogs˚a meget hurtigt overg˚a skak ved blot at øge dimensionerne<br />
p˚a <strong>Taiji</strong>-brættet. Ifølge de officielle regler er den næste godkendte brætstørrelse<br />
11 gange 11, da side længderne ifølge dem skal være ulige. Hvor ubber-bound<br />
estimatet for 9 gange 9 l˚a omkring 10 38 vil det for 11 gange 11 ligge omkring<br />
10 57 2 , hvilket er langt over det estimerede 10 43 for skak. Skak vil dog via sine<br />
muligheder for<br />
Muligheden for at estimere antallet af <strong>til</strong>bageværende træk en en vigtigt faktor<br />
for at optimere performance uden tab af kvalitet, da antal <strong>til</strong>bageværende træk<br />
kan bruges <strong>til</strong> at estimere hvor meget regnekraft der skal <strong>til</strong> for at regne et<br />
bestemt antal generationer ned i spiltræet. Jo færre antal træk der er <strong>til</strong>bage,<br />
jo færre mulige træk vil der være <strong>til</strong>bage, og jo længere vil det være muligt<br />
at regne ned i spiltræet indenfor en rimelig tid. Det gør det samtidig muligt<br />
beregne grundigst p˚a de sidste træk i spillet uden at ødelægge performance, og<br />
de sidste træk er ofte afgørende for at vinde spillet.<br />
2 3 11·11 reduceret med 80%
20 <strong>Taiji</strong>
Kapitel 2<br />
Design og brugervenlighed<br />
Da der skal arbejdes meget med programmet gennem forløbet, er det vigtigt<br />
at det har en god brugerflade som er hurtig, brugbar og nem at anvende. Dog<br />
behøver ikke nødvendigvis nem at <strong>til</strong>egne sig, da det ville blive anvendt rigeligt<br />
s˚a en hurtig og smidig anvendelse for en erfaren bruger er vigtigere, end at<br />
brugerfladen er let at g˚a i gang med som ny bruger.<br />
2.1 Vurdering af Néstors Interface<br />
Inden jeg designer og udvikler min egen brugerflade vil jeg kigge p˚a hvordan<br />
Néstor Romeral Andrés har lavet sin og gøre mig nogle erfaringer ud fra den.<br />
2.1.1 At starte et spil:<br />
For at starte et spil ˚abnes menupunktet ”Game”og ”1-Player”vælges.
22 Design og brugervenlighed<br />
Figur 2.1: Néstor’s brugerflade n˚ar ”Game”er ˚aben.<br />
Her bliver brugeren s˚a mødt med en menu, hvor man kan vælge sin farve og en<br />
modstander, i form af de fire sværhedsgrader for Néstor’s egen AI.
2.1 Vurdering af Néstors Interface 23<br />
Figur 2.2: Opsætningen for starte et nyt spil.<br />
Dette fungerer godt, men jeg ser ingen grund <strong>til</strong> at undlade at have et spil klar <strong>til</strong><br />
start n˚ar programmet ˚abnes. Et spil mod en sort AI p˚a et af de lave niveauer vil<br />
være at foretrække, da en s˚adan ikke vil lave nogen beregningen før spilleren selv<br />
lægger den først brik, og fordi de lave niveauer af AI svarer forholdsvis hurtigt<br />
efter spilleren har foretaget sit træk. Det kan tænkes at Néstor Romeral Andrés<br />
har undladt dette med vilje for at lede brugeren op i Game menuen og derved<br />
gøre brugen opmærksom p˚a at der ogs˚a er en ”2-Player-funktion, der spilles over<br />
nettet, hvilket kan være mere spændende for brugeren. Hvorfor der dog ikke er<br />
en 2-Player funktion, for to spillere ved samme computer kan man dog undre<br />
sig over. Der er selvfølgelig den mulighed, at det er et ønske fra Néstor Romeral<br />
Andrés’ side om at f˚a brugeren <strong>til</strong> at anskaffe sig den fysiske version af spillet.<br />
2.1.2 Placering af brikker:<br />
N˚ar spillet er i gang, placeres en brik ved at bevæge musen hen over brættet<br />
ind<strong>til</strong> man har den rette placering. Brikken kan hele tiden ses p˚a brættet og har<br />
en hvid markering rundt om sig, der gør det tydeligt at skelne den fra andre<br />
brikker p˚a brættet. Det kan dog være lidt besværligt at f˚a placeret brikken<br />
korrekt. Brikken vendes lodret eller vandret efter om musen lige er passeret<br />
gennem en vandret eller lodret væg mellem felterne, hvilket ikke altid virker lige
24 Design og brugervenlighed<br />
naturligt. Skal brikken vendes s˚a hvid og sort skifter plads, er det nødvendigt<br />
at bruge højre musetast, hvilket formentligt kræver et kig i ”Help”og menuen<br />
”Controls”for at gennemskue. N˚ar brikken først er placeret kræver det kun et<br />
enkelt klik p˚a venstre musetast at lægge brikken. Dette kan dog give anledning<br />
<strong>til</strong> frustration, da der ikke skal meget <strong>til</strong> at komme <strong>til</strong> at lægge en brik ved en<br />
fejl, og spilles der samtidigt mod højeste niveau AI, kan man sidde og ærgre sig<br />
over fejl trækket i et halv <strong>til</strong> et helt minut før det bliver éns tur igen.<br />
2.1.3 Information p˚a displayet:<br />
Displayet viser to væsentlige ting, hvilken farve spilleren selv har i form af et<br />
felt i den farve i nederste højre hjørne og s˚a fortæller en kort tekst om det er<br />
spillerens tur eller om AI’en er ved at beregne sit træk og hvor langt den er n˚aet<br />
ved hjælp af en lille bar ved siden af.<br />
Der vises ingen score undervejs i spillet, men n˚ar spillet afsluttes viser et popop<br />
vindue den endelige s<strong>til</strong>ling og vinderen, derudover vises størrelse p˚a de to<br />
største figurer for hver spiller i form af et tal placeret p˚a selve figurerne.
2.1 Vurdering af Néstors Interface 25<br />
Figur 2.3: Eksempel p˚a afsluttet spil med score vist p˚a figurerne.<br />
2.1.4 Det overordnede indtryk:<br />
Néstor Romeral Andrés’ brugerflade er p˚a alle omr˚ader god, n˚ar det gælder om<br />
at lærer spillet at kende. Brikkernes form og hvor de kan lægges vises fint, n˚ar<br />
musen bevæges hen over brættet. N˚ar spillet er afsluttet vises scoren p˚a figurerne,<br />
s˚a det er nemt at se og forst˚a, hvor den endelige resultat kommer fra. Den<br />
placerer ogs˚a to plus’er p˚a den brik som AI senest har placeret, hvilket gør det<br />
nye træk lettere at finde, hvilket ofte er nødvendigt for de høje sværhedsgrader,<br />
da spilleren ofte har mistet interessen inden AI bliver færdig med at beregne sit<br />
træk.<br />
Fra et lærings synspunkt er Néstor’s interface glimrende, men n˚ar det kommer<br />
<strong>til</strong> effektivitet kunne man ønske sig mere. Mulighederne n˚ar spillet derimod først<br />
er startet er stort set ikke eksisterende, du kan foretage dine træk og vente p˚a<br />
modstanderens, og evt. starte et nyt spil, hvis du bliver træt af det. Der er ingen
26 Design og brugervenlighed<br />
muligheder for at fortryde træk eller g˚a frem og <strong>til</strong>bage i spillet. Det ville ogs˚a<br />
være rart at kunne gemme spillet undervejs, n˚ar de netop bliver s˚a langvarige<br />
ved den højeste sværhedsgrad.<br />
2.2 Design af eget Interface<br />
Min egen brugerflade er designet med henblik p˚a langvarigt brug med test af<br />
AI’er som hovedform˚al, ikke at lære brugeren spillet hurtigst muligt eller at<br />
skabe den ultimative spil oplevelse.<br />
2.2.1 At starte et spil:<br />
Et spil kan startes op med inds<strong>til</strong>linger opsat i programmet blot ved at klikke<br />
p˚a spilbrættet. Enten vil brugeren begynde med at sætte sin brik eller ogs˚a vil<br />
en AI begynde at beregne sit træk.<br />
Det er ogs˚a muligt at ændre p˚a inds<strong>til</strong>lingerne gennem menuen, men disse valgmuligheder<br />
er begrænsede og anvendes hovedsageligt <strong>til</strong> at vise programmet<br />
frem. I testsammenhæng vil ændringerne af inds<strong>til</strong>lingerne blive foretaget i selve<br />
koden. Spillet med disse inds<strong>til</strong>linger vil s˚a være <strong>til</strong>gængeligt med det samme<br />
programmet ˚abnes og det vil ikke være nødvendigt at skulle igennem menuerne<br />
for at starte det ønskede spil.<br />
For at starte et nyt spil op med samme inds<strong>til</strong>linger kan dette hurtigt gøres i<br />
menuen. Der vælges blot ”New Game”og ”Same settings”
2.2 Design af eget Interface 27<br />
Figur 2.4: Min brugerflade n˚ar ”Game”er ˚aben og ”New Game”markeret.<br />
Vælges ”Change settings”mødes brugeren med denne menu, hvor bruger kan<br />
vælge at spille menneske mod et menneske p˚a samme computer eller mod en af<br />
de tre hoved AI’er.<br />
Figur 2.5: Opsætningen for starte et nyt spil med nye inds<strong>til</strong>linger.
28 Design og brugervenlighed<br />
2.2.2 Placering af brikker:<br />
Placering af brikker udføres ved at klikke p˚a et frit felt, hvor man ønsker at<br />
placere sin farves halvdel af brikken, og derefter klikker man p˚a et frit felt ved<br />
siden af for at placere halvdelen med modstanderens farve. Foretages andet klik<br />
et sted hvor trækket bliver ugyldigt annulleres det og begge halvdele fjernes<br />
automatisk igen. Et ugyldigt træk kan ogs˚a bruges <strong>til</strong> at annullere et træk, som<br />
man ikke ønskede at lave, hvis man kun har f˚aet placeret den ene halvdel. At<br />
klikke p˚a samme felt en gang <strong>til</strong> er en hurtigt m˚ade at annullere et halvt træk<br />
p˚a.<br />
Denne m˚ade at udføre trækkene p˚a er yderst hurtigt og nem at anvende, n˚ar<br />
man først er blev vandt <strong>til</strong> den. Og det at et enkelt fejlagtigt klik ikke afgør et<br />
træks skæbne er ofte yderst velkomment.<br />
2.2.3 Information p˚a displayet:<br />
P˚a displayet vises flere informationer forholdsvist diskret. Under brættet er der<br />
et felt med et tal. Tallet viser hvor mange træk, der er blevet foretaget. Desuden<br />
fortæller baggrundsfarven her om det er hvid eller sorts tur, da den har en<br />
mørkere nuance ved sort spillers træk end n˚ar der er hvid der st˚ar for tur.<br />
P˚a venstre side af brættet st˚ar et hvidt tal. Dette tal viser det nuværende antal<br />
point for den hvide spiller, mens det sorte tal p˚a højre side viser antal af point<br />
for den sorte. Hvid er placeret i venstre side, da vi læser fra venstre mod højre<br />
og det er hvid der under de officielle regler starter.
2.2 Design af eget Interface 29<br />
Figur 2.6: Eksempel p˚a afsluttet spil med score vist p˚a figurerne.<br />
2.2.4 Andre funktioner:<br />
Der er i bunden af vinduet to knapper, hvor brugeren kan g˚a frem og <strong>til</strong>bage<br />
i spillet blandt de træk der er blevet foretaget. G˚ar brugeren <strong>til</strong>bage i spillet<br />
og ændrer et træk, fjernes de forrige træk fremad selvfølgelig da disse højst<br />
sandsynligt ikke længere er korrekte. Disse knapper giver mulighed for bedre at<br />
analysere spillets gang og kan ogs˚a benyttes efter det har n˚aet sin ende.<br />
Under menupunktet ”Game”er der ogs˚a mulighed for at gemme spillet. Det<br />
er kun brættet og dets historie der gemmes, alts˚a den nyeste bræt og alle de<br />
foreg˚aende som har ledt op <strong>til</strong> det. Inds<strong>til</strong>lingerne for hvem, der spiller hvad<br />
gemmes ikke. Hentes spillet vil de spillere der var sat <strong>til</strong> at spille inden spillet<br />
blev hentet stadig være gældende. Dette er ikke s˚a heldigt set fra et normalt spils<br />
synsvinkel, da dette giver brugeren mulighed for at snyde ved f.eks. at bytte om<br />
p˚a farverne for de to spiller. Men fra et testsynspunkt er dette ganske udmærket,<br />
da der kan undersøges hvordan forskellige AI’er takler den samme situation.<br />
Bemærk ogs˚a at vinduet er større, det er for at det skal være muligt at anvende<br />
større brætstørrelser, uden at brikkerne bliver alt for sm˚a.<br />
Det skal ogs˚a nævnes at AI’erne først begynder deres beregning, n˚ar brugeren<br />
klikker en gang p˚a brættet efter placeringen af sin egen brik. Dette er lidt
30 Design og brugervenlighed<br />
upraktisk, n˚ar der spilles mellem et menneske og en AI. N˚ar det er to AI’er<br />
der sættes op mod hinanden, bliver det dog nemmere at følge med i spillet, da<br />
brugeren selv kan bestemme, hvor hurtigt spillet skrider frem. Ønskes flere træk<br />
taget hurtigst muligt, er det blot at klikke det ønskede antal gange, og s˚a fortsætter<br />
AI’erne op <strong>til</strong> dette antal træk. Dette sker selvom beregningen af første<br />
træk ikke er blevet gjort færdig inden bruger er færdig med sine klik.
Kapitel 3<br />
3.1 Programmet<br />
<strong>Kunstig</strong> <strong>Intelligens</strong><br />
Herunder er en kort oversigt over programmet og dets opbygning.
32 <strong>Kunstig</strong> <strong>Intelligens</strong><br />
3.1.1 <strong>Taiji</strong>Driver:<br />
Figur 3.1: Oversigtsdiagram for programmet.<br />
<strong>Taiji</strong>Driver er main-metoden, der konstruerer <strong>Taiji</strong>Frame og viser den.<br />
3.1.2 <strong>Taiji</strong>Frame:<br />
<strong>Taiji</strong>Frame er rammen, som indeholder de dele, der bliver vist p˚a skærmen. Det<br />
er ogs˚a her dimensionerne for brættet ligger gemt.<br />
3.1.3 <strong>Taiji</strong>Listeners:<br />
<strong>Taiji</strong>Listeners h˚andtere opfangelsen af museklik indenfor vinduet.
3.1 Programmet 33<br />
3.1.4 <strong>Taiji</strong>Menu<br />
<strong>Taiji</strong>Menu h˚andterer dropdown menuen for menupunktet ”Game”.<br />
3.1.5 <strong>Taiji</strong>Settings:<br />
<strong>Taiji</strong>Settings indeholder menuen for ”Change settings”ved start af nyt spil, hvor<br />
det er muligt at ændre opsætning for hvilken AI brugeren spiller mod.<br />
3.1.6 <strong>Taiji</strong>Panels:<br />
<strong>Taiji</strong>Panels tegner selve brættet og omr˚aderne omkring, der f.eks. viser den<br />
nuværende score.<br />
3.1.7 <strong>Taiji</strong>Model:<br />
Hvor <strong>Taiji</strong>Frame st˚ar for at styre brugerfladen, at tegne brættet, vise menuerne<br />
og h˚andtere brugerens kommunikation med programmet, tager <strong>Taiji</strong>Model sig<br />
af selve spillet. <strong>Taiji</strong>Model h˚andterer brættet, hvilke træk, der foretages p˚a det,<br />
og kalder de forskellige kunstige intelligenser.<br />
3.1.8 <strong>Taiji</strong>Hash:<br />
<strong>Taiji</strong>Hash indeholder hashfunktionerne, som de forskellige AI’er har adgang <strong>til</strong><br />
gennem <strong>Taiji</strong>Model.<br />
3.1.9 <strong>Taiji</strong>Print:<br />
<strong>Taiji</strong>Print inderholder flere forskellige funktioner <strong>til</strong> effektivt ud skrive forskellig<br />
data, der kan være relevant n˚ar forskellige dele af de kunstige intelligenser testes.
34 <strong>Kunstig</strong> <strong>Intelligens</strong><br />
3.1.10 FigureMap:<br />
FigureMap bruges <strong>til</strong> at kortlægge de største figurer for begge farver s˚aledes at<br />
det bliver muligt at beregne scoren for hver spiller. Andre funktioner, der bruges<br />
<strong>til</strong> at konvertere almindelige taijibræt <strong>til</strong> figurbræt, som fortæller hvilke felter,<br />
der hænger sammen, findes ogs˚a her.<br />
3.1.11 Board:<br />
Board indeholder selve brættet og spilhistorien op <strong>til</strong> det nyeste træk og derudover<br />
funktioner, der har at gøre med h˚andtering af brættet.<br />
3.1.12 Node:<br />
Node indeholder datastrukturen for Nodes, som anvendes i alle AI’erne.<br />
3.1.13 Tree:<br />
Tree indeholder datastrukturen for et spiltræ. Denne benyttes dog kun i den<br />
først prototype AI, AI<strong>Taiji</strong>Minimax.<br />
3.1.14 AI<strong>Taiji</strong>Minimax:<br />
AI<strong>Taiji</strong>Minimax er prototypen lavet for at komme i gang med at lave kunstig<br />
intelligens <strong>til</strong> <strong>Taiji</strong>, effektivitets niveauet for denne AI er langt under de senere<br />
AI’er. Den benytter sig som den eneste af en bredde-først minimax søgning.<br />
3.1.15 AI<strong>Taiji</strong>ALphaBeta:<br />
En kunstig intelligense, der anvender minimax algorithmen med alpha beta pruning<br />
<strong>til</strong> at søge ned i spilgrafen for at finde et træk.
3.2 Generelle datastrukturer og metoder 35<br />
3.1.16 AI<strong>Taiji</strong>PureAlphaBeta:<br />
Fungere som AI<strong>Taiji</strong>AlphaBeta uden at tage højde for rotationer og spejlinger.<br />
Denne AI er lavet <strong>til</strong> test form˚al, hvor dens resultat kan holdes op imod resultater<br />
for AlphaBeta AI’en.<br />
3.1.17 AI<strong>Taiji</strong>Minimax2:<br />
Fungere som end dybde først minimax søgning, ved at deaktivere alpha beta<br />
pruningen i AlphaBeta AI’en. Denne AI anvendes ligeledes <strong>til</strong> test form˚al, hvor<br />
den holdes op mod resultaterne fra AlphaBeta AI’en.<br />
Da AI<strong>Taiji</strong>PureAlphaBeta og AI<strong>Taiji</strong>Minimax2 begge blot er versioner af AI-<br />
<strong>Taiji</strong>Alpha, med henholdvis alpha beta pruning og h˚andteringen af rotationerne<br />
og spejlinger deaktiveret. Er disse to ikke taget med i kildekoden.<br />
3.1.18 AI<strong>Taiji</strong>LocalArea<br />
Denne kunstige intelligens benytter sig af samme metoder som AlphaBeta AI’en,<br />
men begrænser sig selv <strong>til</strong> et lille søgeomr˚ade omkring det seneste træk.<br />
3.1.19 AI<strong>Taiji</strong>Growth<br />
Growth AI’en benytter sig af en dybde-først minimax søgning. Men i stedet for<br />
at lade alle de mulige træk prøves af, lader den træk mulighederne vokser ud<br />
fra de største figurer p˚a brættet.<br />
3.2 Generelle datastrukturer og metoder<br />
I dette afsnit beskrives nogle af de vigtigste datastrukturer og metoder, som g˚ar<br />
igen gennem mange af de kunstige intelligenser.
36 <strong>Kunstig</strong> <strong>Intelligens</strong><br />
3.2.1 Nodes:<br />
Noderne bruges <strong>til</strong> at holde styr p˚a informationerne om hvert enkelt spilstadie.<br />
I en node gemmes spilbrættet med alle brikkerne. Der gemmes ingen information<br />
om grænserne for de enkelte brikker, der gemmes blot hvor der er sorte,<br />
hvide og frie felter. Det betyder at der ikke er nogen bestemt struktur gemt i<br />
brættet om hvordan, spillet n˚aede dette punkt. Denne anonymitet er en fordel,<br />
da det er mere end en rute <strong>til</strong> hver eneste brætsituation i spillet, og brættets<br />
fortid derfor ikke m˚a være bundet <strong>til</strong> en bestemt forgænger. I noden kaldes det<br />
to-dimensionelle array hvor bræt<strong>til</strong>standen gemmes for nodeBoard.<br />
P˚a trods af brættets p˚akrævede anonymitet er koordinatorerne <strong>til</strong> det træk, der<br />
skabte Noden, gemt i fire variabler. wc, wr, bc, br, kolonnen for det hvide felt,<br />
rækken for det hvide felt, kolonnen for det sorte felt og rækken for det sorte felt<br />
for brikken, der blev lagt for at komme <strong>til</strong> dette stadie. Disse koordinatorer er<br />
et levn fra de første versioner, hvor der ikke blev taget højde for at flere forgænger<br />
kunne lede <strong>til</strong> samme spilsituation. I de nyere versionerne bliver de dog<br />
stadig brugt <strong>til</strong> at gemme det træk, som den kunstige intelligens finder frem <strong>til</strong><br />
skal foretages. I Noden er der ogs˚a en variabel <strong>til</strong>egnet at gemme værdien som<br />
heuristikken finder n˚ar Noden evalueres. Denne variabel hedder a.<br />
Dybden gemmes ogs˚a i Noden, under navnet d. Dybden er ligesom scoren uafhængig<br />
af hvilken rute, der er blevet taget for at n˚a Noden, da der skal være<br />
blevet lagt lige mange brikker før to brætsituationer kan være ens.<br />
Til slut holder to arraylister af variable længde styr p˚a hvilke forgængere og<br />
efterkommere Noden har. Den kaldes par for parents og den anden kaldes blot<br />
children.<br />
3.2.2 Skabelsen af efterkommere:<br />
Det vil i langt de fleste af de kunstige intelligenser før eller siden være nødvendigt<br />
at skabe alle efterkommere <strong>til</strong> en given node. Da denne proces i disse <strong>til</strong>fælde er<br />
den samme, vil den blive beskrevet her. I de <strong>til</strong>fælde hvor skabelsen af efterkommer<br />
foreg˚ar p˚a anden vis vil det være beskrevet i afsnittet om den p˚agældende<br />
AI.<br />
For at skabe alle efterkommerne <strong>til</strong> en Node, er det nødvendigt at foretage alle<br />
de træk som den p˚agældende spilleplade <strong>til</strong>lader. Dette gøres ved at gennemg˚a<br />
brættet fra enden <strong>til</strong> anden og lægge brikker alle de steder det er muligt. Det<br />
nemmeste er først at gennemg˚a brættet med vandrette brikker og hver gang der<br />
findes en vandret plads <strong>til</strong> en brik oprettes to Noder, en for hver led brikken<br />
kan vender p˚a, sort-hvid og hvid-sort. Der samme gøres derefter for alle mulighederne<br />
for at lægge en brik lodret. Checkes der for b˚ade lodrette og vandrette<br />
samtidigt opst˚ar der en masse special<strong>til</strong>fælde omkring to af kanterne af brættet,
3.3 Heuristik 37<br />
og der m˚a checkes separat for lodrette pladser langs højre side og det samme<br />
gælder de vandrette pladser langs bunden.<br />
3.3 Heuristik<br />
En heuristik bruges <strong>til</strong> at vurdere spillets <strong>til</strong>stand. Heuristikken skal alts˚a kunne<br />
levere en værdi, som giver et indblik i hvor godt eller skidt det st˚ar <strong>til</strong> for de to<br />
spiller. I <strong>Taiji</strong> vil det være naturligt at anvende differencen mellem de to spilleres<br />
score, som heuristik.<br />
I <strong>til</strong>fælde, hvor det er muligt at undersøge alle trækkombinationer <strong>til</strong> ende, er<br />
denne heuristik perfekt.<br />
3.3.1 Mulige forbedringer af heuristikken:<br />
Er det ikke muligt at beregne en fuldstændig løsningen, vil en heuristik, der<br />
tager højde for mere end blot den nuværende score, være mere anvendelig. Den<br />
nuværende score vil ikke nødvendigvis sige meget om hvad fremtiden vil bringe.<br />
F.eks er en fugl i h˚anden bedre en ti p˚a taget. Et endeligt spilstadie med et<br />
points forspring inden for den mulige søgedybde, vil selvfølgelig være bedre end<br />
en et stadie, hvor spilleren er foran med flere points, men hvor søgedybden er<br />
n˚aet og spilleren derfor ikke ved hvad trækkene efter vil bringe. (Søgedybden er<br />
hvor mange generationer man har besluttet at g˚a ned i spiltræet). Er heuristikken<br />
kun baseret p˚a scoren vil de 10 fugle p˚a taget blive opfattet som den bedste<br />
muglighed. Dette løsses ved at vinderstadier f˚ar <strong>til</strong>delt værdien uendelig, uanset<br />
hvor stor eller lille forskellen i scoren s˚a er. Dette kan selvfølgelig resultere i at<br />
AI’en vælger en løsning, hvor den vinder med en mindre point forskel end hvad<br />
der var mulighed for. Dette har dog først en betydning, hvis point forskellen<br />
lægges <strong>til</strong> en samlet score som strækker sig over flere spil. Er dette <strong>til</strong>fældet kan<br />
heuristikken modificeres <strong>til</strong> at sætte værdien for vinderstadier <strong>til</strong> uendeligt plus<br />
differencen i scoren mellem de to spiller, s˚a det bedste af vinderstadierne indenfor<br />
søgedybden kan vælges. Dette kan selvfølgelig kun gøres fordi ”uendeligt”i<br />
praksis blot er en værdi som er højere end noget der kan opn˚as i selve spillet.<br />
Det er ogs˚a muligt at forbedre heuristikken i <strong>til</strong>fælde hvor et endeligt stadie ikke<br />
n˚as indenfor søgedybden. Den ene spiller kan f.eks. have en højere score, men<br />
være blevet lukket af for at udvide sine to største figurer yderligere, mens den<br />
anden kan være lidt bagud p˚a point, men have gode muligheder for at udvide<br />
sine største figurer og dermed komme foran. I dette <strong>til</strong>fælde kan heuristikken<br />
udvides <strong>til</strong> ogs˚a at tage højde for hvor mange muligheder, der umiddelbart er for
38 <strong>Kunstig</strong> <strong>Intelligens</strong><br />
at udvide de større figurer i spillet. Det store spørgsm˚al er her hvordan vægtningen<br />
skal ligge mellem scoren og mulighederne for udvidelse. Her kunne det<br />
være en mulighed at anvende et neuraltnetværk eller simuleret nedkøling <strong>til</strong> at<br />
finpudse vægtningen basseret p˚a resultater og erfaringer gennem mange spil.<br />
Det største problem med en heuristik, der kun tager højde for selve scoren,<br />
opst˚ar n˚ar den kunstige intelligens ikke har mulighed for at søge hele træet<br />
igennem, og der er blevet lavet to store figurer for begge spillere, som det ikke<br />
længere er muligt at udvide p˚a. Da det er de to største figurer der tæller<br />
p˚a scoren, er alle andre figurer ligegyldige ind<strong>til</strong> en indhenter den næststørste<br />
figur. Dette betyder at den kunstige intelligens famler i blinde ind<strong>til</strong> en figur<br />
som minimum overg˚ar den næststørste figurs størrelse. Har begge spiller f.eks.<br />
to figurer p˚a 8 point, som ikke længere kan udvides, og ellers kun figurer med<br />
størrelsen 2 eller mindre, vil det være nødvendigt at bringe en af disse figurer<br />
op p˚a størrelsen 9 før det overhovedet kan ses p˚a heuristikken. Dette ville i de<br />
fleste <strong>til</strong>fælde kræve flere træk end den kunstige intelligens kan regne frem p˚a<br />
et større bræt. Dette vil simpelthen resultere i at alle træk vil f˚a <strong>til</strong>delt samme<br />
værdi og derfor vil den kunstige intelligens vælge et fuldstændigt <strong>til</strong>fældigt træk.<br />
Løsningen er selvfølgelig at ændre heuristikken s˚a den ikke kun ser p˚a de største<br />
figurer. Som nævnt tidligere kunne heuristikken ogs˚a se p˚a antallet af mulige<br />
udvidelser p˚a de største figurer. Men i stedet for at se p˚a muligheder omkring de<br />
to største figurer, s˚a sættes op <strong>til</strong> at se p˚a mulighederne omkring de to største<br />
figurer der endnu har muligheder for udvidelse. Den endelige udfordring lander<br />
igen p˚a vægtningen. Hvorn˚ar g˚ar den mindre figur med gode muligheder for<br />
udvidelse hen og bliver mere fordelagtigt at spille p˚a end den store figur som er<br />
begyndt at løbe tør for udvidelses muligheder.<br />
3.3.2 Konklusion p˚a heuristik:<br />
I den nuværende løsning anvendes den simple heuristikken, der kun ser p˚a selve<br />
spillets score <strong>til</strong> de forskellige AI’er. Men som det er blevet beskrevet er der en<br />
lang række steder hvor denne heuristik ikke er optimal. Dette gælder n˚ar det<br />
ikke er en praktisk mulighed at afdække hele spiltræet, hvilket er <strong>til</strong>fældet ved<br />
et hvert spilbræt, der er støre end 4x4. Det forventes derfor at en forbedring af<br />
heuristikken, vil give en yderst mærkbar forbedring p˚a AI’ernes præstation.
Kapitel 4<br />
Minimax<br />
Minimax 1 er en velkendt algoritme, der ofte anvendes <strong>til</strong> brætspil. Minimax<br />
tager udgangspunkt i at begge spiller altid vil forsøge at maksimere sit eget<br />
udbytte og minimere modstanderens.<br />
Minimax fungerer ved at generere et træ med alle mulige træk gennem hele<br />
spillet. De afsluttende spilstadier (bladene p˚a træet) bliver s˚a givet en heuristisk<br />
værdi, som fortæller om dette stadie er vundet, tabt eller uafgjort. I <strong>Taiji</strong>s<br />
<strong>til</strong>fælde ogs˚a hvor meget, der er blevet vundet eller tabt med, da det er muligt<br />
at vinde med forskellige antal points. Disse værdier bliver ført videre op gennem<br />
træet. Dette sker ved at generationerne af forældre skiftevis p˚atager sig<br />
den højeste af børnenes værdier eller den laveste, alt efter hvilken spiller generationen<br />
repræsenterer. Her igennem opn˚as det at spillerne altid vil vælg det<br />
træk med det minimale maksimum for sin modstander og derved det maksimale<br />
minimum for sig selv. Deraf navnet Minimax. Med andre ord vælger spilleren<br />
den vej hvor modstanderens bedst mulige udbytte er det ringeste.<br />
Da hele træet søges igennem under alle omstændigheder, er det b˚ade muligt at<br />
lave en Minimax algoritme, hvor der anvendes en dybde-først fremgangsm˚ade,<br />
og en hvor der anvendes en bredde-først fremgangsm˚ade.<br />
Fordelen ved en bredde-først søgning, er at den er mere overskuelige at have<br />
med at gøre. Derimod er mulighederne for videreudvikling bedre for dybde-<br />
1 Minimax-algoritmen st˚ar beskrevet i kapitel 6, afsnit 2 i ”Articial Intelligence - A Modern<br />
Approach”.
40 Minimax<br />
først søgningen, da denne er nødvendig for at kunne lave Alpha-Beta pruning<br />
(se afsnit om dette). I brede-først søgningen evalueres størstedelen af slutstadierne<br />
først n˚ar søgningen samlet har n˚aet bunden af træstrukturen, og s˚a er det<br />
for sent at begynde at skære grene af som ikke behøves søges igennem.<br />
4.1 Beskrivelse af Minimax med brede-først søgning<br />
Da bredde-først versionen af Minimax er blev skrevet som en øvelse og ikke<br />
skulle anvendes <strong>til</strong> videreudvikling, er den kun blevet skrevet <strong>til</strong> at kunne spille<br />
sort.<br />
Bredde-først versionen fungere ved først at skabe hele træet, ved at sætte det<br />
nuværende spilstadie som roden og s˚a lade hver generation vokse ud fra den<br />
forrige. Undervejs bliver der holdt styr p˚a generationerne, ved at hver Node i<br />
den nye generation gemmes i et af to arrays. Et array for ulige generationer og et<br />
for lige. Det lige array tømmes, n˚ar en nye lige generation p˚abegyndes og <strong>til</strong>svarende<br />
tømmes det ulige n˚ar en nye ulige generation startes. Det gøres, fordi det<br />
er nødvendigt at holde styr p˚a medlemmerne af de to nyeste generationer n˚ar<br />
alting foreg˚ar per generation, i stedet for at fokusere p˚a en enkelt Node og dens<br />
efterkommer eller forgænger. De endelige stadier, ogs˚a kaldet bladene, gemmes<br />
ogs˚a i et array, da bladene ikke kun vil være at finde i den sidste generation.<br />
N˚ar træet er skabt p˚abegyndes beregning af værdierne op gennem træet.<br />
Beregningen startes i den endelige generation. Alle Noderne af denne generation<br />
evalueres og f˚ar <strong>til</strong>delt en værdi. Nodernes forgænger <strong>til</strong>føjes <strong>til</strong> det ulige eller<br />
det lige array afhængigt af generationen. For næste generation p˚atager nodernes<br />
sig alle den højeste værdi af sine børn, n˚ar generationen er lige. Hvis generationen<br />
er ulige p˚atager noderne sig den laveste værdi af sine børn. Herudover<br />
evalueres alle bladene af denne generation som befinder sig i arrayet for bladene,<br />
og <strong>til</strong>føjes <strong>til</strong> det ulige eller det lige array efter generation. Alle forgængerne<br />
<strong>til</strong>føjes igen <strong>til</strong> enten det ulige eller det lige array, efter at arrayet er blevet tømt<br />
for den gamle generation. S˚aledes fortsættes der ind<strong>til</strong> værdierne n˚ar roden og<br />
det bedste træk kan vælges.<br />
4.1.1 Pseudo-kode for Minimax med brede-først søgning:<br />
Funktion : Minimax ( s t a d i e ) , r e t u r n e r e r et træk<br />
Input : s t a d i e , s p i l l e t s nuværende s t a d i e .<br />
rod = s t a d i e<br />
BeregnTræ ( SkabTræ ( rod ) )
4.2 Beskrivelse af Minimax med dybde-først søgning 41<br />
RETURN rodens barn med den mindste værdi<br />
4.2 Beskrivelse af Minimax med dybde-først søgning<br />
I dybde-først søgningen, søger den først en gren <strong>til</strong> bunds og n˚ar den n˚ar bunden,<br />
g˚ar den blot et skridt <strong>til</strong>bage for at tage et nyt skridt fremad.<br />
4.2.1 Pseudo-kode for Minimax med dybde-først søgning:<br />
Funktion : Minimax ( s p i l l e r , s t a d i e ) , r e t u r n e r e et træk<br />
Input : s p i l l e r , s p i l l e r n e som s t˚a r f o r tur .<br />
s t a d i e , s p i l l e t s nuværende s t a d i e .<br />
IF s p i l l e r = hvid THEN v = Max( s t a d i e )<br />
ELSE v = Min( s t a d i e )<br />
RETURN Trækket med værdien v<br />
Funktion : Max( S ) , r e t u r n e r e en værdi f o r s t a d i e t<br />
Input : S , det a k t u e l l e s t a d i e i s p i l l e t .<br />
IF S er et e n d e l i g t s t a d i e<br />
THEN v = e v a l u e r i n g a f S RETURN v<br />
v = −i n f<br />
FOR a l l e efterkommere a f S ( s )<br />
m = Min( s )<br />
IF v < m THEN v = m<br />
RETURN v<br />
Funktion : Min(S ) , r e t u r n e r e en værdi f o r s t a d i e t<br />
Input : S , det a k t u e l l e s t a d i e i s p i l l e t .<br />
IF S er et e n d e l i g t s t a d i e<br />
THEN v = e v a l u e r i n g a f S RETURN v<br />
v = i n f<br />
FOR a l l e efterkommere a f S ( s )<br />
m = Max( s )<br />
IF v > m THEN v = m<br />
RETURN v
42 Minimax<br />
4.3 Spilgraf for 3x3 <strong>Taiji</strong> spil:<br />
Forskellen mellem et spiltræ og en spilgraf, er at det i spilgrafen er muligt at<br />
flere foreg˚aende stadier kan ende i samme stadie.<br />
Herunder ses spilgrafen for <strong>Taiji</strong> p˚a en 3 gange 3 spilplade. Alle rotationer og<br />
spejlinger af et spilbræt, anses for at være et spilstadie. Var dette ikke <strong>til</strong>fældet<br />
skulle grafen være betydeligt større, f.eks. ville der i stedet for 4 mulige starttræk<br />
være 18.
4.3 Spilgraf for 3x3 <strong>Taiji</strong> spil: 43<br />
Figur 4.1: Spilgrafen for <strong>Taiji</strong> p˚a et 3x3 bræt.
44 Minimax<br />
Herunder ses spilgrafen efter de endelige spilstadier har f˚aet <strong>til</strong>delt deres værdier.<br />
Spilgrafen er blevet vendt om for at illustrere hvordan værdierne først<br />
bliver <strong>til</strong>delt de endelige stadier og derefter bliver givet videre op gennem træet.<br />
(Positiv score er <strong>til</strong> hvids fordel, negativ er <strong>til</strong> sorts.)
4.3 Spilgraf for 3x3 <strong>Taiji</strong> spil: 45<br />
Figur 4.2: Spilgrafen for <strong>Taiji</strong> p˚a et 3x3 bræt med score p˚a slutstadierne. Positive<br />
værdier er <strong>til</strong> hvids fordel, negative er <strong>til</strong> sorts.
46 Minimax<br />
Herunder ses spilgrafen n˚ar værdierne er blevet sendt op gennem træet efter<br />
minimax-princippet. Dette er grafen som den vil se ud, hvis det er den hvide<br />
spiller der har det første træk, ergo er det blevet kørt Max() p˚a roden.
4.3 Spilgraf for 3x3 <strong>Taiji</strong> spil: 47<br />
Figur 4.3: Spilgrafen for <strong>Taiji</strong> p˚a et 3x3 efter Minimax genkørsel med Max som<br />
starter.
48 Minimax<br />
Som det kan ses ender spilgrafen i et nul ved roden. Dette betyder at der ikke<br />
er nogen vinderstrategi, som kan lede <strong>til</strong> en sikker sejr. Dette betyder dog ogs˚a,<br />
at det er muligt at f˚a et uafgjort resultat uanset hvad modstanderen gør. S˚a<br />
længe begge parter spiller optimalt vil spillet ende uafgjort. Der vil først være<br />
en sejrherre, n˚ar den ene part beg˚ar en fejl som vil lede <strong>til</strong> modstanderens sejr.<br />
Det kan ogs˚a ses at det første træk ingen betydning har for resultatet, da alle<br />
anden generations spilstadierne har værdien nul. Spilles der mod en modstander<br />
der beg˚ar fejl er nogle af disse træk dog bedre end andre. Dette kan f.eks.<br />
bedømmes p˚a hvor stor en andel af de efterfølgende stadier der føre <strong>til</strong> en sejr.<br />
Jo større andel af træk, der føre <strong>til</strong> en sejr, jo større sandsynlighed for at en forhastet<br />
modstander vil komme <strong>til</strong> at vælge et af disse. Placeres den sorte halvdel<br />
af brikken i et hjørne, er der 6 efter følgende stadier der leder <strong>til</strong> en sejr ud af<br />
de i alt 15 forskellige muligheder.<br />
Herunder er en tabel over de fire mulige starttræk og hvor mange af modstanderens<br />
træk, der efterfølgende vil lede <strong>til</strong> sejr for den første spiller:<br />
Placering Træk, der leder <strong>til</strong> sejr Samlet antal træk Procentdel<br />
Sort i hjørnet 6 15 40%<br />
Hvid i hjørnet 3 15 20%<br />
Sort i midten 0 6 0%<br />
Hvid i midten 3 6 50%<br />
Tages der ikke højde for spejlinger og rotationer ser tabellen s˚aledes ud:<br />
Placering Træk, der leder <strong>til</strong> sejr Samlet antal træk Procentdel<br />
Sort i hjørnet 7 16 43,75%<br />
Hvid i hjørnet 3 16 18,75%<br />
Sort i midten 0 12 0,00%<br />
Hvid i midten 6 12 50,00%<br />
Ud fra dette kan det ses, at sandsynligheden for at modstanderen laver en fejl,<br />
der leder den første spiller <strong>til</strong> sejr, er størst ved at placere spillerens egen halvdel<br />
af brikken i midten. Det kan ogs˚a forventes, at jo større antallet af mulige træk<br />
er, jo større er sandsynligheden for at der laves en fejl. Er dette sandt, kan det<br />
være bedre at placere den sorte halvdel af brikken i et hjørne, da dette øger<br />
antallet af mulige træk p˚a bekostning af en relativt lille nedgang i procentdelen<br />
af træk der vil lede <strong>til</strong> sejr.<br />
Det kan ogs˚a ses, at det at placere den sorte halvdel af brikken i midten udelukker<br />
muligheden for sejr, medmindre modstanderen laver fejl længere inde i<br />
spillet, hvor det vil være nemmere at overskue konsekvenserne af et træk og<br />
derved er mindre sandsynligt at der laves en fejl. Det er m˚aske endda <strong>til</strong>fældet<br />
at sejren slet ikke er mulig efter dette træk. For at undersøge dette er her<br />
spilgrafen for trækket med sort i midten:
4.3 Spilgraf for 3x3 <strong>Taiji</strong> spil: 49<br />
Figur 4.4: Spilgrafen for <strong>Taiji</strong> p˚a et 3x3 med fokus p˚a første træk med sort i<br />
midten.
50 Minimax<br />
Det kan ses at alle de endelige stadier, som kan opn˚as fra dette træk, enten<br />
ender i uafgjort eller i en sejr <strong>til</strong> sort.<br />
Gennemg˚as alle endelige stadier kan det ogs˚a ses, at intet stadie med sort i<br />
midten g˚ar <strong>til</strong> den hvide spiller. Dette gælder selvfølgelige ogs˚a den anden vej<br />
rundt, intet stadie med hvid i midten g˚ar <strong>til</strong> den sorte spillers sejr.<br />
Her af kan det konkluderes at den spiller, der først placeres sin farve i midten,<br />
vil være sikret minimum et uafgjort resultat.<br />
Desuden kan det ses at et hvert slutstadie med et frit felt i midten ender uafgjort.<br />
Med andre ord er midten nødvendig for at vinde spillet, n˚ar brættet er p˚a 3 gange<br />
3 felter.
Kapitel 5<br />
5.1 Spilgraf<br />
Optimering af Minimax<br />
En kraftig reducering kan opn˚as ved at skifte fra et spiltræ <strong>til</strong> en spilgraf. Forskellen<br />
mellem et spil træ og en spilgraf er, at hvor et spiltræs grene aldrig vil g˚a<br />
sammen igen, er dette en mulighed for en spilgraf. I praksis er dette muligheden<br />
for at samme bræt<strong>til</strong>stand kan n˚as ad mere end en vej.
52 Optimering af Minimax<br />
Figur 5.1: Eksempel p˚a et lille spiltræ.<br />
Figur 5.2: Eksempel p˚a en lille spilgraf for samme bræt<strong>til</strong>stande.
5.2 Rotationer og spejlinger 53<br />
5.2 Rotationer og spejlinger<br />
At undg˚a rotationer og spejlinger er en af de mest besparende faktorer i <strong>Taiji</strong>,<br />
især ved det helt første træk. Rotationer og spejlinger g˚ar i sin enkelthed ud<br />
p˚a at to bræt<strong>til</strong>stande anses for at være samme <strong>til</strong>stand, hvis den ene er en<br />
rotation eller spejling af den anden. Hvis to bræt<strong>til</strong>stande er ens, behøves de<br />
efterfølgende beregninger kun laves en gang. Jo flere bræt<strong>til</strong>stande, der kan siges<br />
at være de samme, jo færre beregninger skal der <strong>til</strong>.<br />
Figur 5.3: Eksempel p˚a tre 4x4 bræt<strong>til</strong>stande, der kan betragtes som værende<br />
ens.<br />
I praksis kommer reduceringen kraftigst <strong>til</strong> syne ved første træk, da de efterfølgende<br />
reducering bliver færre, fordi den første brik der sættes kommer<br />
<strong>til</strong> at danne et anker for efterfølgende rotationer og spejlinger. Herunder ses<br />
antal af bræt<strong>til</strong>stande før reduceringen og efter reducering pga. rotationer og<br />
spejlinger:
54 Optimering af Minimax<br />
Figur 5.4: Alle trækmuligheder for et standardbræt. Hver streg repræsentere<br />
en brik og de to m˚ader, som brikken kan vende p˚a.<br />
Figur 5.5: Alle træk muligheder for først træk p˚a et standardbræt efter reducering<br />
pga. rotationer og spejlinger.<br />
Første forgrening i spilgrafen reduceres her <strong>til</strong> omkring en 1/8. Langt de fleste<br />
reduceringer sker i form af denne reducering og alle de bræt<strong>til</strong>stande der aldrig<br />
kommer <strong>til</strong> at eksistere fordi deres forgænger blev fjernet her. Der opst˚ar dog<br />
yderligere reduktioner ned gennem spilgrafen efter den store reducering, n˚ar der<br />
undervejs dannes ny symmetri.
5.3 Hash funktioner 55<br />
Figur 5.6: Eksempel p˚a reducering af bræt<strong>til</strong>stande pga. rotationer og spejlinger<br />
længere nede i spilgrafen.<br />
Som tommelfingerregel er reduceringen p˚a en faktor 8, fire rotationer af brættet<br />
og fire rotationer af det spejlvendte bræt. Dette gælder dog kun kvadratiske<br />
brætstørrelser, for rektangulære brætstørrelser er det ikke muligt at lave 90<br />
graders rotationer og reduceringen bliver derfor halveret <strong>til</strong> en faktor 4.<br />
5.3 Hash funktioner<br />
Efter at have sparet store dele af spiltræet væk ved at lade det være en graf i<br />
stedet, hvor hvor flere vej kan lede <strong>til</strong> samme stadie, er det blevet nødvendigt<br />
ved hvert enkelt spilstadie at checke om dette spilstadie allerede eksisterer. For<br />
at gøre dette m˚a spilstadiet sammenlignes med alle andre spilstadier, der ind<strong>til</strong><br />
videre er blevet dannet i aktuelle spil, inden stadiet bliver oprettet i systemet
56 Optimering af Minimax<br />
som et unikt stadie, eller om det blot skal bruges <strong>til</strong> at <strong>til</strong>føje ny information <strong>til</strong><br />
et allerede eksisterende stadie.<br />
Denne søgning efter ens stadier kan, hvis den bare udføres blindt, potentielt øge<br />
tidsfaktoren s˚a meget at det ikke kan betale sig at g˚a fra spiltræ <strong>til</strong> spilgraf.<br />
Søgningen skal udføres for hvert stadie i spillet, og da der er tusinder af stadier,<br />
skal der for tusindvis af stadier søges igennem netop tusindvis af stadier. Dette<br />
vil selvfølgelig være et større problem i slutningen af et spil end i starten, hvor<br />
der endnu ikke er s˚a mange stadier at søge igennem. Desuden kan et matchende<br />
stadie findes tidligt i søgning, som s˚a kan afsluttes der. I gennemsnit kan det forventes<br />
at et stadie findes halvvejs inde i søgningen, men dette gælder selvfølgelig<br />
kun i <strong>til</strong>fælde hvor der er et matchende stadie. Er der ikke et matchende stadie,<br />
vil det være nødvendigt at søge alle stadierne igennem for at konstatere at der<br />
ikke er et.<br />
Dette vil give d˚arlig svartid, hvis der søges blindt fra enden <strong>til</strong> anden. Men<br />
søgningen kan optimeres ved at begrænse den <strong>til</strong> et mindre omr˚ade hvori det<br />
kan afgøres at stadiet enten eksisterer eller ikke eksisterer.<br />
Det er her hashtabeller kommer ind i billedet. Hashtabeller 1 bruges <strong>til</strong> at gøre<br />
søgninger hurtigere, ikke kun i spiltræer men i alle former data. Det gøres ved at<br />
opdele data i grupper, s˚aledes at det kun er nødvendigt at søge en enkelt gruppe<br />
igennem for at konstatere om dataene eksistere eller ej. For at bestemme hvor<br />
i hashtabellen et stykke data skal placeres, er det nødvendigt at en hashfunktion<br />
beregner en hashværdi for det stykke data der skal gemmes. Hashværdien<br />
fungerer lidt ligesom et postnummer og bestemmer hvor i hashtabellen dataene<br />
skal gemmes, og derved ogs˚a hvor de kan findes og findes hurtigt igen. For at<br />
dette skal fungere, er det nødvendigt at hashværdierne overholder nogle regler.<br />
Flere stykker data m˚a godt f˚a <strong>til</strong>delt samme hashværdi, dette betyder blot at de<br />
havner i samme gruppe. Derimod m˚a to ens stykker data ikke kunne f˚a forskellige<br />
hashværdier, da system s˚a ikke længere vil være p˚alideligt. Det vil fejlagtigt<br />
give svaret at der ikke findes flere forekomster af et givne stykker data, selvom<br />
dette ikke er korrekt.<br />
Da der for hvert træk lægges en brik, og da der p˚a intet tidspunkt hverken<br />
fjernes eller flyttes brikker, vil to ens stadie kun kunne opst˚a i samme generation,<br />
da to ens stadier altid vil have samme antal brikker. Af denne grund kan<br />
dybden p˚a træet anvendes som en hash værdi.<br />
Ulempen ved at bruge dybden er at de forskellige generationer meget hurtigt<br />
kan komme <strong>til</strong> at indeholde rigtigt mange spilstadier. Især de midterste generationer<br />
i spillet, hvor der er mange stadier i den tidligere generation at komme<br />
fra, og der stadig er mange fri muligheder for placering af nye brikker.<br />
Der er dog flere fordele ved at benytte dybden som en hashværdi. Den er nem<br />
at komme <strong>til</strong>, det er blot at holde styr p˚a turen eller tælle antallet af brikker,<br />
1 Der kan findes mere information om hash-tabeller og -funktioner i ”Introduction to Algo-<br />
rithms”, kapitel 11.
5.3 Hash funktioner 57<br />
hvilket igen blot kan gøres ved at tælle antallet af enten sort eller hvide felter.<br />
I denne implementering er dybden endda gemt i hver eneste Node, s˚a den er<br />
hurtigere og lettere <strong>til</strong>gængelige end som s˚a, da en hashfunktion faktisk slet ikke<br />
er nødvendig. Udover <strong>til</strong>gængeligheden vil fordelingen af spilstadierne ogs˚a være<br />
ganske udmærket. P˚a trods af at der vil værre færre stadier gemt i de først generationer,<br />
vil spilstadierne være godt fordelt ud over de forskellige generationerne.<br />
Scoren er ogs˚a en mulig hash værdi, da scoren selvfølgelig altid ville være den<br />
samme for ens stadier. Differencen i scoren vil dog i et spil mellem jævnbyrdige<br />
modstander ofte ligge tæt omkring værdien 0, hvilket vil betyde at store dele af<br />
stadierne vil havne i samme grupper. Derfor vil de oftest forekommende <strong>til</strong>fælde<br />
kræve de største søgninger. Dette er selvfølgelig ikke hensigtsmæssigt. Ved at<br />
anvende de to score i stedet for blot difference mellem dem, kan der skabes mere<br />
variation i hashværdierne. Dette kan f.eks. gøres ved at anvende hashfunktionen:<br />
hashværdi = hvids score + (sorts score · (max score + 1))<br />
Med denne hashfunktion vil kun de spilstadier, der har præcis samme score per<br />
spiller, f˚a samme hashværdi. For mange spilstadier vil scorerne ligge omkring<br />
de samme værdier, men slet ikke i s˚a høj grad, som n˚ar kun differencen anvendes.<br />
Selve hashtabellen er blevet lavet som et to-dimensionelt array. Spilstadierne<br />
bliver inddelt i denne tabel efter to hashværdier som bestemmer i henholdsvis<br />
hvilken række og hvilken kolonne det enkelt spilstadie placeres. Den ene af disse<br />
værdier er dybden. Omkostningerne i form af regnekraft for at fremskaffe den<br />
er stort set ikke eksisterende, samtidigt med at den gør et glimmerende stykke<br />
arbejde, n˚ar det kommer <strong>til</strong> at fordele stadierne ud nogenlunde ligeligt. Den<br />
anden værdi bliver overladt <strong>til</strong> en mere traditionel hashfunktion.<br />
I første omgang fik hashfunktionen baseret p˚a scoren opgaven at fordele stadierne,<br />
og blev nanvgivet hashFunction. Kombinationen af hashFunction og dybden<br />
fungere rimeligt godt p˚a sm˚a brætter, hvor det er muligt at regne hele spiltræet<br />
igennem. Denne kombinationen har dog, uanset hvilken størrelse et bræt har,<br />
den ulempe at generationen og scoren ofte følges ad, jo længere inde i spillet,<br />
jo højere score. Men de største problemer opst˚ar p˚a store brætter, hvor det<br />
kun er muligt at søge f˚a generationer frem. For de første par træk i spillet vil<br />
scoren altid være den samme. For første træk vil der blive lagt en brik, hvilket<br />
altid vil give et point <strong>til</strong> sort og et point <strong>til</strong> hvid, og da det er er de to største<br />
figurer der tæller, vil andet træk resultere i scoren to-to uanset hvordan den<br />
anden brik placeres. Først ved spillets tredje træk fremkommer nogen form for<br />
variation nemlig s<strong>til</strong>lingerne to-to, to-tre, tre-to og tre-tre. Resultatet er alts˚a<br />
at hashFunction lige s˚a vel kunne have være undladt for de først to træk og kun<br />
opdeler spilstadierne i yderligere fire grupper for det tredje.
58 Optimering af Minimax<br />
Det er derfor hensigtsmæssigt at finde en nye hashfunktion <strong>til</strong> at erstatte hash-<br />
Function. Dette alternativ kun baseres p˚a brikkernes placering p˚a bræt, da den<br />
enkelte briks placering er s˚a godt som uafhængig af dybden. Problemet er bare<br />
at en hashfunktion skal give samme hashværdi uanset om spilstadiets bræt er<br />
blevet spejlvendt, roteret eller en kombination af disse for at fungere. For at<br />
komme uden om dette problem, kan et bræt med værdi bruges <strong>til</strong> finde en hashværdi.<br />
Et s˚adant værdibræt skal have samme dimensioner som selve spilbrættet<br />
og skal forblive det samme uanset hvordan det vendes og drejes. Hvert felt skal<br />
have en værdi, som s˚a kan tages i anvendelse, hvis en brik lægges oven p˚a det,<br />
og derved f˚a indflydelse p˚a den endelige hashværdi.<br />
I dette <strong>til</strong>fælde er værdibrættet konstrueret s˚aledes; det midterste felt har værdien<br />
1, der kan være tale om flere felter, hvis antallet af kolonner eller rækker af<br />
lige generationer. Værdierne for fletterne lodret og vandret ud fra midten stiger<br />
med 1 hver gang de kommer et felt længere fra midten. Disse felter kan ses<br />
som to akser. De resterende felter f˚ar deres værdi ud fra disse. Er et felt ud for<br />
værdien 2 p˚a den lodret akse og ud for værdien 3 p˚a den vandret, bliver feltet<br />
<strong>til</strong>delt værdien 6 (2 x 3).<br />
Et eksempel p˚a dette kan se s˚aledes ud:<br />
12 9 6 3 3 6 9 12<br />
8 6 4 2 2 4 6 8<br />
4 3 2 1 1 2 3 4<br />
8 6 4 2 2 4 6 8<br />
12 9 6 3 3 6 9 12<br />
Den oprindelige ide var at lægge alle værdierne sammen for alle de felter hvor<br />
der l˚a en hvid halvdel, og trække summen fra af værdierne for alle de felter hvor<br />
der l˚a en sort halvdel. Det kan dog hurtigt observeres at dette ikke er en optimal<br />
fremgangsm˚ade, da en vandret brik vil <strong>til</strong>føje den samme værdi s˚a længe den<br />
bevæger sig langs en række ind<strong>til</strong> den n˚ar midten. Det samme gælder en lodret<br />
briks bevægelse i en kolonne.<br />
Eksembel for midterste række: 2 - 1 = 1, 3 - 2 = 1, 4 - 3 = 1.<br />
Dette kan løses ved i stedet for at fratrække de sorte værdier, halveret værdien<br />
og s˚a lægge den <strong>til</strong>, for fortsat at bibeholde en vigtig afvigelse mellem de<br />
to farver. Til sidst benyttes modulus <strong>til</strong> at reducere resultatet <strong>til</strong> en passende<br />
størrelse. Denne hashfunktion er navngivet hashFunction2.<br />
Til slut forsøges med en tredje funktion som kombinerer hashFunction og hashFunction2.<br />
Denne funktion lægger blot hashværdierne fra de to funktionerne<br />
samme og anvender igen modulus <strong>til</strong> at holde værdien inde for rammerne. Den<br />
funktion har f˚aet navnet hashFunction3.
5.3 Hash funktioner 59<br />
5.3.1 Test af hashfunktioner<br />
Køretiderne er efter at den menneskelige spiller har foretaget første træk, da<br />
nogle af de kunstige intelligenser sætter en brik i midten uden at tænke sig om,<br />
hvis de har første træk, og derfor ikke kan bruges <strong>til</strong> sammenligning. Gældende<br />
træk er alts˚a andet træk i spillet, dette er blevet taget ti gange for hver størrelse<br />
af hver af kunstig intelligens og gennemsnittet af disse ti er hvad der ses i tabellen<br />
her under:<br />
4x4 Kun dybde hashFunction hashFunction2 hashFunction3<br />
AlphaBeta 5,040 1,127 1,555 1,178<br />
LocalArea 2,997 1,398 1,333 1,348<br />
Growth 0,183 0,144 0,092 0,096<br />
For et spillebræt p˚a fire gange fire ses det at de kunstige intelligenser kører<br />
betydeligt hurtigere n˚ar de tre hash funktioner anvendes sammen med dybden<br />
end n˚ar dybden anvendes alene. Der er ikke blevet lavet forsøg uden dybden som<br />
hash værdi, da denne er dybere integreret i koden og derfor ikke lige s˚a nem<br />
at fjerne i test henseende som de andre hashfunktioner. Overraskende er det<br />
hashFunction, som kun er baseret p˚a scoren, der klare sig bedst for AlphaBeta<br />
p˚a et fire gange fire bræt. Det kunne forventes at dette skyldes beregningstiden<br />
for værdigrafs metoden i hashFunction2 var større end den score baserede<br />
metode i hashFunction, men var dette <strong>til</strong>fældet ville hashFunction3’s resultat<br />
være d˚arligere en b˚ade hashFunction og hashFunction2, da denne anvender begge<br />
metoder, hvilket ikke er <strong>til</strong>fældet. HashFunction3 klarer sig stort set lige s˚a<br />
godt som hashFunction, hvilket m˚a betyde at problemet ligger i hashFunction2.<br />
HashFunction2 anvender som sagt værdigrafs metoden alene og heri opst˚ar problemet,<br />
da der ikke er meget variation i værdierne i en værdigraf af den størrelse:<br />
4 2 2 4<br />
2 1 1 2<br />
2 1 1 2<br />
4 2 2 4<br />
Mange spilstadier vil derfor f˚a samme hash-værdi og der vil s˚aledes være flere<br />
stadier, der skal søges igennem per søgning.<br />
9x9 Kun dybde hashFunction hashFunction2 hashFunction3<br />
AlphaBeta 62,56 41,34 4,22 3,95<br />
LocalArea 2,997 1,398 1,333 1,348<br />
Growth 20,12 1,82 1,34 0,82<br />
Den oprindelige frygt for at en hashfunktion baseret p˚a score ville give meget<br />
lille variation i starten af spillet, viser sig her begrundet. HashFunction klarer<br />
sig næsten lige s˚a d˚arligt som dybden anvendt alene. Mens hashFunction2 og 3
60 Optimering af Minimax<br />
klarer sig hele ti gange bedre end hashFunction. Der er unægtelig forskel p˚a om<br />
den menneskelige spiller skal vente fire sekunder p˚a at modstanderen foretager<br />
sit ryk eller om det tager næsten et helt minut.<br />
LocalArea og Growth vil der blive set nærmere p˚a senere, men generelt er resultatet<br />
det samme for disse to.<br />
5.3.2 Konklusion p˚a hashfunktioner:<br />
Testen viser som forventet at hashFunction2 giver en betydeligt hurtigere beregning<br />
end ved brug af den oprindelige hashFunction, n˚ar det kommer <strong>til</strong> den<br />
almindelige minimax algoritme med aplha beta pruning p˚a en stor plade, hvor<br />
det ikke er muligt at søg ret langt ned i spiltræet. Testen viser ogs˚a at selvom<br />
den kombinere hashfunktion hashFunction3 ikke altid er hurtigst, kommer den<br />
altid nær den bedste tid, da den kombinere de to tidligere versioners styrker. Det<br />
kan ogs˚a ses at denne kombination ikke har de store tidsomkostninger, selvom<br />
den laver b˚ade beregningen fra hashFunction og fra hashFunction2.<br />
Dette peger ogs˚a imod at selve beregningerne for hash-værdier ikke er den tunge<br />
del af svartiden. F.eks. er der en meget lille forskel i beregningstiden mellem<br />
hashFunction og hashFunction3 for AlphaBeta AI’en p˚a en fire gange fire plade,<br />
hvor hashFunction2 klare sig mindre godt og derfor ikke burde spille ind p˚a hashFunction3s<br />
resultat i forhold <strong>til</strong> hashFunction. Men der opst˚ar alts˚a ikke den<br />
stor forskel mellem hashFunction og hashFunction3, selvom hashFunction3 laver<br />
to beregninger, hvor hashFunction laver en. Den lille forskel i beregningstiden<br />
mellem hashFunction og hashFunction3, kan dog ogs˚a skyldes at hashværdien<br />
for hashFunction3 er det bedre og derfor giver hurtigere søgetider, og at dette<br />
derfor opvejer den ekstra regnetid per hashværdi.<br />
Alt i alt vil hashFunction3 være det bedste generelle valg. Den klare sig altid<br />
bedst eller næstbedst i testene, og i de <strong>til</strong>fælde hvor den kun er næstbedst ligger<br />
den meget tæt op ad den bedste. Det at den tager egenskaberne fra begge de<br />
forrige funktioner betyder at den aldrig vil klare sig specielt meget d˚arligere end<br />
den bedste af disse to i et hvilket som helst <strong>til</strong>fælde.<br />
5.4 Alpha-beta pruning<br />
Alpha-beta pruning 2 er en teknik, der kan anvendes <strong>til</strong> at se bort fra store dele<br />
af et spiltræ.<br />
2 Alpha-beta pruning er beskrevet i kapitel 6, afsnit 3 i ”Articial Intelligence - A Modern<br />
Approach”.
5.4 Alpha-beta pruning 61<br />
Alpha-beta pruning kan anvendes sammen med minimax algorithmen <strong>til</strong> at begrænse<br />
mængden af grene, der er skal søges i gennem i spiltræet. Ved hjælp af<br />
alpha beta pruning er det muligt at afgøre om det er værd at fortsætte søgningen<br />
ned af en gren, eller om det allerede kan ses at et bedre resultat kan opn˚as anden<br />
steds. Dette gøres ved at de henholdsvis bedste værdier for max og min gemmes<br />
som alpha og beat-værdier. N˚ar en søgning n˚ar enden af en gren, er det muligt<br />
at sammenligne værdien af denne med alpha eller beta-værdien, og afgøre om<br />
der er grund <strong>til</strong> at fortsætte søgningen eller ej. Disse afbrydelser kan forsætte<br />
længere op gennem træet, men minimum et blad skal være besøgt før en gren<br />
kan klippes fra i søgningen.<br />
Alpha anvendes <strong>til</strong> at gemme den hid<strong>til</strong> bedste løsning for Max p˚a vejen <strong>til</strong> det<br />
p˚agældende stadie, mens beta anvendes ligeledes for min. Hvis Max-funktionen<br />
et sted inde i søgningen modtager en værdi fra et af børnene, som er større end<br />
eller lige s˚a stor som beta-værdien for Min en generation over den nuværende<br />
Max, s˚a afbryder Max sin igangværende søgning og returnere den fundne værdi<br />
<strong>til</strong> den igangværende Min-funktion generationen højere oppe. Max afbryder<br />
her fordi, det lige er blevet bekræftet, at denne gren kun er p˚a niveau med<br />
eller d˚arligere end overst˚aende Min-funktions hid<strong>til</strong> bedste løsning, og det at<br />
forstsætte søgningen vil kun vise hvor meget d˚arligere grenen er. Hvilket er irrelevant,<br />
da Min-funktionen under alle omstændigheder aldrig vil vælge denne<br />
gren, n˚ar der allerede er fundet en bedre mulighed.<br />
5.4.1 Pseudo-kode for Minimax med Alpha-Beta pruning:<br />
Funktion : AI−AlphaBeta ( s p i l l e r , s t a d i e ) , r e t u r n e r e et træk<br />
Input : s p i l l e r , s p i l l e r n e som s t˚a r f o r tur .<br />
s t a d i e , s p i l l e t s nuværende s t a d i e .<br />
IF s p i l l e r = hvid THEN Max( s t a d i e , −i n f , i n f )<br />
ELSE Min( s t a d i e , −i n f , i n f )<br />
Funktion : Max(S , a , ß ) , r e t u r n e r e en værdi f o r s t a d i e t<br />
Input : S , det a k t u e l l e s t a d i e i s p i l l e t .<br />
a , den a k t u e l l e Alpha værdi .<br />
ß , den a k t u e l l e Beta værdi .<br />
IF S er et e n d e l i g t s t a d i e<br />
THEN v = e v a l u e r i n g a f S RETURN v<br />
v = −i n f<br />
FOR a l l e efterkommere a f S ( s )<br />
m = Min( s , a , ß )
62 Optimering af Minimax<br />
IF v < m THEN v = m<br />
IF v = ß THEN RETURN v<br />
IF a < v THEN a = v<br />
RETURN v<br />
Funktion : Min(S , a , ß ) , r e t u r n e r e en værdi f o r s t a d i e t<br />
Input : S , det a k t u e l l e s t a d i e i s p i l l e t .<br />
a , den a k t u e l l e Alpha værdi .<br />
ß , den a k t u e l l e Beta værdi .<br />
IF S er et e n d e l i g t s t a d i e<br />
THEN v = e v a l u e r i n g a f S RETURN v<br />
v = i n f<br />
FOR a l l e efterkommere a f S ( s )<br />
m = Max( s , a , ß )<br />
IF v > m THEN v = m<br />
IF v = a THEN RETURN v<br />
IF ß > v THEN ß = v<br />
RETURN v<br />
5.4.2 Gennemgang af et eksempel p˚a Alpha-Beta pruning:<br />
Da det kan være svært umiddelbart at overskue præcist hvordan Alpha-Beta<br />
pruning fungere er her en grundig gennemgang af et eksempel p˚a Alpha-Beta<br />
pruning.
5.4 Alpha-beta pruning 63<br />
Figur 5.7: Eksempel p˚a et spiltræ.<br />
For at starte søgningen køres Max() p˚a noden rod-noden A, med alpha-værdien<br />
-8 og beta-værdien 8. Havde det været den modsatte spiller der startede, skulle<br />
søgningen i stedet startes med Min().<br />
Start Max(A,−∞,∞):<br />
Da søge dybden ikke er n˚aet og A ikke er et endeligt stadie, sættes værdien for<br />
A sættes <strong>til</strong> −∞ og der køres Min() p˚a As børn.<br />
Min(B,−∞,∞):<br />
Da søge dybden ikke er n˚aet og B ikke er et endeligt stadie, sættes værdien for<br />
B sættes <strong>til</strong> ∞ og der køres Max() p˚a Bs børn.<br />
Max(D,−∞,∞):<br />
Da søge dybden ikke er n˚aet og D ikke er et endeligt stadie, sættes værdien for<br />
D sættes <strong>til</strong> −∞ og der køres Min() p˚a Ds børn.<br />
Min(H,−∞,∞):<br />
Da søge dybden er n˚aet, evalueres H og f˚ar i dette <strong>til</strong>fælde værdien 5. Værdien<br />
returneres.<br />
Max(D,−∞,∞):<br />
Modtager værdien 5 fra H.<br />
Værdien for D sættes <strong>til</strong> at være den højeste værdi af de to værdier, den nuværende<br />
værdi for D (−∞) eller værdien for H (5). Værdien for D sættes <strong>til</strong> 5.<br />
Der checkes om værdien for D (5) er større end/lig med Beta (∞). Hvilket ikke
64 Optimering af Minimax<br />
er <strong>til</strong>fældet.<br />
Alpha sættes <strong>til</strong> at være den største værdi af Alpha (−∞) og værdien for D (5).<br />
Alpha = 5.<br />
Max(D) forsætter med det næste barn. Kører Min(I,5,8).<br />
Min(I,5,∞):<br />
Da søgedybden er n˚aet, evalueres I og f˚ar i dette <strong>til</strong>fælde værdien 2. Værdien<br />
returneres.<br />
Max(D,−∞,∞):<br />
Modtager værdien 2 fra I.<br />
Værdien for D sættes <strong>til</strong> at være den højeste af de to værdier, den nuværende<br />
værdi for D (5) eller værdien for H (2). Værdien for D forbliver 5.<br />
Der checkes om værdien for D (5) er større end/lig med Beta (∞). Hvilket ikke<br />
er <strong>til</strong>fældet.<br />
Alpha sættes <strong>til</strong> at være den største værdi af Alpha (5) og værdien for D (5).<br />
Alpha = 5.<br />
Da D ikke har flere børn returneres værdien (5).<br />
Figur 5.8: Spiltræet efter at Max(D,−∞,∞) er blevet kørt.<br />
Min(B,−∞,∞):<br />
Modtager værdien 5 fra D.<br />
Værdien for B sættes <strong>til</strong> at være den mindeste af de to værdier, den nuværende<br />
værdi for B (∞) eller værdien for D (5). Værdien for B sættes <strong>til</strong> 5.
5.4 Alpha-beta pruning 65<br />
Der checkes om værdien for B (5) er mindre end Alpha (−∞). Hvilket ikke er<br />
<strong>til</strong>fældet.<br />
Beta sættes <strong>til</strong> at være den mindste værdi af Beta (∞) og værdien for B (5).<br />
Beta = 5.<br />
Min(B) forsætter med det næste barn. Kører Max(E,−∞,5).<br />
Max(E,−∞,5):<br />
Da søge dybden ikke er n˚aet og E ikke er et endeligt stadie, sættes værdien for<br />
E sættes <strong>til</strong> −∞ og der køres Min() p˚a Ds børn.<br />
Min(J,−∞,5):<br />
Da søge dybden er n˚aet, evalueres J og f˚ar i dette <strong>til</strong>fælde værdien 6. Værdien<br />
returneres.<br />
Max(E,−∞,5):<br />
Modtager værdien 6 fra J.<br />
Værdien for E sættes <strong>til</strong> at være den højeste af de to værdier, den nuværende<br />
værdi for E (−∞) eller værdien for J (6). Værdien for E sættes <strong>til</strong> 6.<br />
Der checkes om værdien for E (6) er større end/lig med Beta (5). Hvilket er<br />
<strong>til</strong>fældet.<br />
Søgningen afbrydes og værdien for E (6) returneres.<br />
Min(B,−∞,∞):<br />
Modtager værdien 6 fra E.<br />
Værdien for B sættes <strong>til</strong> at være den mindeste af de to værdier, den nuværende<br />
værdi for B (5) eller værdien for E (6). Værdien for B forbliver 5.<br />
Der checkes om værdien for B (5) er mindre end/lig med Alpha (−∞). Hvilket<br />
ikke er <strong>til</strong>fældet.<br />
Beta sættes <strong>til</strong> at være den mindste værdi af Beta (5) og værdien for B (5).<br />
Beta forbliver 5.<br />
Da B ikke har flere børn returneres værdien 5.<br />
Max(A,−∞,∞):<br />
Modtager værdien 5 fra B.<br />
Værdien for A sættes <strong>til</strong> at være den højeste af de to værdier, den nuværende<br />
værdi for A (−∞) eller værdien fra B (5). Værdien for A sættes <strong>til</strong> 5.<br />
Der checkes om værdien for A (5) er større end/lig med Beta (∞). Hvilket ikke<br />
er <strong>til</strong>fældet.<br />
Alpha sættes <strong>til</strong> at være den største værdi af Alpha (−∞) og værdien for A (5).<br />
Alpha = 5.<br />
Max(A) forsætter med det næste barn. Kører Min(C,5,∞).
66 Optimering af Minimax<br />
Figur 5.9: Spiltræet, hvor Min(C,5,∞) kaldes.<br />
Min(C,5,−∞):<br />
Da søge dybden ikke er n˚aet og C ikke er et endeligt stadie, sættes værdien for<br />
C sættes <strong>til</strong> 8 og der køres Max() p˚a Cs børn.<br />
Max(F,5,∞): Da F er et endeligt stadie, evalueres F og f˚ar i dette <strong>til</strong>fælde<br />
værdien 3. Værdien returneres.<br />
Min(C,5,∞): Modtager værdien 3 fra F.<br />
Værdien for C sættes <strong>til</strong> at være den mindeste af de to værdier, den nuværende<br />
værdi for C (∞) eller værdien fra F (3). Værdien for C sættes <strong>til</strong> 3.<br />
Der checkes om værdien for C (3) er mindre end/lig med Alpha (5). Hvilket er<br />
<strong>til</strong>fældet.<br />
Søgningen afbrydes og værdien for C (3) returneres.<br />
Max(A,−∞,∞):<br />
Modtager værdien 3 fra C.<br />
Værdien for A sættes <strong>til</strong> at være den højeste af de to værdier, den nuværende<br />
værdi for A (5) eller værdien fra C (3). Værdien for A forbliver 5.<br />
Der checkes om værdien for A (5) er større end/lig med Beta (∞). Hvilket ikke<br />
er <strong>til</strong>fældet.<br />
Alpha sættes <strong>til</strong> at være den største værdi af Alpha (5) og værdien for A (5).<br />
Alpha forbliver 5.<br />
Da A ikke har flere børn er søgning slut.<br />
Resultatet er at B er det bedste træk, da dette træk har den højeste minimums<br />
værdi p˚a 5.
5.4 Alpha-beta pruning 67<br />
Figur 5.10: Det færdige spiltræet. De gr˚a noder er ikke blevet undersøgt. Den<br />
tykke, sorte vej markere de endelige valg for Max og Min.<br />
5.4.3 Alpha-Beta pruning p˚a spilgraf:<br />
I et spiltræ er det relativt nemt at afslutte en undersøgelsen af en bræt<strong>til</strong>stand,<br />
n˚ar visse kriterier er opfyldt og s˚a g˚a videre uden at bekymre sig mere om den.<br />
Det samme er dog ikke <strong>til</strong>fældet for en spilgraf. I en spilgraf er det nemlig muligt<br />
at komme <strong>til</strong>bage <strong>til</strong> denne bræt<strong>til</strong>stand, der tidligere er blevet besøgt, som kan<br />
være blevet søgt helt igennem eller afbrudt undervejs af AlphaBeta pruning’en.<br />
N˚ar en s˚adan bræt<strong>til</strong>stand mødes igen er det nødvendigvis ikke under samme<br />
kriterier som forrige gang. Alpha og beta-værdierne, som afgør om undersøgelsen<br />
af bræt<strong>til</strong>standen skal afsluttes før tid, kan have ændret sig i mellemtiden og den<br />
værdi, som er gemt i bræt<strong>til</strong>standen fra forrige møde, kan være blevet forældet.<br />
Fortages søgningen p˚a ny under de nye kriterier for at undg˚a at værdi ikke<br />
længere er tidsvarende, forsvinder hele ideen med at benytte en spilgraf, nemlig<br />
at den samme bræt<strong>til</strong>stand ikke søges igennem flere gange. Anvendes den gemt<br />
værdi derimod uden at undersøge bræt<strong>til</strong>standen igen, risikeres der at det endelige<br />
resultat bliver forkert.<br />
Løsningen er at finde en m˚ade at vurdere hvorn˚ar en ny undersøgelse er nødvendig<br />
og hvorn˚ar den gemte værdi kan anvendes uden videre.<br />
For finde ud af om en ny undersøgelse af bræt<strong>til</strong>standen er nødvendig, er det
68 Optimering af Minimax<br />
vigtigt at være opmærksom p˚a præcis hvilken information der er gemt i værdien<br />
for bræt<strong>til</strong>standen. Uanset hvilke kriterier undersøgelsen af bræt<strong>til</strong>standen tidligere<br />
er blevet foretaget med, vil værdien være et minimum for hvor godt enten<br />
Min eller Max vil klare sig for denne bræt<strong>til</strong>stand. Om det er Min eller Max<br />
afhænger af bræt<strong>til</strong>standens generation. Er generationen over bræt<strong>til</strong>standen en<br />
Min-generation er bræt<strong>til</strong>standen selv af en Max-generation og omvendt.<br />
Værdien gemt i bræt<strong>til</strong>standen kommer alts˚a ikke <strong>til</strong> at blive bedre end den allerede<br />
er set fra Max eller Min’s syn generationen over bræt<strong>til</strong>standen. S˚a hvis Min<br />
generationen over arbejder med en beta-værdi, der er lige s˚a stor eller større end<br />
den gemte værdi, behøver den ikke lave en nye undersøgelse af bræt<strong>til</strong>standen,<br />
da der allerede findes en lige s˚a god eller bedre løsning. Er det ikke <strong>til</strong>fældet,<br />
bliver den nødt <strong>til</strong> at starte en ny undersøgelse af bræt<strong>til</strong>standen med de nye<br />
alpha og beta værdier, da det ikke kan garanteres at værdien for bræt<strong>til</strong>standen<br />
ikke reelt er højere end hvad den forrige undersøgelse var kommet frem <strong>til</strong>, da<br />
den blev afsluttet.<br />
Er det Max, der er i gang generationen før bræt<strong>til</strong>standen, skal der i stedet<br />
checkes om alpha-værdien er mindre end eller lige s˚a stor som den gemte værdi.<br />
Er den mindre end eller lige s˚a stor er der ingen grund <strong>til</strong> at undersøge bræt<strong>til</strong>standen<br />
igen.<br />
Normalt checker Min- eller Max-funktionen om et træk resultere i en bræt<strong>til</strong>stand<br />
der allerede eksisterer, hvis den gør det <strong>til</strong>føjer den bræt<strong>til</strong>stand som et<br />
barn og <strong>til</strong>føjer sig selv som forældre p˚a bræt<strong>til</strong>standen, og s˚a gøres der ellers<br />
ikke mere ved den. Men med alpha beta-pruning inde i billedet, stopper den<br />
ikke længere. Ligesom hvis den ikke havde konstateret at der allerede fandtes<br />
en s˚adan bræt<strong>til</strong>stand, kører den enten Max eller Min p˚a <strong>til</strong>standen, dog med<br />
den lille forskel, at udover at sende alpha og beta værdierne med, sender den en<br />
værdi der indikere om bræt<strong>til</strong>stand fandtes i forvejen eller ej.<br />
Det første Min eller Max gør, i <strong>til</strong>fælde af at bræt<strong>til</strong>standen allerede eksisterede,<br />
er at sammenligne henholdsvis alpha og beta med bræt<strong>til</strong>standens gemte værdi.<br />
Er værdien for Min’s vedkommende mindre end eller lig med alpha eller for<br />
Max’s vedkommende større end lig med beta, stoppes processen der og værdien<br />
gemt i bræt<strong>til</strong>standen returneres. Er det ikke <strong>til</strong>fældet fortsætter Min og Max<br />
p˚a sædvanligvis.<br />
5.4.4 Fordele og ulemper:<br />
Sammenlignet med en almindelige Minimax algoritme har Alpha-Beta versionen<br />
ingen ulemper, da den altid vil kom frem <strong>til</strong> samme løsning, bare hurtigere. Den<br />
eneste forskel der kan komme <strong>til</strong> syne er, at der kan være mindre variation i<br />
Alpha-Beta versionens træk. Dette skyldes at den kunstige intelligens er sat
5.4 Alpha-beta pruning 69<br />
<strong>til</strong> at vælge et <strong>til</strong>fældigt træk, n˚ar der er mere end et træk med den bedste<br />
værdi. Her er det muligt at Alpha-Beta pruningen har frasorteret grene, som<br />
hvis de havde været søgt <strong>til</strong> bunds, havde vist sig at være lige s˚a gode som<br />
den fundne løsning men aldrig bedre. I det <strong>til</strong>fælde ville mængden af lige gode<br />
træk, som den kunstige intelligens havde at vælge imellem, været mindre end<br />
med en almindelige Minimax AI. Var dette dog en prioritet, kunne Alpha-Beta<br />
versionen hurtigt modificeres <strong>til</strong> ogs˚a at finde alle de bedste løsninger og stadig<br />
være hurtigere end den almindelige Minimax AI. Dette kunne opn˚as blot ved at<br />
ændre parametrene <strong>til</strong> ikke at stoppe en søgning ved en kun lige s˚a god løsning,<br />
men først at stoppe n˚ar den viser sig decideret at være d˚arligere end den hid<strong>til</strong><br />
bedst fundne. Det er dog svært at finde et scenarie, hvor det vil være s˚a vigtigt<br />
at være sikker p˚a at alle lige gode løsninger kommer med, at det er den ekstra<br />
regnetid værd.<br />
Desuden er der problemerne som er beskrevet i afsnit omkring heuristik.<br />
5.4.5 Mulige forbedringer:<br />
Jo tidligere en god løsning findes, jo flere d˚arlige løsning kan s˚a udelukkes inden<br />
der søges <strong>til</strong> bunds. Derfor kan kørslestiden af en Minimax AI som anvender<br />
Alpha-Beta pruning forbedres ved at der sørges for, at de grene som forventes<br />
at have en god løsning søges igennem først, s˚aledes at der formentligt vil være et<br />
godt udgangspunkt for at stoppe de d˚arligere løsninger p˚a et tidligere tidspunkt.
70 Optimering af Minimax
Kapitel 6<br />
Begrænsning af antallet af<br />
undersøgte træk<br />
6.1 Local Area<br />
Ideen med Local Area AI’en et at fokusere søgningen omkring et lille omr˚ade,<br />
der s˚a <strong>til</strong> gengæld søges helt <strong>til</strong> bunds. Omr˚adet lægges omkring modstanderens<br />
seneste træk, med mindre det er Local Area AI’en der starter. I s˚a fald ligger<br />
den bare en brik p˚a midten af brættet. Denne AI vil formentligt spille mere<br />
defensivt end offensivt, da den fokusere p˚a modstanderens træk som udgangspunkt.<br />
I praksis er det blot Minimax algoritmen med Alpha-Beta pruning, der<br />
sættes <strong>til</strong> at spille p˚a en lille plade midt i den store plade. Heuristikken vurdere<br />
dog spillet p˚a hele pladen og ikke kun det lokale omr˚ade. Dette betyder at<br />
figurer, der ligger op ad det lokale omr˚ade, f˚ar den indflydelse de skal have p˚a<br />
scoren som AI’en vælger sit træk ud fra. Local Area AI’en kører med et lokalt<br />
omr˚ade p˚a 4x4, da dette er den største plade, hvor p˚a Minimax algoritmen med<br />
Alpha-Beta pruning kan finde den fuldstændige løsning.<br />
Hvis modstanderen lægger sin brik tæt p˚a kanten af brættet flytter AI’en det<br />
lokale omr˚ade længere ind mod midten for fortsat at udnytte hele regnearealet.
72 Begrænsning af antallet af undersøgte træk<br />
Figur 6.1: Eksempel p˚a søge areal rundt om seneste brik.<br />
6.1.1 Fordele og ulemper:<br />
Fordelen ved denne AI er at den vil fungere ved en hver brætstørrelse, s˚a længe<br />
brættet bare er mindst fire gange fire.<br />
6.1.2 Mulige forbedringer:<br />
Det er muligt at denne AI kan forbedres ved at søgearealet udvides p˚a bekostning<br />
af søgedybden.<br />
6.2 Growth<br />
Growth AI’en bygger p˚a, at det kun er de to største figurer for hver spiller, der<br />
er relevante for spillet og at disse kun er relevante s˚a længe der er mulighed for<br />
at udvide dem. Dermed er alt andet end de to største figurer, der stadig har
6.2 Growth 73<br />
mulighed for udvidelse, irrelevant og ikke værd at bruge tid p˚a at undersøge.<br />
Forskellen p˚a denne kunstige intelligens og den sædvanlige Minimax algoritme<br />
er, at hvor den almindelige AI lader en mulig efterkommer opst˚a, lader Growth<br />
AI’en kun efterkommer opst˚a som ligger op ad de to største figurer med mulighed<br />
for udvidelse. Disse efterkommer vil gøre en af to ting, enten vil de udvide<br />
AI’ens egen figurer eller ogs˚a vil de fratage modstanderen nogle af mulighederne<br />
for udvidelse p˚a sine største figurer. Denne AI kaldes netop Growth, fordi efterkommerne<br />
s˚a at sige vokser ud fra de største figurer, hvor der er mulighed for det.<br />
Figur 6.2: Eksempel p˚a hvor Growth forsøger at lægge brikker. Hver rød streg<br />
repræsenterer en brik og den samme brik vendt 180 grader.
74 Begrænsning af antallet af undersøgte træk<br />
Figur 6.3: Hvor Growth forsøger sig med at lægge brikker efter den nye brik er<br />
blevet lagt som forsøg.<br />
6.2.1 Fordele:<br />
Der vil blive set mere p˚a det i testafsnittet, men i praksis ser Growth ud <strong>til</strong><br />
at spille lige op med den almindelige Alpha-Beta Minimax algoritmen b˚ade p˚a<br />
resultat og afviklingstid, n˚ar de spiller med samme søgedybde. Dette betyder at<br />
hvis det lykkes ogs˚a at implementere Alpha-Beta pruning p˚a Growth AI’en, vil<br />
denne formentligt f˚a muligheden for at regne en generation dybder end Minimax<br />
algortimen med Alpha-Beta pruning. Om ikke anden s˚a i hvert fald øge<br />
søgedybden tidligere i spillet.<br />
6.2.2 Ulemper:<br />
Der vil opst˚a <strong>til</strong>fælde, hvor det bedre kan betale sig at lægge en brik lidt væk fra<br />
de største figurer og lade modstanderen forbinde figurerne. Dette vil dog aldrig<br />
ske med denne AI, da der kun ses p˚a mulighederne lige opad de størstefigurer.<br />
Med den nuværende heuristik lider denne kunstige intelligens ogs˚a under at<br />
famle i blinde, n˚ar de største figurer ikke længere har muligheden for udvidelser,
6.2 Growth 75<br />
og de næststørste figurer har lang vej igen for n˚a op p˚a de største. Det ser dog<br />
ikke ud som om den famler helt s˚a meget i blinde, da den altid placerer brikkerne<br />
op ad de næststørste figurer med mulighed for udvidelse. Men om de brikker<br />
den lægger op ad disse figurer hjælper sig selv eller modstanderen, er den stadig<br />
komplet blind over for.<br />
Et trejde problem<br />
6.2.3 Mulige forbedringer:<br />
Som det første er der at f˚a implementeringen af Alpha-Beta pruning <strong>til</strong> at fungere.<br />
P˚a nuværende tidspunkt er aplha-beta pruningen sl˚aet fra, da den ikke<br />
fungerer korrekt. Derudover er der muligheden for at forbedre heuristikken, s˚a<br />
den ikke længere famler i blinde n˚ar søgedybden ikke dækker over problemet<br />
med store afsluttede figurer. Som alternativ <strong>til</strong> forbedring af heuristikken, kunne<br />
skabelsen af efterkommer ændres s˚aledes, at den kun lægger brikker, s˚a de<br />
udvider egne figurer eller tager muligheder fra modstanderens, hvor den nu afprøver<br />
f.eks. at lægge den sorte ende af en brik op mod sin egen hvide figur<br />
eller lægge en sort ende op mod modstanderens sorte figur. Dette vil dog reducere<br />
mængden af træk, som bliver undersøgt med en faktor to p˚a godt og ondt.<br />
Afviklingstiden vil falde, og dette vil give mulighed for dybere søgninger, men<br />
sandsynligheden for at en bedre løsning ikke bliver undersøgt vil ogs˚a stige.
76 Begrænsning af antallet af undersøgte træk
Kapitel 7<br />
Test og sammenligning af de<br />
implementerede AI’er<br />
I dette afsnit vil de forskellige kunstige intelligenser blive test og sammenlignet.<br />
Udover de komplementerende AI’er vil <strong>Taiji</strong> designeren Néstor Romeral Andrés’<br />
egen AI ogs˚a indg˚a i testen, s˚a det er muligt at sammenligne resultaterne. De<br />
forskellige AI’er vil blive afprøvet mod en menneskelige modstander, mod hinanden<br />
s˚a vidt muligt og der vil blive taget tid p˚a hvor hurtigt beregningerne<br />
bliver udført.<br />
7.1 Test af Néstor’s AI<br />
Néstor’s egen AI spiller kun med standard brætstørrelsen p˚a ni gange ni felter<br />
og vil derfor kun blive testet for denne størrelse. Néstor’s AI har fire sværdheds<br />
grader, hvor 1 er den letteste og 4 er den sværeste, 4 kræver ogs˚a længst tid<br />
<strong>til</strong> at beregne sit træk. De fire sværhedsgrader g˚ar ogs˚a under navne Basic (1),<br />
Intermediate (2), Expert (3) og Master (4).
78 Test og sammenligning af de implementerede AI’er<br />
7.1.1 Kørselstider for Néstor’s AI:<br />
Her under ses gennemsnits kørsels tiderne for Néstor’s AI taget over de første<br />
10 træk:<br />
Basic Intermediate Expert Master<br />
9x9 ca. 1 sek ca. 3 sek ca 15 sek ca. 50 sek<br />
De to mest krævende sværhedsgrader Expert og Master bliver dog mærkbart<br />
hurtigere n˚ar spillet nærmere sig enden, f.eks bruger Master omkring 25 sekunder<br />
n˚ar der er cirka 15 træk <strong>til</strong>bage og ca. 10 sekunder n˚ar der er cirka 8 træk<br />
<strong>til</strong>bage.<br />
Beregningstiderne for de to letteste sværhedsgrader er helt i orden. Intermediate<br />
er lige i overkanten, da en menneskelig modstander vil n˚a at blive en smule<br />
ut˚almodig inden computeren foretager sit træk. Master er derimod helt uacceptabel<br />
med beregningstider der tager op i mod et minut. Et spil <strong>Taiji</strong> forventes<br />
at vare omkring 20 minutter mellem to menneskelige spiller 1 , hvor der bruges<br />
længere tid p˚a at fysisk lægge brikkerne og der formentligt snakkes lidt, og der<br />
bliver tænkt lidt længere over trækkene end mod en computer, hvor ens ære<br />
ikke st˚ar p˚a spil p˚a samme m˚ade. Et spil <strong>Taiji</strong> kan indeholde op <strong>til</strong> 40 træk<br />
og minimum 27, AI’en kommer <strong>til</strong> at st˚a for halvdelen af disse. Dette betyder<br />
at AI’en alene kommer <strong>til</strong> at st˚a for rundt regnet et kvartes betænkningstid i<br />
løbet af et enkelt spil. Til sammenligning kan et spil mod Intermediate sagtens<br />
afsluttes p˚a 3 minutter <strong>til</strong> den menneskelige spillers fordel.<br />
7.1.2 Test af Néstor’s AI mod menneskelig modstander:<br />
Her bliver Néstor’s AI s<strong>til</strong>let overfor en erfaren menneskelig modstander, hvilket<br />
jeg efterh˚anden godt kan <strong>til</strong>lade mig at kalde mig selv. Basic er ikke taget med<br />
i testen, da dennes eneste fordel er dens lave beregningstid, hvor Intermediate<br />
er storset lige s˚a hurtig, men er betydeligt smartere.<br />
Intermediate (sort) mod erfaren menneskelig spiller (hvid):<br />
1 Tal fra boardgamegeek.com
7.1 Test af Néstor’s AI 79<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
18 17 Tabt<br />
19 16 Tabt<br />
14 9 Tabt<br />
30 12 Tabt<br />
19 14 Tabt<br />
I alt 100 68 0%<br />
Intermediate (hvid) mod erfaren menneskelig spiller (sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
15 29 Tabt<br />
9 22 Tabt<br />
12 20 Tabt<br />
10 15 Tabt<br />
10 24 Tabt<br />
I alt 56 110 0%<br />
Intermediate vinder alts˚a ingen af sine 10 spil, hverken som sort eller hvid spiller.<br />
Gennemsnitligt taber den med 8,6 point og det nærmeste den kommer uafgjort<br />
er en forskel p˚a 3 point.<br />
Expert (sort) mod erfaren menneskelig spiller (hvid):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
22 11 Tabt<br />
25 11 Tabt<br />
19 16 Tabt<br />
26 9 Tabt<br />
19 12 Tabt<br />
I alt 111 59 0%<br />
Expert (hvid) mod erfaren menneskelig spiller (sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
14 19 Tabt<br />
13 24 Tabt<br />
12 24 Tabt<br />
14 29 Tabt<br />
16 32 Tabt<br />
I alt 69 128 0%<br />
Expert vinder heller ikke nogen af sine 10 spil. Gennemsnitligt taber den med<br />
11,1 point, men <strong>til</strong> gengæld kommer den tæt p˚a at afslutte et enkelt spil med
80 Test og sammenligning af de implementerede AI’er<br />
uafgjort med kun et points forskel.<br />
Master (sort) mod erfaren menneskelig spiller (hvid):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
22 14 Tabt<br />
12 11 Tabt<br />
17 14 Tabt<br />
19 8 Tabt<br />
24 12 Tabt<br />
I alt 94 59 0%<br />
Master (hvid) mod erfaren menneskelig spiller (sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
9 17 Tabt<br />
11 19 Tabt<br />
15 29 Tabt<br />
11 18 Tabt<br />
12 17 Tabt<br />
I alt 58 100 0%<br />
Master taber ogs˚a alle sine 10 spil p˚a trods af sine lange beregningstider. Den<br />
taber dog gennemsnitligt med point 7,7 points, hvilket har været det laveste<br />
ind<strong>til</strong> videre. Samtidigt kommer den i et enkelt <strong>til</strong>fælde lige s˚a tæt p˚a uafgjort<br />
som Expert med et enkelt points forskel.<br />
7.1.3 Sammenfatning af resultatet for Néstor’s AI:<br />
Néstor’s AI beregner hurtigt et træk ved de to laveste sværhedsgrader, men<br />
sætter nærmeste brikkerne <strong>til</strong>fældigt ved den laveste sværhedsgrad og yder ikke<br />
den store modstand p˚a Intermediate.<br />
Expert sværhedsgraden bruger typisk en 15 sekunder p˚a at beregne sit træk,<br />
hvilket er fem gange s˚a meget som Intermediate, p˚a trods af dette klarede den<br />
sig gennemsnitligt ikke meget bedre en denne, dog kom den i et enkelt <strong>til</strong>fælde<br />
tættere p˚a et uafgjort resultat.<br />
Master kan bruge næsten et helt minut p˚a at beregne sit træk, p˚a trods af dette<br />
opn˚aede den kun nederlag overfor den erfarende menneskelige spiller. Den klarere<br />
sig dog bedre end de alle de lavere sværhedsgrader, s˚a længe der ses bort<br />
fra beregningstiden.<br />
Det kunne forventes at Masters lange beregningstider ogs˚a har givet den menneskelige<br />
spiller længere tid <strong>til</strong> at overveje sit næste træk, og at dette har været
7.2 Test af AlphaBeta AI (udviklet af Morten Rask) 81<br />
med <strong>til</strong> at danne resultatet med en kun let fremgang fra forrige niveau. I praksis<br />
har de lange beregningstid dog betydet at jeg som testperson er g˚aet helt væk<br />
fra spillet og lavet noget andet indimellem i de lange ventetider.<br />
7.2 Test af AlphaBeta AI (udviklet af Morten<br />
Rask)<br />
AlphaBeta bruger en minimax søgning med alpha beta pruning. Den eneste forskel<br />
mellem den almindelige minimax AI og AlphaBeta versionen er beregningstiden.<br />
Var det ikke for det <strong>til</strong>fældige valg mellem lige gode træk ville AlphaBeta<br />
og minimax AI’en altid vælge samme træk.<br />
7.2.1 Kørselstider for AlphaBeta AI’en:<br />
For en fuld søgningen gennem spilgrafen for en fire gange fire plade, har de<br />
længste beregningstider altid været for det første træk, hvor der selvfølgelig er<br />
mest at regne igennem. Disse søgninger har taget lidt under 6 sekunder. Starter<br />
den anden spiller skal AlphaBeta AI’en beregne et træk mindre, beregningstiden<br />
her svinger mellem 1,7 og 3,3 sekunder afhængigt af hvilket træk modstanderen<br />
foretager. Alle beregningstider herefter er ubetydeligt sm˚a.<br />
P˚a en ni gange ni plade, hvor dybden bliver begrænset, har de længste beregningstider<br />
gennem fem spil været p˚a lige under fire sekunder langt de fleste tider<br />
har dog ligget under to sekunder.<br />
7.2.2 Test af AlphaBeta AI med fuld søgning<br />
AlphaBeta AI’en kan højst kører p˚a en fire gange fire plade, hvis søgningen skal<br />
g˚a helt <strong>til</strong> bunds i spilgrafen. Forventningerne er at det ikke vil være muligt<br />
at opn˚a et bedre resultat end uafgjort mod AlphaBeta AI’en p˚a den størrelse<br />
plade. Lykkedes det at besejre denne AI vil det enten betyde at der er en vinderstrategi<br />
for brætstørrelsen fire gange fire, eller at der er en fejl i AI’en.<br />
AI’en beregninger siger at der ikke er nogen vinderstrategier, da AI’en selv efter<br />
en fuld søgning giver alle de mulige start træk enten værdien 0, ufgjort, eller<br />
-1, tabt. Ergo vil AI’en altid kunne f˚a uafgjort uanset hvordan modstanderen<br />
spiller. -1-værdierne p˚a først træk betyder ogs˚a, at der er start træk, som altid<br />
vil lede <strong>til</strong> et nederlag, mod en modstander der ikke beg˚ar fejl.
82 Test og sammenligning af de implementerede AI’er<br />
Da AI’en ikke mener, der er nogle vinderstrategier, vil et nederlag for AI’en<br />
betyde at den ikke fungere korrekt, dette vil dog hverken bekræft eller udelukke<br />
om der er en vinderstrategi eller ej.<br />
AlphaBeta (hvid) mod erfaren menneskelig spiller (sort):<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for AI<br />
6 6 Uafgjort<br />
3 3 Uafgjort<br />
6 6 Uafgjort<br />
5 5 Uafgjort<br />
7 7 Uafgjort<br />
7 7 Uafgjort<br />
5 5 Uafgjort<br />
7 6 Vundet<br />
6 6 Uafgjort<br />
7 7 Uafgjort<br />
I alt 59 58 55%<br />
Gennem ti spil med AlphaBeta spillende som hvid, har den som forventet aldrig<br />
tabt og derud over vundet et enkelt spil.<br />
AlphaBeta (sort) mod erfaren menneskelig spiller (hvid):<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for AI<br />
4 4 Uafgjort<br />
2 2 Uafgjort<br />
6 6 Uafgjort<br />
2 2 Uafgjort<br />
5 5 Uafgjort<br />
7 7 Uafgjort<br />
7 7 Uafgjort<br />
7 7 Uafgjort<br />
6 6 Uafgjort<br />
6 6 Uafgjort<br />
I alt 52 52 50%<br />
Heller ikke n˚ar den menneskelige spiller starter f˚ar AlphaBeta AI’en et d˚arligere<br />
resultat end uafgjort.<br />
AI’ens værdier p˚a mulighederne for første træk viste at nogle disse ville føre<br />
<strong>til</strong> nederlag mod en modstander som ikke laver fejl. Det er disse to træk og alle<br />
spejlinger og rotationerne af disse:
7.2 Test af AlphaBeta AI (udviklet af Morten Rask) 83<br />
Figur 7.1: De to træk der leder <strong>til</strong> nederlag (for hvid spiller, n˚ar hvid starter).<br />
Herunder forsøger den menneskelige spiller at vinde eller f˚a uafgjort efter at<br />
være startet med et af disse to træk.<br />
AlphaBeta (sort) mod erfaren menneskelig spiller, som starter med nederlags<br />
træk (hvid):<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for AI<br />
4 5 Vundet<br />
3 5 Vundet<br />
3 5 Vundet<br />
5 7 Vundet<br />
7 8 Vundet<br />
3 4 Vundet<br />
4 5 Vundet<br />
3 5 Vundet<br />
4 6 Vundet<br />
3 4 Vundet<br />
I alt 39 54 100%<br />
Det kan ses at AI’en vinder alle spillene, n˚a den menneskelige spiller starter<br />
med et af de to træk, som AI’en har vurderet ender i nederlag. Dette p˚aviser at<br />
der er starttræk der leder direkte <strong>til</strong> nederlag mod en øvet modstander.<br />
Disse test viser ogs˚a at de konklusioner, der blev draget ud fra værdierne for<br />
de forskellige starttræk, som AlphaBeta AI’en beregnede, har vist sig at holde<br />
stik gennem alle forsøgene. Der kan udfra dette konkluderes at AlphaBeta AI’en<br />
fungere korrekt, det vil dog kræve en komplet spilgraf for en fire gange fire plade,<br />
lavet i h˚anden at bevise dette, hvilket er en meget stor og uoverskuelige opgave,<br />
da der er godt og vel 30000 bræt<strong>til</strong>stande for et spil p˚a fire gange fire og det er<br />
uden rotationer og spejlinger, hvor antallet for brætstørrelsen tre gange tre var<br />
p˚a lidt over 100.
84 Test og sammenligning af de implementerede AI’er<br />
7.2.3 Test af AlphaBeta AI mod menneskelig modstander:<br />
Her bliver AlphaBeta AI’en sat op imod en erfaren menneskelig modstander.<br />
AlphaBeta (sort) mod erfaren menneskelig spiller (hvid):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
17 18 Vundet<br />
10 11 Vundet<br />
20 12 Tabt<br />
24 14 Tabt<br />
17 18 Vundet<br />
I alt 88 73 60%<br />
AlphaBeta (hvid) mod erfaren menneskelig spiller (sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
15 18 Tabt<br />
16 15 Vundet<br />
20 22 Tabt<br />
16 20 Tabt<br />
14 14 Uafgjort<br />
I alt 81 89 30%<br />
Samlet set har AlphaBeta vundet 4 spil, tabt 5 og et endte i uafgjort. Dette<br />
giver en vindings procent p˚a 45% . N˚ar det kommer <strong>til</strong> ren score har den gennemsnitligt<br />
tabt med 2,3 point. Dens sejre har alle været snævre, mens nogle af<br />
dens nederlag har være af større karakter.<br />
Den menneskelige spiller har aldrig brugt mere end 5 sekunder p˚a sine træk.<br />
Dette har været <strong>til</strong>strækkeligt <strong>til</strong> udelukkende at sejr over Néstor’s AI, dette<br />
har dog ikke været <strong>til</strong>fældet her, hvor kun 55% har været sejre. Menneskelige<br />
spiller er svære at h˚andtere, n˚ar det kommer <strong>til</strong> holde præstationen konstant.<br />
Motivation, mental <strong>til</strong>stand, humør og t˚almodighed spiller alle ind p˚a kvaliteten<br />
af den menneskeliges spillers præstation, for ikke at nævne den konstant stigende<br />
erfaring med spillet. Det er derfor en god ide at ops<strong>til</strong>le nogle rammer for<br />
den menneskelige modstand. F.eks. har den menneskelig modstander hid<strong>til</strong> ikke<br />
brugt mere end fem sekunder p˚a at tænke over sit træk. Dette kan bruges som<br />
en regel <strong>til</strong> at holde den menneskelige modstander niveau lidt nede. Alternativ<br />
kun en regel, som at der minimum skal g˚a 15 sekunder før den menneskelige<br />
spiller foretager et træk, hjælper <strong>til</strong> at holde niveauet oppe.<br />
Det høje niveau har ikke været nødvendigt mod Néstor’s AI, men det kunne<br />
være interessant at prøve det op imod AlphaBeta AI’en for at se om dette giver
7.3 Test af LocalArea AI (designet og udviklet af Morten Rask) 85<br />
indflydelse p˚a resultatet.<br />
AlphaBeta (sort) mod erfaren menneskelig spiller min 15 sek (hvid):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
25 13 Tabt<br />
10 12 Vundet<br />
15 12 Tabt<br />
17 12 Tabt<br />
18 11 Tabt<br />
I alt 85 60 20%<br />
AlphaBeta (hvid) mod erfaren menneskelig spiller min 15 sek (sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
11 14 Tabt<br />
14 26 Tabt<br />
11 21 Tabt<br />
9 9 Uafgjort<br />
13 14 Tabt<br />
I alt 58 84 10%<br />
Det ekstra betænkningstid, som er blevet p˚atvunget den menneskelige spiller,<br />
har givet resultat. AlphaBeta AI’ens sejrs procent er g˚aet ned fra 45% <strong>til</strong> kun<br />
15% . Dette er uden tvivl et resultat af færre fejl p˚a grund bedre overvejede<br />
beslutninger fra den menneskelige side.<br />
7.3 Test af LocalArea AI (designet og udviklet<br />
af Morten Rask)<br />
LocalArea AI’en benytter en minimax søgning med alpha beta pruning <strong>til</strong> at<br />
søge et omr˚ade p˚a fire gange fire helt <strong>til</strong> bunds, uanset brættets størrelse. Dette<br />
omr˚ade placeres omkring modstanderens sidst lagte brik, er der ingen frie pladser<br />
inden for dette omr˚ade flyttets det <strong>til</strong> et sted hvor der er.
86 Test og sammenligning af de implementerede AI’er<br />
7.3.1 Test af LocalArea AI p˚a en 4x4 plade:<br />
Denne test er i sig selv ikke s˚a interessant, da resultatet skulle være præcist<br />
det samme som for AlphaBeta AI’en, da disse fungere ens p˚a en fire gange fire<br />
plade. Det er dog vigtigt at konstatere at LocalArea AI’en fungere korrekt inden<br />
den slippes løs p˚a de større brætter, hvor det vil være svært at gennemskue<br />
forskellen mellem deciderede fejl og generelle problemer med netop den metode.<br />
Her gør rammerne det tydeligt hvorvidt AI’en fungere, da en lokal fuld dybde<br />
søgning p˚a fire gange fire anvendt p˚a et fire gange fire bræt, ikke m˚a kunne tabe.<br />
LocalArea (sort) mod AlphaBeta (hvid):<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for LocalArea<br />
6 6 Uafgjort<br />
2 2 Uafgjort<br />
6 6 Uafgjort<br />
5 5 Uafgjort<br />
6 6 Uafgjort<br />
5 5 Uafgjort<br />
6 6 Uafgjort<br />
8 8 Uafgjort<br />
4 4 Uafgjort<br />
5 5 Uafgjort<br />
I alt 53 53 50%<br />
LocalArea (hvid) mod AlphaBeta (sort):<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for LocalArea<br />
4 4 Uafgjort<br />
6 6 Uafgjort<br />
5 5 Uafgjort<br />
5 5 Uafgjort<br />
2 2 Uafgjort<br />
4 4 Uafgjort<br />
5 5 Uafgjort<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
6 6 Uafgjort<br />
I alt 45 45 50%<br />
Alle spil endte i uafgjort mellem AlphaBeta og LocalArea, hvilket tyder p˚a<br />
at LocalArea udfører sin søgning p˚a sit fire gange fire areal korrekt.
7.4 Test af Growth AI (designet og udviklet af Morten Rask) 87<br />
7.3.2 Test af LocalArea AI p˚a en 9x9 plade:<br />
P˚a en plade større end fire gange fire <strong>til</strong>deler LocalArea trækmulighederne forkert<br />
værdier, i form af enten ∞ eller −∞ . De mulige træk placeres dog korrekt<br />
indenfor det p˚agældende fire gange fire omr˚ade.<br />
Det interessante ved fejlen for LocalArea AI’en er, udover at den virker fint<br />
for et 4x4 bræt, at der er b˚ade negative og positive ”uendelige”værdier, ofte vil<br />
der kun være et fortegn, hvis der f.eks. er blevet lavet en fortegnes fejl s˚a en<br />
værdi, der skulle være meget lille, er s˚a stor at den overtrumfer alt.<br />
Jeg er overbevidst om at forklaring skal findes i, at undersøgelsen af hvorvidt<br />
en bræt<strong>til</strong>stand har n˚aet bunden eller ej ikke længere fungerer korrekt, da der<br />
stadig kan findes lovlige træk uden for arealet som LocalAera koncentrer sig<br />
om. Derfor ender alle værdier med at blive p˚a det minimum eller maksimum de<br />
fik <strong>til</strong>delt fra start af. De endelige bræt<strong>til</strong>stande bliver ikke vurderet <strong>til</strong> at være<br />
endelige bræt<strong>til</strong>stande, men de f˚ar heller ikke nogle børn, da alle pladser inden<br />
for arealet er optaget. Grund <strong>til</strong> der b˚ade opst˚ar positive og negative værdi er<br />
fordi det vil være forskelligt om de endelige bræt<strong>til</strong>stande er af lige eller ulige<br />
generation, derfor bliver nogle h˚andteret af Min-funktionen og f˚ar værdien ∞,<br />
mens andre af Max-funktionen og f˚ar −∞.<br />
En løsning ville være at lave en nye funktion <strong>til</strong> at vurdere, hvorvidt en bræt<strong>til</strong>stand<br />
er endelige ud fra det lokal areal i stedet for hele brættet.<br />
7.4 Test af Growth AI (designet og udviklet af<br />
Morten Rask)<br />
7.4.1 Test af Growth AI’en p˚a en 4x4 plade:<br />
Det er interessant at se hvordan Growth klare sig mod AlphaBeta, da Growth<br />
netop ser bort fra træk der anses som uinteressante, mens AlphaBeta forsøger<br />
sig med alle træk. Denne test vil visse om de træk Growth ser bort fra virkeligt<br />
er uinteressante eller om det lykkedes AlphaBeta at vinde netop p˚a grund af<br />
disse træk.<br />
Growth (sort) mod AlphaBeta (hvid):
88 Test og sammenligning af de implementerede AI’er<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for Growth<br />
4 4 Uafgjort<br />
6 6 Uafgjort<br />
5 5 Uafgjort<br />
4 4 Uafgjort<br />
7 7 Uafgjort<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
5 5 Uafgjort<br />
5 5 Uafgjort<br />
I alt 48 48 50%<br />
Growth (hvid) mod AlphaBeta (sort):<br />
4x4 Hvid score Sort score s<strong>til</strong>ling for Growth<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
6 6 Uafgjort<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
6 6 Uafgjort<br />
5 5 Uafgjort<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
4 4 Uafgjort<br />
I alt 45 45 50%<br />
Testen viser at Growth p˚a en fire gange fire plade ikke er AlphaBeta underlegen<br />
p˚a trods af at den undersøger færre træk.<br />
P˚a en lille plade som fire gange fire er det dog rimeligt begrænset hvor mange<br />
træk Growth ser bort fra. Jo større pladen bliver jo større bliver forskellen<br />
mellem antallet af undersøgte træk for Growth og AlphaBeta. Om resultatet vil<br />
være et andet for større plader er svært at sige, da det ikke er muligt at lave en<br />
fuld søgning p˚a plader større end fire gange fire.<br />
7.4.2 Test af Growth AI’en p˚a en 9x9 plade:<br />
Growth (sort) mod erfaren menneskelig spiller (hvid):
7.4 Test af Growth AI (designet og udviklet af Morten Rask) 89<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
11 12 Vundet<br />
15 12 Tabt<br />
18 17 Tabt<br />
14 12 Tabt<br />
11 11 Uafgjort<br />
I alt 69 64 30%<br />
Growth (hvid) mod erfaren menneskelig spiller (sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
17 19 Tabt<br />
14 18 Tabt<br />
13 13 Uafgjort<br />
19 12 Vundet<br />
15 10 Vundet<br />
I alt 64 82 50%<br />
Resultatet for Growth mod den erfaren menneskelige modstander, som maximum<br />
bruger 5 sekunder p˚a hvert træk, er lige s˚a godt som resultatet for Alpha-<br />
Beta ved samme test med 45% vundende spil. Lige som for AlphaBeta forsøges<br />
der ogs˚a mod den menneskelige spiller, hvor der bruges minimum 15 sekunder<br />
per træk.<br />
Growth (sort) mod erfaren menneskelig spiller min 15 sek(hvid):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
21 16 Tabt<br />
20 14 Tabt<br />
13 12 Tabt<br />
10 13 Vundet<br />
12 15 vundet<br />
I alt 76 70 40%<br />
Growth (hvid) mod erfaren menneskelig spiller min 15 sek(sort):<br />
9x9 Hvid score Sort score s<strong>til</strong>ling for AI<br />
10 10 Uafgjort<br />
11 12 Tabt<br />
14 15 Tabt<br />
12 11 Vundet<br />
11 14 Tabt<br />
I alt 58 62 30%
90 Test og sammenligning af de implementerede AI’er<br />
7.5 Sammenligning af AI’erne<br />
Der er foretaget færre spil med Néstor’s AI, da disse spil er langt mere tidskrævende<br />
end de andre, b˚ade fordi Néstor’s bedste af AI har lange beregningstider<br />
og fordi Néstor’s AI ikke kan spille direkte mod de andre AI’er eller mod sig<br />
selv. Det her derfor været nødvendigt manuelt at kopier træk frem og <strong>til</strong>bage<br />
mellem AI’erne i hvert deres vindue. Skal en hvid Néstor AI f.eks spille mod en<br />
sort AlphaBeta, bliver det <strong>til</strong> en hvid Néstor AI mod en sort menneskelig spiller<br />
og en hvid menneskelig spiller mod en sort AlphaBeta, hvor den menneskelig<br />
spiller blot kopier Néstor AI’ens træk mod AlphaBeta i det andet vindue og<br />
omvendt.<br />
Resultatet i parentes er for de Officielle Regler, hvor uafgjort tæller som en<br />
sejr <strong>til</strong> sort.<br />
9x9:<br />
Hvid spiller Sort spiller antal spil hvid score sort score hvid% (OR)<br />
Néstor4 Néstor4 5 66 67 50% (40%)<br />
Néstor4 AlphaBeta 5 73 71 70% (60%)<br />
Néstor4 Growth 5 57 73 0% (0%)<br />
AlphaBeta AlphaBeta 10 171 165 65% (50%)<br />
AlphaBeta Néstor4 5 81 62 80% (80%)<br />
AlphaBeta Growth 10 147 162 30% (20%)<br />
Growth Growth 10 157 164 50% (40%)<br />
Growth Néstor4 5 90 75 90% (80%)<br />
Growth AlphaBeta 10 182 141 100% (100%)<br />
Mens AlphaBeta og Néstor4 har en vis tendens <strong>til</strong> at vinde over hinanden, n˚ar<br />
de spiller hvid, s˚a sl˚ar Growth dem begge overbevisende uanset hvilken farve<br />
den spiller som.<br />
N˚ar det kommer <strong>til</strong> beregningstiderne p˚a de tre er det mest sigende at lade<br />
dem kører et helt spil igennem mod sig selv:<br />
9x9 spil mod sig selv AlphaBeta Growth Néstor4<br />
tiden (gennemsnit af flere spil) ca. 30 sekunder ca. 1 minut ca. 19 minutter
Kapitel 8<br />
Konklusion<br />
Jeg m˚atte konstatere under testen af den AI, som Néstor Romeral Andrés har<br />
konstrueret <strong>til</strong> at spille <strong>Taiji</strong>, at den ikke er særlig anvendelig i praksis. Den er<br />
for langsom, n˚ar den skal yde sit ypperste for at vinde spillet. Desuden m˚atte<br />
jeg konkludere, at den ikke p˚a nogen af sine fire niveauer kan vinde over en<br />
kvalificeret menneskelig modstander.<br />
Derfor satte jeg for at teste, om det kunne lade sig gøre at n˚a et højere niveau<br />
med anvendelse af flere metoder indenfor AI.<br />
Hvis man ikke har ubegrænsede ressourcer som i IBM’s Deep Blue skakcomputerprojekt,<br />
er det afgørende at kombinere forskellige metoder og kunne benytte<br />
dem i velovervejet omfang, s˚aledes at man udnytter de <strong>til</strong>gængelige computerkræfter<br />
smart og opn˚ar et anvendeligt resultat.<br />
I opbygningen af mine AI’er har jeg undersøgt forskellige teorier for kunstige<br />
intelligencer (AI’er) og gennemprøvet disse. Derefter har jeg kombineret dem<br />
som gav de bedste resultater og gav mest mening for den foreliggende opgave, at<br />
spille <strong>Taiji</strong>. Mit hovedform˚al har netop været at opn˚a en AI som netop opfører<br />
sig intelligent og samtidig en AI der er <strong>til</strong>strækkelig hurtig <strong>til</strong> at den kan anvendes<br />
i praksis. Desuden forlangte jeg at den skulle kunne vinde over en rimelig<br />
god menneskelig modstander.<br />
Min Growth AI er b˚ade hurtigt og smart. Growth AI’en kan i spil mod sig
92 Konklusion<br />
selv n˚a igennem et helt spil p˚a omkring et minut. Den samme opgave tager<br />
for Néstor Romeral Andrés’ kraftigste AI næsten 20 minutter. Men p˚a trods<br />
af at Néstor Romeral Andrés’ AI anvender godt 20 gange s˚a lang tid <strong>til</strong> sine<br />
beregninger som Growth, lykkedes det kun at vinde et ud 10 spil, og dette var<br />
ud fra de officielle regler, hvor et uafgjort resultat tæller som en sejr for sort.<br />
Growth vinder ni ud af ti gange, hvor den sidste en ud af ti endte uafgjort eller<br />
tabt afhængigt af reglerne. Og dette gjorde den p˚a kun ca. 5% af den tid Néstor<br />
Romeral Andrés’ AI anvendte.<br />
Desværre er resultatet ikke lige s˚a overbevisende mod en erfaren menneskelig<br />
spiller, hvor den vinder en tre-fire gange ud af ti spil, hvilket dog ogs˚a er et<br />
ganske glimmerende resultat sammenlignes med de andre AI’ers resultater.<br />
Min overordnede konklusion er derfor, at ved at benytte flere AI-teorier og<br />
kombinere disse p˚a gennemtænkt og gennemtestet m˚ade, kan man opn˚a væsentlige<br />
forbedringer vedr. afviklingshastighed uden at sætte ’intelligensen’ over<br />
styr. Dette er netop bevist med min AI. Derfor mener jeg ogs˚a det er rimeligt<br />
at konkludere at AI vil kunne anvendes med fordel i flere gennemanalyserede<br />
situationer. Disse situationer kan netop h˚andteres med AI uden at der behøves<br />
at anvendes overvældende computerkraft.<br />
Men ligesom det kan konkluderes at den kunstig intelligens kan bruges med fordel<br />
p˚a gennemanalyserede situationer, kan det <strong>til</strong>svarende konkluderes at: For<br />
situationer, hvor der ikke ligger en grundig analyse, der har afdækket alle udfaldsrum<br />
for en given situation, vil de typer AI som er anvendt i denne opgave<br />
ikke fungere. I situationer hvor ’spilbrættet’ ikke er kendt vil der være behov for<br />
andre metoder, der kan simulere en anden type intelligens, den type vi i daglig<br />
tale kalder intuition.<br />
8.0.1 Fremtidige udviklingsmuligheder:<br />
I fremtidsperspektivet for AlphaBeta AI’en er der mulighed at lave yderligere<br />
forbedringer, disse kun komme p˚a flere fronter, men det bedste resultat ville<br />
formentligt komme af kombinationer mellem nye <strong>til</strong>tag og gamle fungerende<br />
metoder.<br />
Et omr˚ade hvor der kan indføres nogle nye <strong>til</strong>tag er heuristikken. Nye heuristikker<br />
kunne laves, som i stedet for blot at se p˚a scoren, kan g˚a ind og se p˚a<br />
udvidelsesmulighederne for de største figurer eller ser p˚a hvor store de tredje<br />
største figurer er. Det bedste resultat vil nok ikke komme ved at udskifte den<br />
nuværende heuristik med en ny, men netop ved at kombinere den nuværende<br />
heuristik med nye, og finde en passende vægtning mellem dem.<br />
Vægtningen kunne f.eks. <strong>til</strong>passes ved hjælp af mere avancerede metoder inden<br />
for AI, som simuleret nedkøling eller neurale netværk. Vægtningen vil med disse<br />
metoder kunne <strong>til</strong>passes ud fra erfaringer med at spille spillet, og hvordan disse
spil med forskellige vægtninger er endt.<br />
Ses der p˚a den lidt nærmere fremtid kunne AlphaBeta AI’en forbedres ved<br />
hjælp af metoden, der bestemmer hvilke træk der undersøges i Growth AI’en.<br />
Dette skulle ske ved at trækkene, som growth nøjes med at undersøge, skulle<br />
undersøges først i AlphaBeta AI’en, mens de resterende træk kommer i anden<br />
række. Det er nemlig ret sandsynligt, at de bedste træk befinder sig indenfor<br />
de træk growth undersøger. Jo hurtigere AlphaBeta AI’en finder et godt<br />
træk jo bedre fungerer alpha-beta pruning, da den derved kan stoppe en lang<br />
række undersøgelser p˚a et tidligere tidspunkt. I praksis vil denne forbedring<br />
kunne betyde, at AlphaBeta AI’en kommer <strong>til</strong> at kunne klare en dybere søgning<br />
ned i spiltræet. Skulle det hermed lykkedes AlphaBeta AI’en at n˚a den samme<br />
søgedybde, som Growth AI’en leverer, vil AlphaBeta AI’en sandsynligvis g˚a hen<br />
og blive et bedre valg, fordi Growth AI’ens begrænsede søgning i vise <strong>til</strong>fælde<br />
skader kvaliteten af dens resultat.<br />
Forbedringer for Growth AI’en kunne best˚a i at lade dens træk g˚a ud fra de<br />
tre største figurer for hver farve i stedet for blot de to største, som det har<br />
været hid<strong>til</strong>. En forbedring af justeringen af søgedybden kunne ogs˚a hjælpe, da<br />
nogle træk bliver beregnet s˚a hurtigt, at det formentligt ville være muligt at<br />
tage en generation mere med i beregningen i disse <strong>til</strong>fælde. Dette vil dog kræve<br />
en grundigere analyse af bræt<strong>til</strong>standen, da det ikke umiddelbart er <strong>til</strong> at gennemskue,<br />
i hvilke <strong>til</strong>fælde beregningerne er hurtigt overst˚aet og hvorn˚ar de ikke<br />
er.<br />
93
94 Konklusion
Bilag A<br />
To be added<br />
A.1 AI<strong>Taiji</strong>AlphaBeta.java<br />
Kildekode<br />
1 import java . u t i l . Random ;<br />
2 import java . u t i l . ArrayList ;<br />
3<br />
4 p u b l i c c l a s s AI<strong>Taiji</strong>AlphaBeta {<br />
5<br />
6 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
7 p u b l i c Node tNode ;<br />
8 p u b l i c i n t count ; // f o r at t e s t e hvor mange noder der l a v e s .<br />
9 p u b l i c i n t maxDepth ;<br />
10 p r i v a t e ArrayList [ ] [ ] nodes ; // i n d e h o l d e r a l l e noderne i<br />
a r r a y l i s t s e f t e r g e n e r a t i o n og hash v a e r d i .<br />
11 p r i v a t e i n t maxD; // den maximale dybde f o r t r a e e t .<br />
12 p r i v a t e i n t maxH ; // den maximale Hash v a e r d i<br />
13 p r i v a t e Node Root ; // Traeets rod .<br />
14 p r i v a t e i n t searchD ; // Search depth , muligheden f o r at s a e t t e<br />
en maximal s o e g e dybde<br />
15<br />
16 p u b l i c AI<strong>Taiji</strong>AlphaBeta ( <strong>Taiji</strong>Model m) {<br />
17 t h i s . tModel = m;<br />
18 }
96 Bilag A<br />
19<br />
20 // i n i t i a l i s e r e r AlphaBeta<br />
21 p u b l i c void AlphaBeta ( ) {<br />
22 tNode = new Node ( ) ;<br />
23 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;<br />
24 count = 1 ;<br />
25 maxD = tModel . maxTurnsLeft ( ) ;<br />
26 searchD = maxD;<br />
27 maxH = tModel . tHash . getMaxH3 ( ) ;<br />
28 nodes = new ArrayList [maxD ] [ maxH+1];<br />
29 f o r ( i n t i =0; i = 8 && maxT < 10)<br />
57 setSearchDepth ( 3 ) ;<br />
58 i f (maxT > 6 && maxT < 8)<br />
59 setSearchDepth ( 4 ) ;<br />
60 i f (maxT
A.1 AI<strong>Taiji</strong>AlphaBeta.java 97<br />
69 i n t h = tModel . tHash . hashFunction3 ( b ) ;<br />
70 p [0]= d ; / / d ;<br />
71 p [1]= h ;<br />
72 p[2]= −1;<br />
73 f o r ( i n t i = 0 ; i = searchD | | ! tModel . movesLeftN ( n ) ) {<br />
85 n . a = tModel . fMap . c a l D i f ( n . nodeBoard , tModel . noCols ,<br />
tModel . noRows ) ;<br />
86 r e t u r n ( n . a ) ;<br />
87 }<br />
88 e l s e {<br />
89 i f ( ex == 1) {<br />
90 i f ( n . a >= beta )<br />
91 r e t u r n ( n . a ) ;<br />
92 }<br />
93 n . a = −tModel . maxScore ;<br />
94 i n t [ ] [ ] b = n . nodeBoard ;<br />
95 i n t d = n . d ;<br />
96 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
97 f o r ( i n t r =0; r < tModel . noRows−1; r++){<br />
98 i f ( b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {<br />
99 b [ c ] [ r ] = 1 ;<br />
100 b [ c ] [ r +1] = 0 ;<br />
101 i n t [ ] p = new i n t [ 3 ] ;<br />
102 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
103 i f ( p [ 2 ] >= 0) {<br />
104 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
105 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
106 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
107 i f ( n . a < v )<br />
108 n . a = v ;<br />
109 i f ( n . a > beta ) {<br />
110 b [ c ] [ r ] = 2 ;<br />
111 b [ c ] [ r +1] = 2 ;<br />
112 r e t u r n ( n . a ) ;<br />
113 }<br />
114 i f ( alpha < n . a )<br />
115 alpha = n . a ;<br />
116<br />
117 }<br />
118 i f ( p [ 2 ] == −1){<br />
119 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;
98 Bilag A<br />
120 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, n ) ) ) ;<br />
121 count++;<br />
122 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
123 i f ( n . a < v )<br />
124 n . a = v ;<br />
125 i f ( n . a > beta ) {<br />
126 b [ c ] [ r ] = 2 ;<br />
127 b [ c ] [ r +1] = 2 ;<br />
128 r e t u r n ( n . a ) ;<br />
129 }<br />
130 i f ( alpha < n . a )<br />
131 alpha = n . a ;<br />
132<br />
133 }<br />
134 b [ c ] [ r ] = 0 ;<br />
135 b [ c ] [ r +1] = 1 ;<br />
136 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
137 i f ( p [ 2 ] >= 0) {<br />
138 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
139 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
140 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
141 i f ( n . a < v )<br />
142 n . a = v ;<br />
143 i f ( n . a > beta ) {<br />
144 b [ c ] [ r ] = 2 ;<br />
145 b [ c ] [ r +1] = 2 ;<br />
146 r e t u r n ( n . a ) ;<br />
147 }<br />
148 i f ( alpha < n . a )<br />
149 alpha = n . a ;<br />
150 }<br />
151 i f ( p [ 2 ] == −1){<br />
152 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
153 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , n ) ) ) ;<br />
154 count++;<br />
155 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
156 i f ( n . a < v )<br />
157 n . a = v ;<br />
158 i f ( n . a > beta ) {<br />
159 b [ c ] [ r ] = 2 ;<br />
160 b [ c ] [ r +1] = 2 ;<br />
161 r e t u r n ( n . a ) ;<br />
162 }<br />
163 i f ( alpha < n . a )<br />
164 alpha = n . a ;<br />
165 }<br />
166<br />
167 b [ c ] [ r ] = 2 ;<br />
168 b [ c ] [ r +1] = 2 ;
A.1 AI<strong>Taiji</strong>AlphaBeta.java 99<br />
169 }<br />
170 }<br />
171 }<br />
172<br />
173 f o r ( i n t c =0; c < tModel . noCols −1; c++){<br />
174 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
175 i f ( b [ c ] [ r ] == 2 && b [ c +1][ r ] == 2 ) {<br />
176 b [ c ] [ r ] = 1 ;<br />
177 b [ c +1][ r ] = 0 ;<br />
178 i n t [ ] p = new i n t [ 3 ] ;<br />
179 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
180 i f ( p [ 2 ] >= 0) {<br />
181 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
182 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
183 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
184 i f ( n . a < v )<br />
185 n . a = v ;<br />
186 i f ( n . a > beta ) {<br />
187 b [ c ] [ r ] = 2 ;<br />
188 b [ c +1][ r ] = 2 ;<br />
189 r e t u r n ( n . a ) ;<br />
190 }<br />
191 i f ( alpha < n . a )<br />
192 alpha = n . a ;<br />
193 }<br />
194 i f ( p [ 2 ] == −1){<br />
195 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
196 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , n ) ) ) ;<br />
197 count++;<br />
198 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
199 i f ( n . a < v )<br />
200 n . a = v ;<br />
201 i f ( n . a > beta ) {<br />
202 b [ c ] [ r ] = 2 ;<br />
203 b [ c +1][ r ] = 2 ;<br />
204 r e t u r n ( n . a ) ;<br />
205 }<br />
206 i f ( alpha < n . a )<br />
207 alpha = n . a ;<br />
208 }<br />
209 b [ c ] [ r ] = 0 ;<br />
210 b [ c +1][ r ] = 1 ;<br />
211 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
212 i f ( p [ 2 ] >= 0) {<br />
213 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
214 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
215 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
216 i f ( n . a < v )<br />
217 n . a = v ;
100 Bilag A<br />
218 i f ( n . a > beta ) {<br />
219 b [ c ] [ r ] = 2 ;<br />
220 b [ c +1][ r ] = 2 ;<br />
221 r e t u r n ( n . a ) ;<br />
222 }<br />
223 i f ( alpha < n . a )<br />
224 alpha = n . a ;<br />
225 }<br />
226 i f ( p [ 2 ] == −1){<br />
227 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
228 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , n ) ) ) ;<br />
229 count++;<br />
230 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
231 i f ( n . a < v )<br />
232 n . a = v ;<br />
233 i f ( n . a > beta ) {<br />
234 b [ c ] [ r ] = 2 ;<br />
235 b [ c +1][ r ] = 2 ;<br />
236 r e t u r n ( n . a ) ;<br />
237 }<br />
238 i f ( alpha < n . a )<br />
239 alpha = n . a ;<br />
240 }<br />
241 b [ c ] [ r ] = 2 ;<br />
242 b [ c +1][ r ] = 2 ;<br />
243 }<br />
244 }<br />
245 }<br />
246 r e t u r n ( n . a ) ;<br />
247 }<br />
248 }<br />
249<br />
250 // Min−f u n k t i o n e n i minimax−soegningen<br />
251 p r i v a t e i n t min ( Node n , i n t alpha , i n t beta , i n t ex ) {<br />
252 i f ( n . d >= searchD | | ! tModel . movesLeftN ( n ) ) {<br />
253 n . a = tModel . fMap . c a l D i f ( n . nodeBoard , tModel . noCols ,<br />
tModel . noRows ) ;<br />
254 r e t u r n ( n . a ) ;<br />
255 }<br />
256 e l s e {<br />
257 i f ( ex == 1) {<br />
258 i f ( n . a
A.1 AI<strong>Taiji</strong>AlphaBeta.java 101<br />
270 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
271 i f ( p [ 2 ] >= 0) {<br />
272 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
273 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
274 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
275 i f ( n . a > v )<br />
276 n . a = v ;<br />
277 i f ( n . a < alpha ) {<br />
278 b [ c ] [ r ] = 2 ;<br />
279 b [ c ] [ r +1] = 2 ;<br />
280 r e t u r n ( n . a ) ;<br />
281 }<br />
282 i f ( beta > n . a )<br />
283 beta = n . a ;<br />
284 }<br />
285 i f ( p [ 2 ] == −1){<br />
286 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
287 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, n ) ) ) ;<br />
288 count++;<br />
289 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
290 i f ( n . a > v )<br />
291 n . a = v ;<br />
292 i f ( n . a < alpha ) {<br />
293 b [ c ] [ r ] = 2 ;<br />
294 b [ c ] [ r +1] = 2 ;<br />
295 r e t u r n ( n . a ) ;<br />
296 }<br />
297 i f ( beta > n . a )<br />
298 beta = n . a ;<br />
299 }<br />
300 b [ c ] [ r ] = 0 ;<br />
301 b [ c ] [ r +1] = 1 ;<br />
302<br />
303 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
304 i f ( p [ 2 ] >= 0) {<br />
305 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
306 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
307 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
308 i f ( n . a > v )<br />
309 n . a = v ;<br />
310 i f ( n . a < alpha ) {<br />
311 b [ c ] [ r ] = 2 ;<br />
312 b [ c ] [ r +1] = 2 ;<br />
313 r e t u r n ( n . a ) ;<br />
314 }<br />
315 i f ( beta > n . a )<br />
316 beta = n . a ;<br />
317 }<br />
318 i f ( p [ 2 ] == −1){
102 Bilag A<br />
319 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
320 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , n ) ) ) ;<br />
321 count++;<br />
322 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
323 i f ( n . a > v )<br />
324 n . a = v ;<br />
325 i f ( n . a < alpha ) {<br />
326 b [ c ] [ r ] = 2 ;<br />
327 b [ c ] [ r +1] = 2 ;<br />
328 r e t u r n ( n . a ) ;<br />
329 }<br />
330 i f ( beta > n . a )<br />
331 beta = n . a ;<br />
332 }<br />
333 b [ c ] [ r ] = 2 ;<br />
334 b [ c ] [ r +1] = 2 ;<br />
335<br />
336<br />
337 }<br />
338 }<br />
339 }<br />
340<br />
341<br />
342 f o r ( i n t c =0; c < tModel . noCols −1; c++){<br />
343 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
344 i f ( b [ c ] [ r ] == 2 && b [ c +1][ r ] == 2 ) {<br />
345 b [ c ] [ r ] = 1 ;<br />
346 b [ c +1][ r ] = 0 ;<br />
347 i n t [ ] p = new i n t [ 3 ] ;<br />
348 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
349 i f ( p [ 2 ] >= 0) {<br />
350 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
351 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
352 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
353 i f ( n . a > v )<br />
354 n . a = v ;<br />
355 i f ( n . a < alpha ) {<br />
356 b [ c ] [ r ] = 2 ;<br />
357 b [ c +1][ r ] = 2 ;<br />
358 r e t u r n ( n . a ) ;<br />
359 }<br />
360 i f ( beta > n . a )<br />
361 beta = n . a ;<br />
362 }<br />
363 i f ( p [ 2 ] == −1){<br />
364 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
365 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , n ) ) ) ;<br />
366 count++;<br />
367 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;
A.1 AI<strong>Taiji</strong>AlphaBeta.java 103<br />
368 i f ( n . a > v )<br />
369 n . a = v ;<br />
370 i f ( n . a < alpha ) {<br />
371 b [ c ] [ r ] = 2 ;<br />
372 b [ c +1][ r ] = 2 ;<br />
373 r e t u r n ( n . a ) ;<br />
374 }<br />
375 i f ( beta > n . a )<br />
376 beta = n . a ;<br />
377 }<br />
378 b [ c ] [ r ] = 0 ;<br />
379 b [ c +1][ r ] = 1 ;<br />
380<br />
381 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
382 i f ( p [ 2 ] >= 0) {<br />
383 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
384 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
385 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
386 i f ( n . a > v )<br />
387 n . a = v ;<br />
388 i f ( n . a < alpha ) {<br />
389 b [ c ] [ r ] = 2 ;<br />
390 b [ c +1][ r ] = 2 ;<br />
391 r e t u r n ( n . a ) ;<br />
392 }<br />
393 i f ( beta > n . a )<br />
394 beta = n . a ;<br />
395 }<br />
396 i f ( p [ 2 ] == −1){<br />
397 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
398 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , n ) ) ) ;<br />
399 count++;<br />
400 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
401 i f ( n . a > v )<br />
402 n . a = v ;<br />
403 i f ( n . a < alpha ) {<br />
404 b [ c ] [ r ] = 2 ;<br />
405 b [ c +1][ r ] = 2 ;<br />
406 r e t u r n ( n . a ) ;<br />
407 }<br />
408 i f ( beta > n . a )<br />
409 beta = n . a ;<br />
410 }<br />
411 b [ c ] [ r ] = 2 ;<br />
412 b [ c +1][ r ] = 2 ;<br />
413 }<br />
414 }<br />
415 }<br />
416 r e t u r n ( n . a ) ;<br />
417 }<br />
418 }
104 Bilag A<br />
419<br />
420<br />
421<br />
422<br />
423<br />
424<br />
425 // s a e t t e r s c o r e n f o r en node t i l −’ u e n d e l i g ’<br />
426 p r i v a t e Node setScoreMin ( Node n ) {<br />
427 n . a = −tModel . maxScore ;<br />
428 r e t u r n ( n ) ;<br />
429 }<br />
430 // s a e t t e r s c o r e n f o r en node t i l ” u e n d e l i g ”<br />
431 p r i v a t e Node setScoreMax ( Node n ) {<br />
432 n . a = tModel . maxScore ;<br />
433 r e t u r n ( n ) ;<br />
434 }<br />
435<br />
436 // u d s k r i v e r v a e r d i e r n e paa f o r a e l d r e n e t i l en Node<br />
437 p r i v a t e void p r i n t P a r S c o r e ( Node n ) {<br />
438 System . out . p r i n t (”AB p r i n t P a r S c o r e d=”+n . d+” n . par s c o r e s :<br />
”) ;<br />
439 f o r ( i n t i =0; i 1) {<br />
465 i f ( b ) {<br />
466 f o r ( i n t i =0; i Root . c h i l d r e n . get ( i ) . a ) {
A.1 AI<strong>Taiji</strong>AlphaBeta.java 105<br />
468 n=Root . c h i l d r e n . get ( i ) ;<br />
469 }<br />
470 }<br />
471 }<br />
472 i f ( ! b ) {<br />
473 f o r ( i n t i =0; i
106 Bilag A<br />
517 n . wr = tModel . noRows−1 − wR;<br />
518 r e t u r n ( n ) ;<br />
519 }<br />
520 i f (mr == 5) {<br />
521 n . bc = bR ;<br />
522 n . wc = wR;<br />
523 n . br = bC ;<br />
524 n . wr = wC;<br />
525 r e t u r n ( n ) ;<br />
526 }<br />
527 i f (mr == 6) {<br />
528 n . bc = tModel . noRows−1 − bR ;<br />
529 n . wc = tModel . noRows−1 − wR;<br />
530 n . br = bC ;<br />
531 n . wr = wC;<br />
532 r e t u r n ( n ) ;<br />
533 }<br />
534 i f (mr == 7) {<br />
535 n . bc = bR ;<br />
536 n . wc = wR;<br />
537 n . br = tModel . noCols −1 − bC ;<br />
538 n . wr = tModel . noCols −1 − wC;<br />
539 r e t u r n ( n ) ;<br />
540 }<br />
541 i f (mr == 8) {<br />
542 n . bc = tModel . noRows−1 − bR ;<br />
543 n . wc = tModel . noRows−1 − wR;<br />
544 n . br = tModel . noCols −1 − bC ;<br />
545 n . wr = tModel . noCols −1 − wC;<br />
546 r e t u r n ( n ) ;<br />
547 }<br />
548 r e t u r n ( n ) ;<br />
549 }<br />
550<br />
551<br />
552 }<br />
A.2 AI<strong>Taiji</strong>Growth.java<br />
1 import java . u t i l . Random ;<br />
2 import java . u t i l . ArrayList ;<br />
3<br />
4 p u b l i c c l a s s AI<strong>Taiji</strong>Growth {<br />
5<br />
6 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
7 p u b l i c Node tNode ;<br />
8 p u b l i c i n t count ; // f o r at t e s t e hvor mange noder der l a v e s .<br />
9 p u b l i c i n t maxDepth ;<br />
10 p r i v a t e ArrayList [ ] [ ] nodes ; // i n d e h o l d e r a l l e noderne i<br />
a r r a y l i s t s e f t e r g e n e r a t i o n og hash v a e r d i .<br />
11 p r i v a t e i n t maxD; // den maximale dybde f o r t r a e e t .<br />
12 p r i v a t e i n t maxH ; // den maximale Hash v a e r d i<br />
13 p r i v a t e Node Root ; // Traeets rod .
A.2 AI<strong>Taiji</strong>Growth.java 107<br />
14 p r i v a t e i n t searchD ; // Search depth , muligheden f o r at s a e t t e<br />
en maximal s o e g e dybde<br />
15<br />
16 p u b l i c AI<strong>Taiji</strong>Growth ( <strong>Taiji</strong>Model m) {<br />
17 t h i s . tModel = m;<br />
18 }<br />
19<br />
20 p u b l i c void Growth ( ) {<br />
21 tNode = new Node ( ) ;<br />
22 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;<br />
23 count = 1 ;<br />
24 maxD = tModel . maxTurnsLeft ( ) ; // max dybden s p i l g r a f e n kan<br />
opnaa f i n d e s<br />
25 searchD = maxD; // soegedybden s a e t t e s som udgangspunkt t i l<br />
at gaa h e l t i bund<br />
26 maxH = tModel . tHash . getMaxH3 ( ) ; //maxH s a e t t e s udfra<br />
h v i l k e n h a s h funktion der anvendes<br />
27 nodes = new ArrayList [maxD ] [ maxH+1];<br />
28 f o r ( i n t i =0; i 7 && maxT 6 && maxT
108 Bilag A<br />
61 }<br />
62 }<br />
63<br />
64 // c h e c k e r om der a l l e r e d e e r e t saadant b r a e t . Returnerer<br />
c o r d i n a t e r n e f o r den node , h v i s der e r .<br />
65 p r i v a t e i n t [ ] c h e c k B o a r d I n d i v i d u a l i t y ( i n t [ ] [ ] b , i n t d ) {<br />
66 i n t [ ] p = new i n t [ 3 ] ;<br />
67 i n t h = tModel . tHash . hashFunction3 ( b ) ;<br />
68 p [0]= d ;<br />
69 p [1]= h ;<br />
70 p[2]= −1;<br />
71 f o r ( i n t i = 0 ; i = searchD | | ! tModel . movesLeftN ( n ) ) {<br />
83 n . a = tModel . fMap . c a l D i f ( n . nodeBoard , tModel . noCols ,<br />
tModel . noRows ) ;<br />
84 r e t u r n ( n . a ) ;<br />
85 }<br />
86 e l s e {<br />
87 i f ( ex == 1) {<br />
88 i f ( n . a >= beta )<br />
89 r e t u r n ( n . a ) ;<br />
90 }<br />
91 n . a = −tModel . maxScore ;<br />
92 i n t [ ] [ ] b = n . nodeBoard ;<br />
93 i n t [ ] [ ] fb = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
94 i n t d = n . d ;<br />
95 i n t [ ] [ ] [ ] f i g s ;<br />
96<br />
97<br />
98 fb = tModel . fMap . getFigBoard ( n . nodeBoard , tModel . noCols<br />
, tModel . noRows ) ;<br />
99 f i g s = tModel . fMap . g e t F i g s ( fb ) ;<br />
100<br />
101 i f ( f a l s e ) { // s a e t t e s t i l t r u e f o r at p r i n t e f i g B o a r d<br />
og h v i l k e f i g u r e , der e r s t o e r s t med f r i e p l a d s e r<br />
omkring s i g . T i l t e s t brug<br />
102 System . out . p r i n t l n (” growth f i g s W: ”+ f i g s<br />
[ 1 ] [ 0 ] [ 0 ] + ” & ”+ f i g s [ 1 ] [ 1 ] [ 0 ] + ” B: ”+ f i g s<br />
[ 0 ] [ 0 ] [ 0 ] + ” & ”+ f i g s [ 0 ] [ 1 ] [ 0 ] ) ;<br />
103 printFB ( fb ) ;<br />
104 }<br />
105<br />
106<br />
107
A.2 AI<strong>Taiji</strong>Growth.java 109<br />
108 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
109 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
110 i f ( fb [ c ] [ r ] == f i g s [ 1 ] [ 0 ] [ 0 ] | | fb [ c ] [ r ] ==<br />
f i g s [ 1 ] [ 1 ] [ 0 ] | | fb [ c ] [ r ] == f i g s [ 0 ] [ 0 ] [ 0 ]<br />
| | fb [ c ] [ r ] == f i g s [ 0 ] [ 1 ] [ 0 ] ) {<br />
111 // o e s t<br />
112 i f ( c < tModel . noCols −1){<br />
113 i f ( fb [ c +1][ r ] == 0) {<br />
114 i f ( r < tModel . noRows−1){<br />
115 i f ( fb [ c +1][ r +1] == 0) {<br />
116 i n t [ ] r e ;<br />
117 b [ c +1][ r ] = 1 ;<br />
118 b [ c +1][ r +1] = 0 ;<br />
119 r e = placePieceMax ( b , d , n ,<br />
c +1, r , c +1, r +1,<br />
alpha , beta ) ;<br />
120 alpha = r e [ 1 ] ;<br />
121 beta = r e [ 2 ] ;<br />
122 i f ( r e [ 0 ] == 1) {<br />
123 b [ c +1][ r ] = 2 ;<br />
124 b [ c +1][ r +1] = 2 ;<br />
125 r e t u r n ( r e [ 3 ] ) ;<br />
126 }<br />
127 b [ c +1][ r ] = 0 ;<br />
128 b [ c +1][ r +1] = 1 ;<br />
129 r e = placePieceMax ( b , d , n ,<br />
c +1, r +1, c +1, r ,<br />
alpha , beta ) ;<br />
130 alpha = r e [ 1 ] ;<br />
131 beta = r e [ 2 ] ;<br />
132 i f ( r e [ 0 ] == 1) {<br />
133 b [ c +1][ r ] = 2 ;<br />
134 b [ c +1][ r +1] = 2 ;<br />
135 r e t u r n ( r e [ 3 ] ) ;<br />
136 }<br />
137 b [ c +1][ r ] = 2 ;<br />
138 b [ c +1][ r +1] = 2 ;<br />
139 }<br />
140 }<br />
141 i f ( r > 0) {<br />
142 i f ( fb [ c +1][ r −1] == 0) {<br />
143 i n t [ ] r e ;<br />
144 b [ c +1][ r ] = 1 ;<br />
145 b [ c +1][ r −1] = 0 ;<br />
146 r e = placePieceMax ( b , d , n ,<br />
c +1, r , c +1, r −1,<br />
alpha , beta ) ;<br />
147 alpha = r e [ 1 ] ;<br />
148 beta = r e [ 2 ] ;<br />
149 i f ( r e [ 0 ] == 1) {<br />
150 b [ c +1][ r ] = 2 ;<br />
151 b [ c +1][ r −1] = 2 ;<br />
152 r e t u r n ( r e [ 3 ] ) ;<br />
153 }<br />
154 b [ c +1][ r ] = 0 ;
110 Bilag A<br />
155 b [ c +1][ r −1] = 1 ;<br />
156 r e = placePieceMax ( b , d , n ,<br />
c +1, r −1, c +1, r ,<br />
alpha , beta ) ;<br />
157 alpha = r e [ 1 ] ;<br />
158 beta = r e [ 2 ] ;<br />
159 i f ( r e [ 0 ] == 1) {<br />
160 b [ c +1][ r ] = 2 ;<br />
161 b [ c +1][ r −1] = 2 ;<br />
162 r e t u r n ( r e [ 3 ] ) ;<br />
163 }<br />
164 b [ c +1][ r ] = 2 ;<br />
165 b [ c +1][ r −1] = 2 ;<br />
166 }<br />
167 }<br />
168 i f ( c < tModel . noCols −2){<br />
169 i f ( fb [ c +2][ r ] == 0) {<br />
170 i n t [ ] r e ;<br />
171 b [ c +1][ r ] = 1 ;<br />
172 b [ c +2][ r ] = 0 ;<br />
173 r e = placePieceMax ( b , d , n ,<br />
c +1, r , c +2, r , alpha ,<br />
beta ) ;<br />
174 alpha = r e [ 1 ] ;<br />
175 beta = r e [ 2 ] ;<br />
176 i f ( r e [ 0 ] == 1) {<br />
177 b [ c +1][ r ] = 2 ;<br />
178 b [ c +2][ r ] = 2 ;<br />
179 r e t u r n ( r e [ 3 ] ) ;<br />
180 }<br />
181 b [ c +1][ r ] = 0 ;<br />
182 b [ c +2][ r ] = 1 ;<br />
183 r e = placePieceMax ( b , d , n ,<br />
c +2, r , c +1, r , alpha ,<br />
beta ) ;<br />
184 alpha = r e [ 1 ] ;<br />
185 beta = r e [ 2 ] ;<br />
186 i f ( r e [ 0 ] == 1) {<br />
187 b [ c +1][ r ] = 2 ;<br />
188 b [ c +2][ r ] = 2 ;<br />
189 r e t u r n ( r e [ 3 ] ) ;<br />
190 }<br />
191 b [ c +1][ r ] = 2 ;<br />
192 b [ c +2][ r ] = 2 ;<br />
193 }<br />
194 }<br />
195 }<br />
196 }<br />
197 // v e s t<br />
198 i f ( c > 0) {<br />
199 i f ( fb [ c −1][ r ] == 0) {<br />
200 i f ( r < tModel . noRows−1){<br />
201 i f ( fb [ c −1][ r +1] == 0) {<br />
202 i n t [ ] r e ;<br />
203 b [ c −1][ r ] = 1 ;
A.2 AI<strong>Taiji</strong>Growth.java 111<br />
204 b [ c −1][ r +1] = 0 ;<br />
205 r e = placePieceMax ( b , d , n ,<br />
c −1, r , c −1, r +1,<br />
alpha , beta ) ;<br />
206 alpha = r e [ 1 ] ;<br />
207 beta = r e [ 2 ] ;<br />
208 i f ( r e [ 0 ] == 1) {<br />
209 b [ c −1][ r ] = 2 ;<br />
210 b [ c −1][ r +1] = 2 ;<br />
211 r e t u r n ( r e [ 3 ] ) ;<br />
212 }<br />
213 b [ c −1][ r ] = 0 ;<br />
214 b [ c −1][ r +1] = 1 ;<br />
215 r e = placePieceMax ( b , d , n ,<br />
c −1, r +1, c −1, r ,<br />
alpha , beta ) ;<br />
216 alpha = r e [ 1 ] ;<br />
217 beta = r e [ 2 ] ;<br />
218 i f ( r e [ 0 ] == 1) {<br />
219 b [ c −1][ r ] = 2 ;<br />
220 b [ c −1][ r +1] = 2 ;<br />
221 r e t u r n ( r e [ 3 ] ) ;<br />
222 }<br />
223 b [ c −1][ r ] = 2 ;<br />
224 b [ c −1][ r +1] = 2 ;<br />
225 }<br />
226 }<br />
227 i f ( r > 0) {<br />
228 i f ( fb [ c −1][ r −1] == 0) {<br />
229 i n t [ ] r e ;<br />
230 b [ c −1][ r ] = 1 ;<br />
231 b [ c −1][ r −1] = 0 ;<br />
232 r e = placePieceMax ( b , d , n ,<br />
c −1, r , c −1, r −1,<br />
alpha , beta ) ;<br />
233 alpha = r e [ 1 ] ;<br />
234 beta = r e [ 2 ] ;<br />
235 i f ( r e [ 0 ] == 1) {<br />
236 b [ c −1][ r ] = 2 ;<br />
237 b [ c −1][ r −1] = 2 ;<br />
238 r e t u r n ( r e [ 3 ] ) ;<br />
239 }<br />
240 b [ c −1][ r ] = 0 ;<br />
241 b [ c −1][ r −1] = 1 ;<br />
242 r e = placePieceMax ( b , d , n ,<br />
c −1, r −1, c −1, r ,<br />
alpha , beta ) ;<br />
243 alpha = r e [ 1 ] ;<br />
244 beta = r e [ 2 ] ;<br />
245 i f ( r e [ 0 ] == 1) {<br />
246 b [ c −1][ r ] = 2 ;<br />
247 b [ c −1][ r −1] = 2 ;<br />
248 r e t u r n ( r e [ 3 ] ) ;<br />
249 }<br />
250 b [ c −1][ r ] = 2 ;
112 Bilag A<br />
251 b [ c −1][ r −1] = 2 ;<br />
252 }<br />
253 }<br />
254 i f ( c > 1) {<br />
255 i f ( fb [ c −2][ r ] == 0) {<br />
256 i n t [ ] r e ;<br />
257 b [ c −1][ r ] = 1 ;<br />
258 b [ c −2][ r ] = 0 ;<br />
259 r e = placePieceMax ( b , d , n ,<br />
c −1, r , c −2, r , alpha ,<br />
beta ) ;<br />
260 alpha = r e [ 1 ] ;<br />
261 beta = r e [ 2 ] ;<br />
262 i f ( r e [ 0 ] == 1) {<br />
263 b [ c −1][ r ] = 2 ;<br />
264 b [ c −2][ r ] = 2 ;<br />
265 r e t u r n ( r e [ 3 ] ) ;<br />
266 }<br />
267 b [ c −1][ r ] = 0 ;<br />
268 b [ c −2][ r ] = 1 ;<br />
269 r e = placePieceMax ( b , d , n ,<br />
c −2, r , c −1, r , alpha ,<br />
beta ) ;<br />
270 alpha = r e [ 1 ] ;<br />
271 beta = r e [ 2 ] ;<br />
272 i f ( r e [ 0 ] == 1) {<br />
273 b [ c −1][ r ] = 2 ;<br />
274 b [ c −2][ r ] = 2 ;<br />
275 r e t u r n ( r e [ 3 ] ) ;<br />
276 }<br />
277 b [ c −1][ r ] = 2 ;<br />
278 b [ c −2][ r ] = 2 ;<br />
279 }<br />
280 }<br />
281 }<br />
282 }<br />
283 // System . out . p r i n t l n (” Growth count so f a r<br />
”+count+” d=”+n . d ) ;<br />
284 // printFB ( fb ) ;<br />
285 // syd<br />
286 i f ( r < tModel . noRows−1){<br />
287 i f ( fb [ c ] [ r +1] == 0) {<br />
288 i f ( c < tModel . noCols −1){<br />
289 i f ( fb [ c +1][ r +1] == 0) {<br />
290 i n t [ ] r e ;<br />
291 b [ c ] [ r +1] = 1 ;<br />
292 b [ c +1][ r +1] = 0 ;<br />
293 r e = placePieceMax ( b , d , n ,<br />
c , r +1, c +1, r +1,<br />
alpha , beta ) ;<br />
294 alpha = r e [ 1 ] ;<br />
295 beta = r e [ 2 ] ;<br />
296 i f ( r e [ 0 ] == 1) {<br />
297 b [ c ] [ r +1] = 2 ;<br />
298 b [ c +1][ r +1] = 2 ;
A.2 AI<strong>Taiji</strong>Growth.java 113<br />
299 r e t u r n ( r e [ 3 ] ) ;<br />
300 }<br />
301 b [ c ] [ r +1] = 0 ;<br />
302 b [ c +1][ r +1] = 1 ;<br />
303 r e = placePieceMax ( b , d , n ,<br />
c +1, r +1, c , r +1,<br />
alpha , beta ) ;<br />
304 alpha = r e [ 1 ] ;<br />
305 beta = r e [ 2 ] ;<br />
306 i f ( r e [ 0 ] == 1) {<br />
307 b [ c ] [ r +1] = 2 ;<br />
308 b [ c +1][ r +1] = 2 ;<br />
309 r e t u r n ( r e [ 3 ] ) ;<br />
310 }<br />
311 b [ c ] [ r +1] = 2 ;<br />
312 b [ c +1][ r +1] = 2 ;<br />
313 }<br />
314 }<br />
315 i f ( c > 0) {<br />
316 i f ( fb [ c −1][ r +1] == 0) {<br />
317 i n t [ ] r e ;<br />
318 b [ c ] [ r +1] = 1 ;<br />
319 b [ c −1][ r +1] = 0 ;<br />
320 r e = placePieceMax ( b , d , n ,<br />
c , r +1, c −1, r +1,<br />
alpha , beta ) ;<br />
321 alpha = r e [ 1 ] ;<br />
322 beta = r e [ 2 ] ;<br />
323 i f ( r e [ 0 ] == 1) {<br />
324 b [ c ] [ r +1] = 2 ;<br />
325 b [ c −1][ r +1] = 2 ;<br />
326 r e t u r n ( r e [ 3 ] ) ;<br />
327 }<br />
328 b [ c ] [ r +1] = 0 ;<br />
329 b [ c −1][ r +1] = 1 ;<br />
330 r e = placePieceMax ( b , d , n ,<br />
c −1, r +1, c , r +1,<br />
alpha , beta ) ;<br />
331 alpha = r e [ 1 ] ;<br />
332 beta = r e [ 2 ] ;<br />
333 i f ( r e [ 0 ] == 1) {<br />
334 b [ c ] [ r +1] = 2 ;<br />
335 b [ c −1][ r +1] = 2 ;<br />
336 r e t u r n ( r e [ 3 ] ) ;<br />
337 }<br />
338 b [ c ] [ r +1] = 2 ;<br />
339 b [ c −1][ r +1] = 2 ;<br />
340 }<br />
341 }<br />
342 i f ( r < tModel . noRows−2){<br />
343 i f ( fb [ c ] [ r +2] == 0) {<br />
344 i n t [ ] r e ;<br />
345 b [ c ] [ r +1] = 1 ;<br />
346 b [ c ] [ r +2] = 0 ;
114 Bilag A<br />
347 r e = placePieceMax ( b , d , n ,<br />
c , r +1, c , r +2, alpha ,<br />
beta ) ;<br />
348 alpha = r e [ 1 ] ;<br />
349 beta = r e [ 2 ] ;<br />
350 i f ( r e [ 0 ] == 1) {<br />
351 b [ c ] [ r +1] = 2 ;<br />
352 b [ c ] [ r +2] = 2 ;<br />
353 r e t u r n ( r e [ 3 ] ) ;<br />
354 }<br />
355 b [ c ] [ r +1] = 0 ;<br />
356 b [ c ] [ r +2] = 1 ;<br />
357 r e = placePieceMax ( b , d , n ,<br />
c , r +2, c , r +1, alpha ,<br />
beta ) ;<br />
358 alpha = r e [ 1 ] ;<br />
359 beta = r e [ 2 ] ;<br />
360 i f ( r e [ 0 ] == 1) {<br />
361 b [ c ] [ r +1] = 2 ;<br />
362 b [ c ] [ r +2] = 2 ;<br />
363 r e t u r n ( r e [ 3 ] ) ;<br />
364 }<br />
365 b [ c ] [ r +1] = 2 ;<br />
366 b [ c ] [ r +2] = 2 ;<br />
367 }<br />
368 }<br />
369 }<br />
370 }<br />
371 // Nord<br />
372 i f ( r > 0) {<br />
373 i f ( fb [ c ] [ r −1] == 0) {<br />
374 i f ( c > 0) {<br />
375 i f ( fb [ c −1][ r −1] == 0) {<br />
376 i n t [ ] r e ;<br />
377 b [ c ] [ r −1] = 1 ;<br />
378 b [ c −1][ r −1] = 0 ;<br />
379 r e = placePieceMax ( b , d , n ,<br />
c , r −1, c −1, r −1,<br />
alpha , beta ) ;<br />
380 alpha = r e [ 1 ] ;<br />
381 beta = r e [ 2 ] ;<br />
382 i f ( r e [ 0 ] == 1) {<br />
383 b [ c ] [ r −1] = 2 ;<br />
384 b [ c −1][ r −1] = 2 ;<br />
385 r e t u r n ( r e [ 3 ] ) ;<br />
386 }<br />
387 b [ c ] [ r −1] = 0 ;<br />
388 b [ c −1][ r −1] = 1 ;<br />
389 r e = placePieceMax ( b , d , n ,<br />
c −1, r −1, c , r −1,<br />
alpha , beta ) ;<br />
390 alpha = r e [ 1 ] ;<br />
391 beta = r e [ 2 ] ;<br />
392 i f ( r e [ 0 ] == 1) {<br />
393 b [ c ] [ r −1] = 2 ;
A.2 AI<strong>Taiji</strong>Growth.java 115<br />
394 b [ c −1][ r −1] = 2 ;<br />
395 r e t u r n ( r e [ 3 ] ) ;<br />
396 }<br />
397 b [ c ] [ r −1] = 2 ;<br />
398 b [ c −1][ r −1] = 2 ;<br />
399 }<br />
400 }<br />
401 i f ( c < tModel . noCols −1){<br />
402 i f ( fb [ c +1][ r −1] == 0) {<br />
403 i n t [ ] r e ;<br />
404 b [ c ] [ r −1] = 1 ;<br />
405 b [ c +1][ r −1] = 0 ;<br />
406 r e = placePieceMax ( b , d , n ,<br />
c , r −1, c +1, r −1,<br />
alpha , beta ) ;<br />
407 alpha = r e [ 1 ] ;<br />
408 beta = r e [ 2 ] ;<br />
409 i f ( r e [ 0 ] == 1) {<br />
410 b [ c ] [ r −1] = 2 ;<br />
411 b [ c +1][ r −1] = 2 ;<br />
412 r e t u r n ( r e [ 3 ] ) ;<br />
413 }<br />
414 b [ c ] [ r −1] = 0 ;<br />
415 b [ c +1][ r −1] = 1 ;<br />
416 r e = placePieceMax ( b , d , n ,<br />
c +1, r −1, c , r −1,<br />
alpha , beta ) ;<br />
417 alpha = r e [ 1 ] ;<br />
418 beta = r e [ 2 ] ;<br />
419 i f ( r e [ 0 ] == 1) {<br />
420 b [ c ] [ r −1] = 2 ;<br />
421 b [ c +1][ r −1] = 2 ;<br />
422 r e t u r n ( r e [ 3 ] ) ;<br />
423 }<br />
424 b [ c ] [ r −1] = 2 ;<br />
425 b [ c +1][ r −1] = 2 ;<br />
426 }<br />
427 }<br />
428 i f ( r > 1) {<br />
429 i f ( fb [ c ] [ r −2] == 0) {<br />
430 i n t [ ] r e ;<br />
431 b [ c ] [ r −1] = 1 ;<br />
432 b [ c ] [ r −2] = 0 ;<br />
433 r e = placePieceMax ( b , d , n ,<br />
c , r −1, c , r −2, alpha ,<br />
beta ) ;<br />
434 alpha = r e [ 1 ] ;<br />
435 beta = r e [ 2 ] ;<br />
436 i f ( r e [ 0 ] == 1) {<br />
437 b [ c ] [ r −1] = 2 ;<br />
438 b [ c ] [ r −2] = 2 ;<br />
439 r e t u r n ( r e [ 3 ] ) ;<br />
440 }<br />
441 b [ c ] [ r −1] = 0 ;<br />
442 b [ c ] [ r −2] = 1 ;
116 Bilag A<br />
443 r e = placePieceMax ( b , d , n ,<br />
c , r −2, c , r −1, alpha ,<br />
beta ) ;<br />
444 alpha = r e [ 1 ] ;<br />
445 beta = r e [ 2 ] ;<br />
446 i f ( r e [ 0 ] == 1) {<br />
447 b [ c ] [ r −1] = 2 ;<br />
448 b [ c ] [ r −2] = 2 ;<br />
449 r e t u r n ( r e [ 3 ] ) ;<br />
450 }<br />
451 b [ c ] [ r −1] = 2 ;<br />
452 b [ c ] [ r −2] = 2 ;<br />
453 }<br />
454 }<br />
455 }<br />
456 }<br />
457 }<br />
458 }<br />
459 }<br />
460 r e t u r n ( n . a ) ;<br />
461 }<br />
462 }<br />
463<br />
464 //Min−f u n k t i o n e n<br />
465 p r i v a t e i n t min ( Node n , i n t alpha , i n t beta , i n t ex ) {<br />
466 // System . out . p r i n t l n (” Growth − Min”) ;<br />
467 i f ( n . d >= searchD | | ! tModel . movesLeftN ( n ) ) {<br />
468 n . a = tModel . fMap . c a l D i f ( n . nodeBoard , tModel . noCols ,<br />
tModel . noRows ) ;<br />
469 r e t u r n ( n . a ) ;<br />
470 }<br />
471 e l s e {<br />
472 i f ( ex == 1) {<br />
473 i f ( n . a
A.2 AI<strong>Taiji</strong>Growth.java 117<br />
490 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
491 i f ( fb [ c ] [ r ] == f i g s [ 1 ] [ 0 ] [ 0 ] | | fb [ c ] [ r ] ==<br />
f i g s [ 1 ] [ 1 ] [ 0 ] | | fb [ c ] [ r ] == f i g s [ 0 ] [ 0 ] [ 0 ]<br />
| | fb [ c ] [ r ] == f i g s [ 0 ] [ 1 ] [ 0 ] ) {<br />
492 // o e s t<br />
493 i f ( c < tModel . noCols −1){<br />
494 i f ( fb [ c +1][ r ] == 0) {<br />
495 i f ( r < tModel . noRows−1){<br />
496 i f ( fb [ c +1][ r +1] == 0) {<br />
497 i f ( n . a==0) ;<br />
498 i n t [ ] r e ;<br />
499 b [ c +1][ r ] = 1 ;<br />
500 b [ c +1][ r +1] = 0 ;<br />
501 r e = placePieceMin ( b , d , n ,<br />
c +1, r , c +1, r +1,<br />
alpha , beta ) ;<br />
502 alpha = r e [ 1 ] ;<br />
503 beta = r e [ 2 ] ;<br />
504 i f ( r e [ 0 ] == 1) {<br />
505 b [ c +1][ r ] = 2 ;<br />
506 b [ c +1][ r +1] = 2 ;<br />
507 r e t u r n ( n . a ) ;<br />
508 }<br />
509 b [ c +1][ r ] = 0 ;<br />
510 b [ c +1][ r +1] = 1 ;<br />
511 r e = placePieceMin ( b , d , n ,<br />
c +1, r +1, c +1, r ,<br />
alpha , beta ) ;<br />
512 alpha = r e [ 1 ] ;<br />
513 beta = r e [ 2 ] ;<br />
514 i f ( r e [ 0 ] == 1) {<br />
515 b [ c +1][ r ] = 2 ;<br />
516 b [ c +1][ r +1] = 2 ;<br />
517 r e t u r n ( r e [ 3 ] ) ;<br />
518 }<br />
519 b [ c +1][ r ] = 2 ;<br />
520 b [ c +1][ r +1] = 2 ;<br />
521 }<br />
522 }<br />
523 i f ( r > 0) {<br />
524 i f ( fb [ c +1][ r −1] == 0) {<br />
525 i n t [ ] r e ;<br />
526 b [ c +1][ r ] = 1 ;<br />
527 b [ c +1][ r −1] = 0 ;<br />
528 r e = placePieceMin ( b , d , n ,<br />
c +1, r , c +1, r −1,<br />
alpha , beta ) ;<br />
529 alpha = r e [ 1 ] ;<br />
530 beta = r e [ 2 ] ;<br />
531 i f ( r e [ 0 ] == 1) {<br />
532 b [ c +1][ r ] = 2 ;<br />
533 b [ c +1][ r −1] = 2 ;<br />
534 r e t u r n ( r e [ 3 ] ) ;<br />
535 }<br />
536 b [ c +1][ r ] = 0 ;
118 Bilag A<br />
537 b [ c +1][ r −1] = 1 ;<br />
538 r e = placePieceMin ( b , d , n ,<br />
c +1, r −1, c +1, r ,<br />
alpha , beta ) ;<br />
539 alpha = r e [ 1 ] ;<br />
540 beta = r e [ 2 ] ;<br />
541 i f ( r e [ 0 ] == 1) {<br />
542 b [ c +1][ r ] = 2 ;<br />
543 b [ c +1][ r −1] = 2 ;<br />
544 r e t u r n ( r e [ 3 ] ) ;<br />
545 }<br />
546 b [ c +1][ r ] = 2 ;<br />
547 b [ c +1][ r −1] = 2 ;<br />
548 }<br />
549 }<br />
550 i f ( c < tModel . noCols −2){<br />
551 i f ( fb [ c +2][ r ] == 0) {<br />
552 i n t [ ] r e ;<br />
553 b [ c +1][ r ] = 1 ;<br />
554 b [ c +2][ r ] = 0 ;<br />
555 r e = placePieceMin ( b , d , n ,<br />
c +1, r , c +2, r , alpha ,<br />
beta ) ;<br />
556 alpha = r e [ 1 ] ;<br />
557 beta = r e [ 2 ] ;<br />
558 i f ( r e [ 0 ] == 1) {<br />
559 b [ c +1][ r ] = 2 ;<br />
560 b [ c +2][ r ] = 2 ;<br />
561 r e t u r n ( r e [ 3 ] ) ;<br />
562 }<br />
563 b [ c +1][ r ] = 0 ;<br />
564 b [ c +2][ r ] = 1 ;<br />
565 r e = placePieceMin ( b , d , n ,<br />
c +2, r , c +1, r , alpha ,<br />
beta ) ;<br />
566 alpha = r e [ 1 ] ;<br />
567 beta = r e [ 2 ] ;<br />
568 i f ( r e [ 0 ] == 1) {<br />
569 b [ c +1][ r ] = 2 ;<br />
570 b [ c +2][ r ] = 2 ;<br />
571 r e t u r n ( r e [ 3 ] ) ;<br />
572 }<br />
573 b [ c +1][ r ] = 2 ;<br />
574 b [ c +2][ r ] = 2 ;<br />
575 }<br />
576 }<br />
577 }<br />
578 }<br />
579 // v e s t<br />
580 i f ( c > 0) {<br />
581 i f ( fb [ c −1][ r ] == 0) {<br />
582 i f ( r < tModel . noRows−1){<br />
583 i f ( fb [ c −1][ r +1] == 0) {<br />
584 i n t [ ] r e ;<br />
585 b [ c −1][ r ] = 1 ;
A.2 AI<strong>Taiji</strong>Growth.java 119<br />
586 b [ c −1][ r +1] = 0 ;<br />
587 r e = placePieceMin ( b , d , n ,<br />
c −1, r , c −1, r +1,<br />
alpha , beta ) ;<br />
588 alpha = r e [ 1 ] ;<br />
589 beta = r e [ 2 ] ;<br />
590 i f ( r e [ 0 ] == 1) {<br />
591 b [ c −1][ r ] = 2 ;<br />
592 b [ c −1][ r +1] = 2 ;<br />
593 r e t u r n ( r e [ 3 ] ) ;<br />
594 }<br />
595 b [ c −1][ r ] = 0 ;<br />
596 b [ c −1][ r +1] = 1 ;<br />
597 r e = placePieceMin ( b , d , n ,<br />
c −1, r +1, c −1, r ,<br />
alpha , beta ) ;<br />
598 alpha = r e [ 1 ] ;<br />
599 beta = r e [ 2 ] ;<br />
600 i f ( r e [ 0 ] == 1) {<br />
601 b [ c −1][ r ] = 2 ;<br />
602 b [ c −1][ r +1] = 2 ;<br />
603 r e t u r n ( r e [ 3 ] ) ;<br />
604 }<br />
605 b [ c −1][ r ] = 2 ;<br />
606 b [ c −1][ r +1] = 2 ;<br />
607 }<br />
608 }<br />
609 i f ( r > 0) {<br />
610 i f ( fb [ c −1][ r −1] == 0) {<br />
611 i n t [ ] r e ;<br />
612 b [ c −1][ r ] = 1 ;<br />
613 b [ c −1][ r −1] = 0 ;<br />
614 r e = placePieceMin ( b , d , n ,<br />
c −1, r , c −1, r −1,<br />
alpha , beta ) ;<br />
615 alpha = r e [ 1 ] ;<br />
616 beta = r e [ 2 ] ;<br />
617 i f ( r e [ 0 ] == 1) {<br />
618 b [ c −1][ r ] = 2 ;<br />
619 b [ c −1][ r −1] = 2 ;<br />
620 r e t u r n ( r e [ 3 ] ) ;<br />
621 }<br />
622 b [ c −1][ r ] = 0 ;<br />
623 b [ c −1][ r −1] = 1 ;<br />
624 r e = placePieceMin ( b , d , n ,<br />
c −1, r −1, c −1, r ,<br />
alpha , beta ) ;<br />
625 alpha = r e [ 1 ] ;<br />
626 beta = r e [ 2 ] ;<br />
627 i f ( r e [ 0 ] == 1) {<br />
628 b [ c −1][ r ] = 2 ;<br />
629 b [ c −1][ r −1] = 2 ;<br />
630 r e t u r n ( r e [ 3 ] ) ;<br />
631 }<br />
632 b [ c −1][ r ] = 2 ;
120 Bilag A<br />
633 b [ c −1][ r −1] = 2 ;<br />
634 }<br />
635 }<br />
636 i f ( c > 1) {<br />
637 i f ( fb [ c −2][ r ] == 0) {<br />
638 i n t [ ] r e ;<br />
639 b [ c −1][ r ] = 1 ;<br />
640 b [ c −2][ r ] = 0 ;<br />
641 r e = placePieceMin ( b , d , n ,<br />
c −1, r , c −2, r , alpha ,<br />
beta ) ;<br />
642 alpha = r e [ 1 ] ;<br />
643 beta = r e [ 2 ] ;<br />
644 i f ( r e [ 0 ] == 1) {<br />
645 b [ c −1][ r ] = 2 ;<br />
646 b [ c −2][ r ] = 2 ;<br />
647 r e t u r n ( r e [ 3 ] ) ;<br />
648 }<br />
649 b [ c −1][ r ] = 0 ;<br />
650 b [ c −2][ r ] = 1 ;<br />
651 r e = placePieceMin ( b , d , n ,<br />
c −2, r , c −1, r , alpha ,<br />
beta ) ;<br />
652 alpha = r e [ 1 ] ;<br />
653 beta = r e [ 2 ] ;<br />
654 i f ( r e [ 0 ] == 1) {<br />
655 b [ c −1][ r ] = 2 ;<br />
656 b [ c −2][ r ] = 2 ;<br />
657 r e t u r n ( r e [ 3 ] ) ;<br />
658 }<br />
659 b [ c −1][ r ] = 2 ;<br />
660 b [ c −2][ r ] = 2 ;<br />
661 }<br />
662 }<br />
663 }<br />
664 }<br />
665 // syd<br />
666 i f ( r < tModel . noRows−1){<br />
667 i f ( fb [ c ] [ r +1] == 0) {<br />
668 i f ( c < tModel . noCols −1){<br />
669 i f ( fb [ c +1][ r +1] == 0) {<br />
670 i n t [ ] r e ;<br />
671 b [ c ] [ r +1] = 1 ;<br />
672 b [ c +1][ r +1] = 0 ;<br />
673 r e = placePieceMin ( b , d , n ,<br />
c , r +1, c +1, r +1,<br />
alpha , beta ) ;<br />
674 alpha = r e [ 1 ] ;<br />
675 beta = r e [ 2 ] ;<br />
676 i f ( r e [ 0 ] == 1) {<br />
677 b [ c ] [ r +1] = 2 ;<br />
678 b [ c +1][ r +1] = 2 ;<br />
679 r e t u r n ( r e [ 3 ] ) ;<br />
680 }<br />
681 b [ c ] [ r +1] = 0 ;
A.2 AI<strong>Taiji</strong>Growth.java 121<br />
682 b [ c +1][ r +1] = 1 ;<br />
683 r e = placePieceMin ( b , d , n ,<br />
c +1, r +1, c , r +1,<br />
alpha , beta ) ;<br />
684 alpha = r e [ 1 ] ;<br />
685 beta = r e [ 2 ] ;<br />
686 i f ( r e [ 0 ] == 1) {<br />
687 b [ c ] [ r +1] = 2 ;<br />
688 b [ c +1][ r +1] = 2 ;<br />
689 r e t u r n ( r e [ 3 ] ) ;<br />
690 }<br />
691 b [ c ] [ r +1] = 2 ;<br />
692 b [ c +1][ r +1] = 2 ;<br />
693 }<br />
694 }<br />
695 i f ( c > 0) {<br />
696 i f ( fb [ c −1][ r +1] == 0) {<br />
697 i n t [ ] r e ;<br />
698 b [ c ] [ r +1] = 1 ;<br />
699 b [ c −1][ r +1] = 0 ;<br />
700 r e = placePieceMin ( b , d , n ,<br />
c , r +1, c −1, r +1,<br />
alpha , beta ) ;<br />
701 alpha = r e [ 1 ] ;<br />
702 beta = r e [ 2 ] ;<br />
703 i f ( r e [ 0 ] == 1) {<br />
704 b [ c ] [ r +1] = 2 ;<br />
705 b [ c −1][ r +1] = 2 ;<br />
706 r e t u r n ( r e [ 3 ] ) ;<br />
707 }<br />
708 b [ c ] [ r +1] = 0 ;<br />
709 b [ c −1][ r +1] = 1 ;<br />
710 r e = placePieceMin ( b , d , n ,<br />
c −1, r +1, c , r +1,<br />
alpha , beta ) ;<br />
711 alpha = r e [ 1 ] ;<br />
712 beta = r e [ 2 ] ;<br />
713 i f ( r e [ 0 ] == 1) {<br />
714 b [ c ] [ r +1] = 2 ;<br />
715 b [ c −1][ r +1] = 2 ;<br />
716 r e t u r n ( r e [ 3 ] ) ;<br />
717 }<br />
718 b [ c ] [ r +1] = 2 ;<br />
719 b [ c −1][ r +1] = 2 ;<br />
720 }<br />
721 }<br />
722 i f ( r < tModel . noRows−2){<br />
723 i f ( fb [ c ] [ r +2] == 0) {<br />
724 i n t [ ] r e ;<br />
725 b [ c ] [ r +1] = 1 ;<br />
726 b [ c ] [ r +2] = 0 ;<br />
727 r e = placePieceMin ( b , d , n ,<br />
c , r +1, c , r +2, alpha ,<br />
beta ) ;<br />
728 alpha = r e [ 1 ] ;
122 Bilag A<br />
729 beta = r e [ 2 ] ;<br />
730 i f ( r e [ 0 ] == 1) {<br />
731 b [ c ] [ r +1] = 2 ;<br />
732 b [ c ] [ r +2] = 2 ;<br />
733 r e t u r n ( r e [ 3 ] ) ;<br />
734 }<br />
735 b [ c ] [ r +1] = 0 ;<br />
736 b [ c ] [ r +2] = 1 ;<br />
737 r e = placePieceMin ( b , d , n ,<br />
c , r +2, c , r +1, alpha ,<br />
beta ) ;<br />
738 alpha = r e [ 1 ] ;<br />
739 beta = r e [ 2 ] ;<br />
740 i f ( r e [ 0 ] == 1) {<br />
741 b [ c ] [ r +1] = 2 ;<br />
742 b [ c ] [ r +2] = 2 ;<br />
743 r e t u r n ( r e [ 3 ] ) ;<br />
744 }<br />
745 b [ c ] [ r +1] = 2 ;<br />
746 b [ c ] [ r +2] = 2 ;<br />
747 }<br />
748 }<br />
749 }<br />
750 }<br />
751 // Nord<br />
752 i f ( r > 0) {<br />
753 i f ( fb [ c ] [ r −1] == 0) {<br />
754 i f ( c > 0) {<br />
755 i f ( fb [ c −1][ r −1] == 0) {<br />
756 i n t [ ] r e ;<br />
757 b [ c ] [ r −1] = 1 ;<br />
758 b [ c −1][ r −1] = 0 ;<br />
759 r e = placePieceMin ( b , d , n ,<br />
c , r −1, c −1, r −1,<br />
alpha , beta ) ;<br />
760 alpha = r e [ 1 ] ;<br />
761 beta = r e [ 2 ] ;<br />
762 i f ( r e [ 0 ] == 1) {<br />
763 b [ c ] [ r −1] = 2 ;<br />
764 b [ c −1][ r −1] = 2 ;<br />
765 r e t u r n ( r e [ 3 ] ) ;<br />
766 }<br />
767 b [ c ] [ r −1] = 0 ;<br />
768 b [ c −1][ r −1] = 1 ;<br />
769 r e = placePieceMin ( b , d , n ,<br />
c −1, r −1, c , r −1,<br />
alpha , beta ) ;<br />
770 alpha = r e [ 1 ] ;<br />
771 beta = r e [ 2 ] ;<br />
772 i f ( r e [ 0 ] == 1) {<br />
773 b [ c ] [ r −1] = 2 ;<br />
774 b [ c −1][ r −1] = 2 ;<br />
775 r e t u r n ( r e [ 3 ] ) ;<br />
776 }<br />
777 b [ c ] [ r −1] = 2 ;
A.2 AI<strong>Taiji</strong>Growth.java 123<br />
778 b [ c −1][ r −1] = 2 ;<br />
779 }<br />
780 }<br />
781 i f ( c < tModel . noCols −1){<br />
782 i f ( fb [ c +1][ r −1] == 0) {<br />
783 i n t [ ] r e ;<br />
784 b [ c ] [ r −1] = 1 ;<br />
785 b [ c +1][ r −1] = 0 ;<br />
786 r e = placePieceMin ( b , d , n ,<br />
c , r −1, c +1, r −1,<br />
alpha , beta ) ;<br />
787 alpha = r e [ 1 ] ;<br />
788 beta = r e [ 2 ] ;<br />
789 i f ( r e [ 0 ] == 1) {<br />
790 b [ c ] [ r −1] = 2 ;<br />
791 b [ c +1][ r −1] = 2 ;<br />
792 r e t u r n ( r e [ 3 ] ) ;<br />
793 }<br />
794 b [ c ] [ r −1] = 0 ;<br />
795 b [ c +1][ r −1] = 1 ;<br />
796 r e = placePieceMin ( b , d , n ,<br />
c +1, r −1, c , r −1,<br />
alpha , beta ) ;<br />
797 alpha = r e [ 1 ] ;<br />
798 beta = r e [ 2 ] ;<br />
799 i f ( r e [ 0 ] == 1) {<br />
800 b [ c ] [ r −1] = 2 ;<br />
801 b [ c +1][ r −1] = 2 ;<br />
802 r e t u r n ( r e [ 3 ] ) ;<br />
803 }<br />
804 b [ c ] [ r −1] = 2 ;<br />
805 b [ c +1][ r −1] = 2 ;<br />
806 }<br />
807 }<br />
808 i f ( r > 1) {<br />
809 i f ( fb [ c ] [ r −2] == 0) {<br />
810 i n t [ ] r e ;<br />
811 b [ c ] [ r −1] = 1 ;<br />
812 b [ c ] [ r −2] = 0 ;<br />
813 r e = placePieceMin ( b , d , n ,<br />
c , r −1, c , r −2, alpha ,<br />
beta ) ;<br />
814 alpha = r e [ 1 ] ;<br />
815 beta = r e [ 2 ] ;<br />
816 i f ( r e [ 0 ] == 1) {<br />
817 b [ c ] [ r −1] = 2 ;<br />
818 b [ c ] [ r −2] = 2 ;<br />
819 r e t u r n ( r e [ 3 ] ) ;<br />
820 }<br />
821 b [ c ] [ r −1] = 0 ;<br />
822 b [ c ] [ r −2] = 1 ;<br />
823 r e = placePieceMin ( b , d , n ,<br />
c , r −2, c , r −1, alpha ,<br />
beta ) ;<br />
824 alpha = r e [ 1 ] ;
124 Bilag A<br />
825 beta = r e [ 2 ] ;<br />
826 i f ( r e [ 0 ] == 1) {<br />
827 b [ c ] [ r −1] = 2 ;<br />
828 b [ c ] [ r −2] = 2 ;<br />
829 r e t u r n ( r e [ 3 ] ) ;<br />
830 }<br />
831 b [ c ] [ r −1] = 2 ;<br />
832 b [ c ] [ r −2] = 2 ;<br />
833 }<br />
834 }<br />
835 }<br />
836 }<br />
837 }<br />
838 }<br />
839 }<br />
840 r e t u r n ( n . a ) ;<br />
841 }<br />
842 }<br />
843<br />
844<br />
845 // haandtere p l a c e r i n g e n a f b r i k k e r f o r max ( ) , c h e c k e r om de<br />
a l l e r e d e e k s i s t e r e r , haandtere alpha beta pruning<br />
846 p r i v a t e i n t [ ] placePieceMax ( i n t [ ] [ ] b , i n t d , Node n , i n t wC,<br />
i n t wR, i n t bC , i n t bR, i n t alpha , i n t beta ) {<br />
847 i n t [ ] p = new i n t [ 3 ] ;<br />
848 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
849 i n t [ ] r e = new i n t [ 4 ] ; // r e [0]= 1 break , r e [1]= alpha , r e<br />
[2]= beta , r e [3]= n . a<br />
850<br />
851 i f ( p [ 2 ] >= 0) {<br />
852 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
853 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
854 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
855 i f ( n . a < v )<br />
856 n . a = v ;<br />
857 i f ( n . a > beta ) {<br />
858 r e [ 0 ] = 0 ; // 1 = alpha beta pruning<br />
s l a a e t t i l , 0 = s l a a e t f r a (<br />
s l a a e t f r a da den g i v e r<br />
problemer )<br />
859 r e [1]= alpha ;<br />
860 r e [2]= beta ;<br />
861 r e [3]= n . a ;<br />
862 r e t u r n ( r e ) ;<br />
863 }<br />
864 i f ( alpha < n . a )<br />
865 alpha = n . a ;<br />
866<br />
867 }<br />
868 i f ( p [ 2 ] == −1){<br />
869 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
870 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode (wC, wR, bC , bR, n ) )
A.2 AI<strong>Taiji</strong>Growth.java 125<br />
) ;<br />
871 count++;<br />
872 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
873 i f ( n . a < v )<br />
874 n . a = v ;<br />
875 i f ( n . a > beta ) {<br />
876 r e [ 0 ] = 0 ; // 1 = alpha beta pruning<br />
s l a a e t t i l , 0 = s l a a e t f r a (<br />
s l a a e t f r a da den g i v e r<br />
problemer )<br />
877 r e [1]= alpha ;<br />
878 r e [2]= beta ;<br />
879 r e [3]= n . a ;<br />
880 r e t u r n ( r e ) ;<br />
881 }<br />
882 i f ( alpha < n . a )<br />
883 alpha = n . a ;<br />
884<br />
885 }<br />
886 r e t u r n ( r e ) ;<br />
887 }<br />
888<br />
889 // haandtere p l a c e r i n g e n a f b r i k k e r f o r min ( ) , c h e c k e r om de<br />
a l l e r e d e e k s i s t e r e r , haandtere alpha beta pruning<br />
890 p r i v a t e i n t [ ] placePieceMin ( i n t [ ] [ ] b , i n t d , Node n , i n t wC,<br />
i n t wR, i n t bC , i n t bR, i n t alpha , i n t beta ) {<br />
891 i n t [ ] p = new i n t [ 3 ] ;<br />
892 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
893 i n t [ ] r e = new i n t [ 4 ] ; // r e [0]= 1 break , r e [1]= alpha , r e<br />
[2]= beta , r e [3]= n . a<br />
894<br />
895 i f ( p [ 2 ] >= 0) {<br />
896 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
897 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) ) ;<br />
898 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) , alpha , beta , 1 ) ;<br />
899 i f ( n . a > v )<br />
900 n . a = v ;<br />
901 i f ( n . a < alpha ) {<br />
902 r e [ 0 ] = 0 ; // 1 = alpha beta pruning s l a a e t t i l , 0 =<br />
s l a a e t f r a ( s l a a e t f r a da den g i v e r problemer )<br />
903 r e [1]= alpha ;<br />
904 r e [2]= beta ;<br />
905 r e [3]= n . a ;<br />
906 r e t u r n ( r e ) ;<br />
907 }<br />
908 i f ( beta > n . a )<br />
909 beta = n . a ;<br />
910 }<br />
911 i f ( p [ 2 ] == −1){<br />
912 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
913 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode . createChildNode (<br />
wC, wR, bC , bR, n ) ) ) ;<br />
914 count++;<br />
915 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) , alpha , beta , 0 ) ;
126 Bilag A<br />
916 i f ( n . a > v )<br />
917 n . a = v ; // 1 = alpha beta pruning s l a a e t t i l , 0 =<br />
s l a a e t f r a ( s l a a e t f r a da denne g i v e r problemer<br />
)<br />
918 i f ( n . a < alpha ) {<br />
919 r e [ 0 ] = 0 ;<br />
920 r e [1]= alpha ;<br />
921 r e [2]= beta ;<br />
922 r e [3]= n . a ;<br />
923 r e t u r n ( r e ) ;<br />
924 }<br />
925 i f ( beta > n . a )<br />
926 beta = n . a ;<br />
927 }<br />
928 r e t u r n ( r e ) ;<br />
929 }<br />
930<br />
931<br />
932<br />
933<br />
934<br />
935<br />
936 // s a e t t e r s c o r e n f o r en node t i l lower bound<br />
937 p r i v a t e Node setScoreMin ( Node n ) {<br />
938 n . a = −tModel . maxScore ;<br />
939 r e t u r n ( n ) ;<br />
940 }<br />
941 // s a e t t e r s c o r e n f o r en node t i l e t upper bound<br />
942 p r i v a t e Node setScoreMax ( Node n ) {<br />
943 n . a = tModel . maxScore ;<br />
944 r e t u r n ( n ) ;<br />
945 }<br />
946<br />
947<br />
948<br />
949 // u d s k r i v e r f i g B o a r d e t f o r 4x4 e l l e r 9x9 p l a d e r<br />
950 p r i v a t e void printFB ( i n t [ ] [ ] fb ) {<br />
951 i f ( tModel . noCols > 8 && tModel . noRows > 8)<br />
952 printFB9x9 ( fb ) ;<br />
953 e l s e<br />
954 printFB4x4 ( fb ) ;<br />
955 }<br />
956<br />
957 // u d s k r i v e r f i g B o a r d e t f o r 4x4 p l a d e r<br />
958 p r i v a t e void printFB4x4 ( i n t [ ] [ ] fb ) {<br />
959 System . out . p r i n t l n (” P r i n t FB ”+fb ) ;<br />
960 System . out . p r i n t l n ( fb [ 0 ] [ 0 ] + ” ”+fb [ 1 ] [ 0 ] + ” ”+fb<br />
[ 2 ] [ 0 ] + ” ”+fb [ 3 ] [ 0 ] ) ;<br />
961 System . out . p r i n t l n ( fb [ 0 ] [ 1 ] + ” ”+fb [ 1 ] [ 1 ] + ” ”+fb<br />
[ 2 ] [ 1 ] + ” ”+fb [ 3 ] [ 1 ] ) ;<br />
962 System . out . p r i n t l n ( fb [ 0 ] [ 2 ] + ” ”+fb [ 1 ] [ 2 ] + ” ”+fb<br />
[ 2 ] [ 2 ] + ” ”+fb [ 3 ] [ 2 ] ) ;<br />
963 System . out . p r i n t l n ( fb [ 0 ] [ 3 ] + ” ”+fb [ 1 ] [ 3 ] + ” ”+fb<br />
[ 2 ] [ 3 ] + ” ”+fb [ 3 ] [ 3 ] ) ;<br />
964 System . out . p r i n t l n ( ) ;
A.2 AI<strong>Taiji</strong>Growth.java 127<br />
965 }<br />
966<br />
967 // u d s k r i v e r f i g B o a r d e t f o r 9x9 p l a d e r<br />
968 p r i v a t e void printFB9x9 ( i n t [ ] [ ] fb ) {<br />
969 System . out . p r i n t l n (” P r i n t FB ”+fb ) ;<br />
970 System . out . p r i n t l n ( fb [ 0 ] [ 0 ] + ” ”+fb [ 1 ] [ 0 ] + ” ”+fb<br />
[ 2 ] [ 0 ] + ” ”+fb [ 3 ] [ 0 ] + ” ”+fb [ 4 ] [ 0 ] + ” ”+fb [ 5 ] [ 0 ] + ”<br />
”+fb [ 6 ] [ 0 ] + ” ”+fb [ 7 ] [ 0 ] + ” ”+fb [ 8 ] [ 0 ] ) ;<br />
971 System . out . p r i n t l n ( fb [ 0 ] [ 1 ] + ” ”+fb [ 1 ] [ 1 ] + ” ”+fb<br />
[ 2 ] [ 1 ] + ” ”+fb [ 3 ] [ 1 ] + ” ”+fb [ 4 ] [ 1 ] + ” ”+fb [ 5 ] [ 1 ] + ”<br />
”+fb [ 6 ] [ 1 ] + ” ”+fb [ 7 ] [ 1 ] + ” ”+fb [ 8 ] [ 1 ] ) ;<br />
972 System . out . p r i n t l n ( fb [ 0 ] [ 2 ] + ” ”+fb [ 1 ] [ 2 ] + ” ”+fb<br />
[ 2 ] [ 2 ] + ” ”+fb [ 3 ] [ 2 ] + ” ”+fb [ 4 ] [ 2 ] + ” ”+fb [ 5 ] [ 2 ] + ”<br />
”+fb [ 6 ] [ 2 ] + ” ”+fb [ 7 ] [ 2 ] + ” ”+fb [ 8 ] [ 2 ] ) ;<br />
973 System . out . p r i n t l n ( fb [ 0 ] [ 3 ] + ” ”+fb [ 1 ] [ 3 ] + ” ”+fb<br />
[ 2 ] [ 3 ] + ” ”+fb [ 3 ] [ 3 ] + ” ”+fb [ 4 ] [ 3 ] + ” ”+fb [ 5 ] [ 3 ] + ”<br />
”+fb [ 6 ] [ 3 ] + ” ”+fb [ 7 ] [ 3 ] + ” ”+fb [ 8 ] [ 3 ] ) ;<br />
974 System . out . p r i n t l n ( fb [ 0 ] [ 4 ] + ” ”+fb [ 1 ] [ 4 ] + ” ”+fb<br />
[ 2 ] [ 4 ] + ” ”+fb [ 3 ] [ 4 ] + ” ”+fb [ 4 ] [ 4 ] + ” ”+fb [ 5 ] [ 4 ] + ”<br />
”+fb [ 6 ] [ 4 ] + ” ”+fb [ 7 ] [ 4 ] + ” ”+fb [ 8 ] [ 4 ] ) ;<br />
975 System . out . p r i n t l n ( fb [ 0 ] [ 5 ] + ” ”+fb [ 1 ] [ 5 ] + ” ”+fb<br />
[ 2 ] [ 5 ] + ” ”+fb [ 3 ] [ 5 ] + ” ”+fb [ 4 ] [ 5 ] + ” ”+fb [ 5 ] [ 5 ] + ”<br />
”+fb [ 6 ] [ 5 ] + ” ”+fb [ 7 ] [ 5 ] + ” ”+fb [ 8 ] [ 5 ] ) ;<br />
976 System . out . p r i n t l n ( fb [ 0 ] [ 6 ] + ” ”+fb [ 1 ] [ 6 ] + ” ”+fb<br />
[ 2 ] [ 6 ] + ” ”+fb [ 3 ] [ 6 ] + ” ”+fb [ 4 ] [ 6 ] + ” ”+fb [ 5 ] [ 6 ] + ”<br />
”+fb [ 6 ] [ 6 ] + ” ”+fb [ 7 ] [ 6 ] + ” ”+fb [ 8 ] [ 6 ] ) ;<br />
977 System . out . p r i n t l n ( fb [ 0 ] [ 7 ] + ” ”+fb [ 1 ] [ 7 ] + ” ”+fb<br />
[ 2 ] [ 7 ] + ” ”+fb [ 3 ] [ 7 ] + ” ”+fb [ 4 ] [ 7 ] + ” ”+fb [ 5 ] [ 7 ] + ”<br />
”+fb [ 6 ] [ 7 ] + ” ”+fb [ 7 ] [ 7 ] + ” ”+fb [ 8 ] [ 7 ] ) ;<br />
978 System . out . p r i n t l n ( fb [ 0 ] [ 8 ] + ” ”+fb [ 1 ] [ 8 ] + ” ”+fb<br />
[ 2 ] [ 8 ] + ” ”+fb [ 3 ] [ 8 ] + ” ”+fb [ 4 ] [ 8 ] + ” ”+fb [ 5 ] [ 8 ] + ”<br />
”+fb [ 6 ] [ 8 ] + ” ”+fb [ 7 ] [ 8 ] + ” ”+fb [ 8 ] [ 8 ] ) ;<br />
979 System . out . p r i n t l n ( ) ;<br />
980 }<br />
981<br />
982 // haandtere Growth AI ’ ens k o e r s e l og r e t u r n e r e det fundne<br />
t r a e k<br />
983 p u b l i c Node returnMove ( boolean b ) {<br />
984 i f ( tModel . currentTurn == 1) {<br />
985 i f ( b == f a l s e ) {<br />
986 tNode = new Node ( ) ;<br />
987 Root = tNode . createNode ( tModel . currentTurn , tModel )<br />
;<br />
988 Root . wc=0; // tModel . noCols / 2 ; // f o r at s a e t t e<br />
f o e r s t e b r i k i midten i s t e d e t f o r i h j o e r n e t<br />
989 Root . wr=1; // tModel . noCols / 2 ; // f o r at s a e t t e<br />
f o e r s t e b r i k i midten i s t e d e t f o r i h j o e r n e t<br />
990 Root . bc=Root . wc ;<br />
991 Root . br=Root . wr−1;<br />
992 r e t u r n ( Root ) ;<br />
993 }<br />
994 i f ( b == t r u e ) {<br />
995 tNode = new Node ( ) ;<br />
996 Root = tNode . createNode ( tModel . currentTurn , tModel )<br />
;
128 Bilag A<br />
997 Root . wc=0; // tModel . noCols / 2 ; // f o r at s a e t t e<br />
f o e r s t e b r i k i midten i s t e d e t f o r i h j o e r n e t<br />
998 Root . wr=0; // tModel . noCols / 2 ; // f o r at s a e t t e<br />
f o e r s t e b r i k i midten i s t e d e t f o r i h j o e r n e t<br />
999 Root . bc=Root . wc ;<br />
1000 Root . br=Root . wr+1;<br />
1001 r e t u r n ( Root ) ;<br />
1002 }<br />
1003 }<br />
1004 Growth ( ) ;<br />
1005<br />
1006 i f ( b )<br />
1007 min ( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;<br />
1008 i f ( ! b )<br />
1009 max( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;<br />
1010<br />
1011 Random randomVal = new Random ( ) ;<br />
1012 Node n ;<br />
1013 ArrayList move = new ArrayList () ;<br />
1014 i n t wC,wR, bC , bR, ran ;<br />
1015 n = Root . c h i l d r e n . get ( 0 ) ;<br />
1016 // tModel . t P r i n t . printNode ( Root ) ;<br />
1017 // tModel . t P r i n t . p r i n t C h i l d r e n ( Root ) ;<br />
1018 // System . out . p r i n t l n (” Growth − r e t u r n move Root . s i z e=”+Root<br />
. c h i l d r e n . s i z e ( ) ) ;<br />
1019 i f ( Root . c h i l d r e n . s i z e ( ) > 1) {<br />
1020 i f ( b ) {<br />
1021 f o r ( i n t i =0; i Root . c h i l d r e n . get ( i ) . a ) {<br />
1023 n=Root . c h i l d r e n . get ( i ) ;<br />
1024 }<br />
1025 }<br />
1026 }<br />
1027 i f ( ! b ) {<br />
1028 f o r ( i n t i =0; i
A.2 AI<strong>Taiji</strong>Growth.java 129<br />
1044 wC = n . wc ;<br />
1045 wR = n . wr ;<br />
1046 bC = n . bc ;<br />
1047 bR = n . br ;<br />
1048 n . nodeBoard [wC ] [ wR]=2;<br />
1049 n . nodeBoard [ bC ] [ bR]=2;<br />
1050 // tModel . t P r i n t . printNode ( n ) ;<br />
1051<br />
1052 // vender det v a l g t e t r a e k saa det matcher s p i l l e t s<br />
igangvaerende t r a e k .<br />
1053 i n t mr = tModel . tBoard . compareBoardsInt ( n . nodeBoard , tModel<br />
. tBoard . board [ tModel . currentTurn ] ) ;<br />
1054 System . out . p r i n t l n (” Growth − Return move mr=”+mr) ;<br />
1055 i f (mr == 1) {<br />
1056 r e t u r n ( n ) ;<br />
1057 }<br />
1058 i f (mr == 2) {<br />
1059 n . br = tModel . noRows−1 − bR ;<br />
1060 n . wr = tModel . noRows−1 − wR;<br />
1061 r e t u r n ( n ) ;<br />
1062 }<br />
1063 i f (mr == 3) {<br />
1064 n . bc = tModel . noCols −1 − bC ;<br />
1065 n . wc = tModel . noCols −1 − wC;<br />
1066 r e t u r n ( n ) ;<br />
1067 }<br />
1068 i f (mr == 4) {<br />
1069 n . bc = tModel . noCols −1 − bC ;<br />
1070 n . wc = tModel . noCols −1 − wC;<br />
1071 n . br = tModel . noRows−1 − bR ;<br />
1072 n . wr = tModel . noRows−1 − wR;<br />
1073 r e t u r n ( n ) ;<br />
1074 }<br />
1075 i f (mr == 5) {<br />
1076 n . bc = bR ;<br />
1077 n . wc = wR;<br />
1078 n . br = bC ;<br />
1079 n . wr = wC;<br />
1080 r e t u r n ( n ) ;<br />
1081 }<br />
1082 i f (mr == 6) {<br />
1083 n . bc = tModel . noRows−1 − bR ;<br />
1084 n . wc = tModel . noRows−1 − wR;<br />
1085 n . br = bC ;<br />
1086 n . wr = wC;<br />
1087 r e t u r n ( n ) ;<br />
1088 }<br />
1089 i f (mr == 7) {<br />
1090 n . bc = bR ;<br />
1091 n . wc = wR;<br />
1092 n . br = tModel . noCols −1 − bC ;<br />
1093 n . wr = tModel . noCols −1 − wC;<br />
1094 r e t u r n ( n ) ;<br />
1095 }<br />
1096 i f (mr == 8) {
130 Bilag A<br />
1097 n . bc = tModel . noRows−1 − bR ;<br />
1098 n . wc = tModel . noRows−1 − wR;<br />
1099 n . br = tModel . noCols −1 − bC ;<br />
1100 n . wr = tModel . noCols −1 − wC;<br />
1101 r e t u r n ( n ) ;<br />
1102 }<br />
1103 r e t u r n ( n ) ;<br />
1104 }<br />
1105<br />
1106 }<br />
A.3 AI<strong>Taiji</strong>LocalAreaAB.java<br />
1 import java . u t i l . Random ;<br />
2 import java . u t i l . ArrayList ;<br />
3<br />
4 p u b l i c c l a s s AI<strong>Taiji</strong>LocalAreaAB {<br />
5<br />
6 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
7 p u b l i c Node tNode ;<br />
8 p u b l i c i n t count ; // f o r at t e s t e hvor mange noder der l a v e s .<br />
9 p u b l i c i n t maxDepth ;<br />
10 p r i v a t e ArrayList [ ] [ ] nodes ; // i n d e h o l d e r a l l e noderne i<br />
a r r a y l i s t s e f t e r g e n e r a t i o n og hash v a e r d i .<br />
11 p r i v a t e i n t maxD; // den maximale dybde f o r t r a e e t .<br />
12 p r i v a t e i n t maxH ; // den maximale Hash v a e r d i<br />
13 p r i v a t e Node Root ; // Traeets rod .<br />
14 p r i v a t e i n t searchD ; // Search depth , muligheden f o r at s a e t t e<br />
en maximal s o e g e dybde<br />
15 p r i v a t e i n t c o l S t a r t , colEnd , rowStart , rowEnd ;<br />
16<br />
17<br />
18 p u b l i c AI<strong>Taiji</strong>LocalAreaAB ( <strong>Taiji</strong>Model m) {<br />
19 t h i s . tModel = m;<br />
20 }<br />
21<br />
22 p u b l i c void LocalAreaAB ( ) {<br />
23 tNode = new Node ( ) ;<br />
24 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;<br />
25 count = 1 ;<br />
26 maxD = tModel . maxTurnsLeft ( ) ;<br />
27 searchD = maxD;<br />
28 maxH = tModel . tHash . getMaxH3 ( ) ;<br />
29 nodes = new ArrayList [maxD ] [ maxH+1];<br />
30 f o r ( i n t i =0; i
A.3 AI<strong>Taiji</strong>LocalAreaAB.java 131<br />
39 }<br />
40<br />
41 // s a e t t e r c o l S t a r t , colEnd , rowStart og rowEnd s a a l e d e s at der<br />
kan k o e r e s minimax paa e t 4x4 omraade a f b r a e t t e t .<br />
42 p r i v a t e void setAround ( i n t [ ] t ) {<br />
43 i f ( t [ 0 ] < t [ 2 ] ) {<br />
44 c o l S t a r t = t [ 0 ] − 1 ;<br />
45 colEnd = t [ 2 ] + 1 ;<br />
46 }<br />
47 i f ( t [ 0 ] > t [ 2 ] ) {<br />
48 c o l S t a r t = t [ 2 ] − 1 ;<br />
49 colEnd = t [ 0 ] + 1 ;<br />
50 }<br />
51 i f ( t [ 0 ] == t [ 2 ] ) {<br />
52 c o l S t a r t = t [ 0 ] − 1 ;<br />
53 colEnd = t [ 0 ] + 2 ; // +2 f o r 4x4 , +1 f o r 3x4<br />
54 }<br />
55 // f l y t t e r omraadet h v i s f o r r i g e t r a e k l i g g e r opad kanten<br />
56 i f ( c o l S t a r t < 0) {<br />
57 i f ( colEnd − c o l S t a r t == 2 && t [0]== t [ 2 ] )<br />
58 colEnd = 2 ; // 3x4<br />
59 e l s e<br />
60 colEnd = 3 ; // 4x4<br />
61 c o l S t a r t = 0 ;<br />
62 }<br />
63<br />
64 // f l y t t e r omraadet h v i s f o r r i g e t r a e k l i g g e r opad kanten<br />
65 i f ( colEnd >= tModel . noCols ) {<br />
66 i f ( colEnd − c o l S t a r t == 2 && t [0]== t [ 2 ] )<br />
67 c o l S t a r t = tModel . noCols −3; // 3x4<br />
68 e l s e<br />
69 c o l S t a r t = tModel . noCols −4; // 4x4<br />
70 colEnd = tModel . noCols −1;<br />
71<br />
72 }<br />
73<br />
74 i f ( t [ 1 ] < t [ 3 ] ) {<br />
75 rowStart = t [ 1 ] − 1 ;<br />
76 rowEnd = t [ 3 ] + 1 ;<br />
77 }<br />
78 i f ( t [ 1 ] > t [ 3 ] ) {<br />
79 rowStart = t [ 3 ] − 1 ;<br />
80 rowEnd = t [ 1 ] + 1 ;<br />
81 }<br />
82 i f ( t [ 1 ] == t [ 3 ] ) {<br />
83 rowStart = t [ 1 ] − 1 ;<br />
84 rowEnd = t [ 1 ] + 2 ; // +2 f o r 4x4 , +1 f o r 4x3<br />
85 }<br />
86 i f ( rowStart < 0) {<br />
87 i f ( rowEnd − rowStart == 2 && t [1]== t [ 3 ] )<br />
88 rowEnd = 2 ; // 4x3<br />
89 e l s e<br />
90 rowEnd = 3 ; // 4x4<br />
91 rowStart = 0 ;<br />
92 }
132 Bilag A<br />
93 i f ( rowEnd >= tModel . noRows ) {<br />
94 i f ( rowEnd − rowStart == 2 && t [1]== t [ 3 ] )<br />
95 rowStart = tModel . noRows−3; // 4x3<br />
96 e l s e<br />
97 rowStart = tModel . noRows−4; // 4x4<br />
98 rowEnd = tModel . noRows−1;<br />
99 }<br />
100 }<br />
101<br />
102 // s a e t t e r soegedybden<br />
103 p u b l i c void setSearchDepth ( i n t d ) {<br />
104 searchD = d ;<br />
105 }<br />
106<br />
107 // c h e c k e r om der a l l e r e d e e r e t saadant b r a e t . Returnerer<br />
c o r d i n a t e r n e f o r den node , h v i s der e r .<br />
108 p r i v a t e i n t [ ] c h e c k B o a r d I n d i v i d u a l i t y ( i n t [ ] [ ] b , i n t d ) {<br />
109 i n t [ ] p = new i n t [ 3 ] ;<br />
110 i n t h = tModel . tHash . hashFunction3 ( b ) ;<br />
111 p [0]= d ;<br />
112 p [1]= h ;<br />
113 p[2]= −1;<br />
114 f o r ( i n t i = 0 ; i = searchD | | ! tModel . movesLeftN ( n ) ) {<br />
128 n . a = tModel . fMap . c a l D i f ( n . nodeBoard , tModel . noCols ,<br />
tModel . noRows ) ;<br />
129 r e t u r n ( n . a ) ;<br />
130 }<br />
131 e l s e {<br />
132 i f ( ex == 1) {<br />
133 i f ( n . a >= beta )<br />
134 r e t u r n ( n . a ) ;<br />
135 }<br />
136 n . a = −tModel . maxScore ;<br />
137 i n t [ ] [ ] b = n . nodeBoard ;<br />
138 i n t d = n . d ;<br />
139 f o r ( i n t c=c o l S t a r t ; c
A.3 AI<strong>Taiji</strong>LocalAreaAB.java 133<br />
143 b [ c ] [ r +1] = 0 ;<br />
144 i n t [ ] p = new i n t [ 3 ] ;<br />
145 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
146 i f ( p [ 2 ] >= 0) {<br />
147 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
148 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
149 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
150 i f ( n . a < v )<br />
151 n . a = v ;<br />
152 i f ( n . a > beta ) {<br />
153 b [ c ] [ r ] = 2 ;<br />
154 b [ c ] [ r +1] = 2 ;<br />
155 r e t u r n ( n . a ) ;<br />
156 }<br />
157 i f ( alpha < n . a )<br />
158 alpha = n . a ;<br />
159<br />
160 }<br />
161 i f ( p [ 2 ] == −1){<br />
162 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
163 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, n ) ) ) ;<br />
164 count++;<br />
165 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
166 i f ( n . a < v )<br />
167 n . a = v ;<br />
168 i f ( n . a > beta ) {<br />
169 b [ c ] [ r ] = 2 ;<br />
170 b [ c ] [ r +1] = 2 ;<br />
171 r e t u r n ( n . a ) ;<br />
172 }<br />
173 i f ( alpha < n . a )<br />
174 alpha = n . a ;<br />
175<br />
176 }<br />
177 b [ c ] [ r ] = 0 ;<br />
178 b [ c ] [ r +1] = 1 ;<br />
179 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
180 i f ( p [ 2 ] >= 0) {<br />
181 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
182 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
183 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
184 i f ( n . a < v )<br />
185 n . a = v ;<br />
186 i f ( n . a > beta ) {<br />
187 b [ c ] [ r ] = 2 ;<br />
188 b [ c ] [ r +1] = 2 ;<br />
189 r e t u r n ( n . a ) ;<br />
190 }<br />
191 i f ( alpha < n . a )
134 Bilag A<br />
192 alpha = n . a ;<br />
193 }<br />
194 i f ( p [ 2 ] == −1){<br />
195 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
196 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , n ) ) ) ;<br />
197 count++;<br />
198 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
199 i f ( n . a < v )<br />
200 n . a = v ;<br />
201 i f ( n . a > beta ) {<br />
202 b [ c ] [ r ] = 2 ;<br />
203 b [ c ] [ r +1] = 2 ;<br />
204 r e t u r n ( n . a ) ;<br />
205 }<br />
206 i f ( alpha < n . a )<br />
207 alpha = n . a ;<br />
208 }<br />
209<br />
210 b [ c ] [ r ] = 2 ;<br />
211 b [ c ] [ r +1] = 2 ;<br />
212 }<br />
213 }<br />
214 }<br />
215<br />
216 f o r ( i n t c=c o l S t a r t ; c beta ) {<br />
230 b [ c ] [ r ] = 2 ;<br />
231 b [ c +1][ r ] = 2 ;<br />
232 r e t u r n ( n . a ) ;<br />
233 }<br />
234 i f ( alpha < n . a )<br />
235 alpha = n . a ;<br />
236 }<br />
237 i f ( p [ 2 ] == −1){<br />
238 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
239 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , n ) ) ) ;<br />
240 count++;
A.3 AI<strong>Taiji</strong>LocalAreaAB.java 135<br />
241 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
242 i f ( n . a < v )<br />
243 n . a = v ;<br />
244 i f ( n . a > beta ) {<br />
245 b [ c ] [ r ] = 2 ;<br />
246 b [ c +1][ r ] = 2 ;<br />
247 r e t u r n ( n . a ) ;<br />
248 }<br />
249 i f ( alpha < n . a )<br />
250 alpha = n . a ;<br />
251 }<br />
252 b [ c ] [ r ] = 0 ;<br />
253 b [ c +1][ r ] = 1 ;<br />
254 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
255 i f ( p [ 2 ] >= 0) {<br />
256 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
257 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
258 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
259 i f ( n . a < v )<br />
260 n . a = v ;<br />
261 i f ( n . a > beta ) {<br />
262 b [ c ] [ r ] = 2 ;<br />
263 b [ c +1][ r ] = 2 ;<br />
264 r e t u r n ( n . a ) ;<br />
265 }<br />
266 i f ( alpha < n . a )<br />
267 alpha = n . a ;<br />
268 }<br />
269 i f ( p [ 2 ] == −1){<br />
270 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
271 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , n ) ) ) ;<br />
272 count++;<br />
273 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
274 i f ( n . a < v )<br />
275 n . a = v ;<br />
276 i f ( n . a > beta ) {<br />
277 b [ c ] [ r ] = 2 ;<br />
278 b [ c +1][ r ] = 2 ;<br />
279 r e t u r n ( n . a ) ;<br />
280 }<br />
281 i f ( alpha < n . a )<br />
282 alpha = n . a ;<br />
283 }<br />
284 b [ c ] [ r ] = 2 ;<br />
285 b [ c +1][ r ] = 2 ;<br />
286 }<br />
287 }<br />
288 }<br />
289 r e t u r n ( n . a ) ;<br />
290 }
136 Bilag A<br />
291 }<br />
292<br />
293 // Min−funktionen , l a v e t t i l holde s i g inden f o r e t 4x4 a r e a l<br />
paa b r a e t t e t<br />
294 p r i v a t e i n t min ( Node n , i n t alpha , i n t beta , i n t ex ) {<br />
295 i f ( n . d >= searchD | | ! tModel . movesLeftN ( n ) ) {<br />
296 n . a = tModel . fMap . c a l D i f ( n . nodeBoard , tModel . noCols ,<br />
tModel . noRows ) ;<br />
297 r e t u r n ( n . a ) ;<br />
298 }<br />
299 e l s e {<br />
300 n . a = tModel . maxScore ;<br />
301 i n t [ ] [ ] b = n . nodeBoard ;<br />
302 i n t d = n . d ;<br />
303 // boolean Break = f a l s e ;<br />
304 f o r ( i n t c=c o l S t a r t ; c v )<br />
316 n . a = v ;<br />
317 i f ( n . a < alpha ) {<br />
318 b [ c ] [ r ] = 2 ;<br />
319 b [ c ] [ r +1] = 2 ;<br />
320 r e t u r n ( n . a ) ;<br />
321 }<br />
322 i f ( beta > n . a )<br />
323 beta = n . a ;<br />
324 }<br />
325 i f ( p [ 2 ] == −1){<br />
326 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
327 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, n ) ) ) ;<br />
328 count++;<br />
329 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
330 i f ( n . a > v )<br />
331 n . a = v ;<br />
332 i f ( n . a < alpha ) {<br />
333 b [ c ] [ r ] = 2 ;<br />
334 b [ c ] [ r +1] = 2 ;<br />
335 r e t u r n ( n . a ) ;<br />
336 }<br />
337 i f ( beta > n . a )<br />
338 beta = n . a ;<br />
339 }
A.3 AI<strong>Taiji</strong>LocalAreaAB.java 137<br />
340 b [ c ] [ r ] = 0 ;<br />
341 b [ c ] [ r +1] = 1 ;<br />
342<br />
343 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
344 i f ( p [ 2 ] >= 0) {<br />
345 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
346 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
347 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
348 i f ( n . a > v )<br />
349 n . a = v ;<br />
350 i f ( n . a < alpha ) {<br />
351 b [ c ] [ r ] = 2 ;<br />
352 b [ c ] [ r +1] = 2 ;<br />
353 r e t u r n ( n . a ) ;<br />
354 }<br />
355 i f ( beta > n . a )<br />
356 beta = n . a ;<br />
357 }<br />
358 i f ( p [ 2 ] == −1){<br />
359 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
360 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , n ) ) ) ;<br />
361 count++;<br />
362 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
363 i f ( n . a > v )<br />
364 n . a = v ;<br />
365 i f ( n . a < alpha ) {<br />
366 b [ c ] [ r ] = 2 ;<br />
367 b [ c ] [ r +1] = 2 ;<br />
368 r e t u r n ( n . a ) ;<br />
369 }<br />
370 i f ( beta > n . a )<br />
371 beta = n . a ;<br />
372 }<br />
373 b [ c ] [ r ] = 2 ;<br />
374 b [ c ] [ r +1] = 2 ;<br />
375<br />
376<br />
377 }<br />
378 }<br />
379 }<br />
380<br />
381<br />
382 f o r ( i n t c=c o l S t a r t ; c
138 Bilag A<br />
391 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
392 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
393 i f ( n . a > v )<br />
394 n . a = v ;<br />
395 i f ( n . a < alpha ) {<br />
396 b [ c ] [ r ] = 2 ;<br />
397 b [ c +1][ r ] = 2 ;<br />
398 r e t u r n ( n . a ) ;<br />
399 }<br />
400 i f ( beta > n . a )<br />
401 beta = n . a ;<br />
402 }<br />
403 i f ( p [ 2 ] == −1){<br />
404 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
405 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , n ) ) ) ;<br />
406 count++;<br />
407 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
408 i f ( n . a > v )<br />
409 n . a = v ;<br />
410 i f ( n . a < alpha ) {<br />
411 b [ c ] [ r ] = 2 ;<br />
412 b [ c +1][ r ] = 2 ;<br />
413 r e t u r n ( n . a ) ;<br />
414 }<br />
415 i f ( beta > n . a )<br />
416 beta = n . a ;<br />
417 }<br />
418 b [ c ] [ r ] = 0 ;<br />
419 b [ c +1][ r ] = 1 ;<br />
420<br />
421 p = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
422 i f ( p [ 2 ] >= 0) {<br />
423 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] ) . par . add ( n ) ;<br />
424 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p<br />
[ 2 ] ) ) ;<br />
425 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 1 ) ;<br />
426 i f ( n . a > v )<br />
427 n . a = v ;<br />
428 i f ( n . a < alpha ) {<br />
429 b [ c ] [ r ] = 2 ;<br />
430 b [ c +1][ r ] = 2 ;<br />
431 r e t u r n ( n . a ) ;<br />
432 }<br />
433 i f ( beta > n . a )<br />
434 beta = n . a ;<br />
435 }<br />
436 i f ( p [ 2 ] == −1){<br />
437 p [2]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;<br />
438 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add ( n . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , n ) ) ) ;
A.3 AI<strong>Taiji</strong>LocalAreaAB.java 139<br />
439 count++;<br />
440 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get ( p [ 2 ] )<br />
, alpha , beta , 0 ) ;<br />
441 i f ( n . a > v )<br />
442 n . a = v ;<br />
443 i f ( n . a < alpha ) {<br />
444 b [ c ] [ r ] = 2 ;<br />
445 b [ c +1][ r ] = 2 ;<br />
446 r e t u r n ( n . a ) ;<br />
447 }<br />
448 i f ( beta > n . a )<br />
449 beta = n . a ;<br />
450 }<br />
451 b [ c ] [ r ] = 2 ;<br />
452 b [ c +1][ r ] = 2 ;<br />
453 }<br />
454 }<br />
455 }<br />
456 r e t u r n ( n . a ) ;<br />
457 }<br />
458 }<br />
459<br />
460<br />
461<br />
462<br />
463 // s a e t t e r s c o r e n f o r en node t i l −”u e n d e l i g ”<br />
464 p r i v a t e Node setScoreMin ( Node n ) {<br />
465 n . a = −tModel . maxScore ;<br />
466 r e t u r n ( n ) ;<br />
467 }<br />
468 // s a e t t e r s c o r e n f o r en node t i l ” u e n d e l i g ”<br />
469 p r i v a t e Node setScoreMax ( Node n ) {<br />
470 n . a = tModel . maxScore ;<br />
471 r e t u r n ( n ) ;<br />
472 }<br />
473<br />
474<br />
475<br />
476 p u b l i c Node returnMove ( boolean b ) {<br />
477 i f ( tModel . currentTurn == 1) {<br />
478 tNode = new Node ( ) ;<br />
479 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;<br />
480 Root . wc=tModel . noCols / 2 ;<br />
481 Root . wr=tModel . noCols / 2 ;<br />
482 Root . bc=Root . wc ;<br />
483 Root . br=Root . wr+1;<br />
484 r e t u r n ( Root ) ;<br />
485 }<br />
486 LocalAreaAB ( ) ;<br />
487<br />
488 w h i l e ( Root . c h i l d r e n . s i z e ( ) == 0 && tModel . movesLeft ( ) ) {<br />
489 i f ( b )<br />
490 min ( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;<br />
491 i f ( ! b )<br />
492 max( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;
140 Bilag A<br />
493 i f ( Root . c h i l d r e n . s i z e ( ) == 0) {<br />
494 i n t [ ] s = new i n t [ 4 ] ;<br />
495 s = tModel . getAMove ( Root ) ;<br />
496 setAround ( s ) ;<br />
497 }<br />
498 // System . out . p r i n t l n (”LA − End o f While ”) ;<br />
499 }<br />
500<br />
501 Random randomVal = new Random ( ) ;<br />
502 Node n ;<br />
503 ArrayList move = new ArrayList () ;<br />
504 i n t wC,wR, bC , bR, ran ;<br />
505 n = Root . c h i l d r e n . get ( 0 ) ;<br />
506 // tModel . t P r i n t . printNode ( Root ) ; // u d s k r i v e r roden<br />
507 // tModel . t P r i n t . p r i n t C h i l d r e n ( Root ) ; // u d s k r i v e r rodens<br />
boern saa r e s u l t a t e t a f soegningen bedre kan<br />
u n d e r s o e g e s<br />
508 System . out . p r i n t l n (”LA − r e t u r n move Root . s i z e=”+Root .<br />
c h i l d r e n . s i z e ( ) ) ;<br />
509 i f ( Root . c h i l d r e n . s i z e ( ) > 1) {<br />
510 i f ( b ) {<br />
511 f o r ( i n t i =0; i Root . c h i l d r e n . get ( i ) . a ) {<br />
513 n=Root . c h i l d r e n . get ( i ) ;<br />
514 }<br />
515 }<br />
516 }<br />
517 i f ( ! b ) {<br />
518 f o r ( i n t i =0; i
A.3 AI<strong>Taiji</strong>LocalAreaAB.java 141<br />
540 // tModel . t P r i n t . printNode ( n ) ;<br />
541<br />
542 // vender det v a l g t e t r a e k saa det matcher s p i l l e t s<br />
igangvaerende t r a e k .<br />
543 i n t mr = tModel . tBoard . compareBoardsInt ( n . nodeBoard , tModel<br />
. tBoard . board [ tModel . currentTurn ] ) ;<br />
544 System . out . p r i n t l n (”LA − Return move mr=”+mr) ;<br />
545 i f (mr == 1) {<br />
546 r e t u r n ( n ) ;<br />
547 }<br />
548 i f (mr == 2) {<br />
549 n . br = tModel . noRows−1 − bR ;<br />
550 n . wr = tModel . noRows−1 − wR;<br />
551 r e t u r n ( n ) ;<br />
552 }<br />
553 i f (mr == 3) {<br />
554 n . bc = tModel . noCols −1 − bC ;<br />
555 n . wc = tModel . noCols −1 − wC;<br />
556 r e t u r n ( n ) ;<br />
557 }<br />
558 i f (mr == 4) {<br />
559 n . bc = tModel . noCols −1 − bC ;<br />
560 n . wc = tModel . noCols −1 − wC;<br />
561 n . br = tModel . noRows−1 − bR ;<br />
562 n . wr = tModel . noRows−1 − wR;<br />
563 r e t u r n ( n ) ;<br />
564 }<br />
565 i f (mr == 5) {<br />
566 n . bc = bR ;<br />
567 n . wc = wR;<br />
568 n . br = bC ;<br />
569 n . wr = wC;<br />
570 r e t u r n ( n ) ;<br />
571 }<br />
572 i f (mr == 6) {<br />
573 n . bc = tModel . noRows−1 − bR ;<br />
574 n . wc = tModel . noRows−1 − wR;<br />
575 n . br = bC ;<br />
576 n . wr = wC;<br />
577 r e t u r n ( n ) ;<br />
578 }<br />
579 i f (mr == 7) {<br />
580 n . bc = bR ;<br />
581 n . wc = wR;<br />
582 n . br = tModel . noCols −1 − bC ;<br />
583 n . wr = tModel . noCols −1 − wC;<br />
584 r e t u r n ( n ) ;<br />
585 }<br />
586 i f (mr == 8) {<br />
587 n . bc = tModel . noRows−1 − bR ;<br />
588 n . wc = tModel . noRows−1 − wR;<br />
589 n . br = tModel . noCols −1 − bC ;<br />
590 n . wr = tModel . noCols −1 − wC;<br />
591 r e t u r n ( n ) ;<br />
592 }
142 Bilag A<br />
593 r e t u r n ( n ) ;<br />
594 }<br />
595<br />
596<br />
597 }<br />
A.4 AI<strong>Taiji</strong>Minimax.java<br />
1 import java . u t i l . Random ;<br />
2 import java . u t i l . ArrayList ;<br />
3<br />
4 p u b l i c c l a s s AI<strong>Taiji</strong>Minimax {<br />
5 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
6 p u b l i c Node tNode ;<br />
7 p u b l i c Tree tTree ;<br />
8 p u b l i c i n t count ; // f o r at t e s t e hvor mange noder der l a v e s .<br />
9 p u b l i c i n t maxDepth ; // f o r at kunne s a e t t e en max dybde paa<br />
soegningen<br />
10<br />
11 p u b l i c AI<strong>Taiji</strong>Minimax ( <strong>Taiji</strong>Model m) {<br />
12 t h i s . tModel = m;<br />
13 }<br />
14<br />
15 // F r e m s t i l l e r t r a e e t med udgangs punkt i det nuvaerende b r a e t .<br />
16 p u b l i c void c r e a t e T r e e ( )<br />
17 {<br />
18 tNode = new Node ( ) ;<br />
19 Node i n i t = tNode . createNode ( tModel . currentTurn ,<br />
tModel ) ;<br />
20 count = 1 ;<br />
21 // i n t b [ ] [ ] = tModel . getOneBoard ( tModel . currentTurn ) ;<br />
22 //Node t e s t = tNode . createCloneNode ( i n i t ) ;<br />
23 // System . out . p r i n t l n (” t e s t . par ”+ t e s t . par ) ;<br />
24 tTree = new Tree ( ) ;<br />
25 tTree . setRoot ( i n i t ) ;<br />
26<br />
27 i n t maxTurns = tModel . maxTurnsLeft ( ) ;<br />
28 System . out . p r i n t l n (” minimax max t u r n s l e f t ”+maxTurns )<br />
;<br />
29 setMaxDepth ( 1 ) ;<br />
30 // System . out . p r i n t l n (” i n i t ”) ;<br />
31 // System . out . p r i n t l n (” ”+ i n i t +” ”+ i n i t . par+” ”+ i n i t . a+”<br />
”+ i n i t . bc+” ”+ i n i t . br+” ”+ i n i t . wc+” ”+ i n i t . wr+” ”+<br />
i n i t . c h i l d r e n +” ”+ i n i t . nodeBoard+” ”+ i n i t . d ) ;<br />
32 // System . out . p r i n t l n ( i n i t . nodeBoard [ 0 ] [ 0 ] + ” ”+ i n i t .<br />
nodeBoard [ 1 ] [ 0 ] + ” ”+ i n i t . nodeBoard [ 2 ] [ 0 ] ) ;<br />
33 // System . out . p r i n t l n ( i n i t . nodeBoard [ 0 ] [ 1 ] + ” ”+ i n i t .<br />
nodeBoard [ 1 ] [ 1 ] + ” ”+ i n i t . nodeBoard [ 2 ] [ 1 ] ) ;<br />
34 // System . out . p r i n t l n ( i n i t . nodeBoard [ 0 ] [ 2 ] + ” ”+ i n i t .<br />
nodeBoard [ 1 ] [ 2 ] + ” ”+ i n i t . nodeBoard [ 2 ] [ 2 ] ) ;<br />
35<br />
36 // System . out . p r i n t l n (” minimax createChildren ”) ;<br />
37 c r e a t e C h i l d r e n ( i n i t , 0) ;
A.4 AI<strong>Taiji</strong>Minimax.java 143<br />
38 // printOddGen ( ) ;<br />
39 // System . out . p r i n t l n (” ”) ;<br />
40 c r e a t e C h i l d r e n ( tTree . oddGen . get ( 1 ) , 1) ;<br />
41 // printEvenGen ( ) ;<br />
42 // System . out . p r i n t l n (” minimax createLeaves ”) ;<br />
43 c r e a t e L e a v e s ( ) ;<br />
44 calcScoreOnLeaves ( ) ;<br />
45 // p r i n t F i n a l L e a v e s ( ) ;<br />
46 // System . out . p r i n t l n (” c a l c T r e e ”) ;<br />
47 // p r i n t L e a v e s ( ) ;<br />
48 // System . out . p r i n t l n (” minimax calcTree ”) ;<br />
49 c a l c T r e e ( ) ;<br />
50 System . out . p r i n t l n (”Number o f nodes c r e a t e d : ”+count ) ;<br />
51 count =0;<br />
52 // addLeavesToGen ( 4 ) ;<br />
53 // calcGen ( 4 ) ;<br />
54 // printMax ( ) ;<br />
55 // printOddGen ( ) ;<br />
56<br />
57 }<br />
58<br />
59<br />
60<br />
61 // Laver en node / barn f o r hvert muligt t r a e k f r a f o r a e l d r e noden<br />
. Laver a l t s a a en g e n e r a t i o n a f boern .<br />
62 p r i v a t e void c r e a t e C h i l d r e n ( Node p , i n t d )<br />
63 {<br />
64 i n t [ ] [ ] b = p . nodeBoard ;<br />
65 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
66 f o r ( i n t r =0; r < tModel . noRows−1; r++){<br />
67 i f ( b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {<br />
68 b [ c ] [ r ] = 1 ;<br />
69 b [ c ] [ r +1] = 0 ;<br />
70 i n t i ;<br />
71 i = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
72 // System . out . p r i n t l n (” minimax checkBI i= ”+ i ) ;<br />
73 i f ( i >= 0) {<br />
74 i f ( d % 2 == 1)<br />
75 tTree . evenGen . get ( i ) . par . add ( p ) ;<br />
76 i f ( d % 2 == 0)<br />
77 tTree . oddGen . get ( i ) . par . add ( p ) ;<br />
78 }<br />
79 i f ( i == −1){<br />
80 i f ( d % 2 == 1) {<br />
81 tTree . evenGen . add ( p . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, p ) ) ) ;<br />
82 count++;<br />
83 }<br />
84 i f ( d % 2 == 0) {<br />
85 tTree . oddGen . add ( p . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, p ) ) ) ;<br />
86 count++;<br />
87 }<br />
88 }<br />
89
144 Bilag A<br />
90 b [ c ] [ r ] = 0 ;<br />
91 b [ c ] [ r +1] = 1 ;<br />
92 i = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
93 // System . out . p r i n t l n (” minimax checkBI2 i= ”+ i ) ;<br />
94 i f ( i >= 0) {<br />
95 i f ( d % 2 == 1)<br />
96 tTree . evenGen . get ( i ) . par . add ( p ) ;<br />
97 i f ( d % 2 == 0)<br />
98 tTree . oddGen . get ( i ) . par . add ( p ) ;<br />
99 }<br />
100 i f ( i == −1){<br />
101 i f ( d % 2 == 1) {<br />
102 tTree . evenGen . add ( p . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , p ) ) ) ;<br />
103 count++;<br />
104 }<br />
105 i f ( d % 2 == 0) {<br />
106 tTree . oddGen . add ( p . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , p ) ) ) ;<br />
107 count++;<br />
108 }<br />
109 }<br />
110 b [ c ] [ r ] = 2 ;<br />
111 b [ c ] [ r +1] = 2 ;<br />
112<br />
113 // tTree . addLeave ( p . addChild ( tNode .<br />
createChildNode ( c , r , c , r +1, p ) ) ) ;<br />
114 // tTree . addLeave ( p . addChild ( tNode .<br />
createChildNode ( c , r +1, c , r , p ) ) ) ;<br />
115 }<br />
116<br />
117 }<br />
118 }<br />
119 f o r ( i n t c =0; c < tModel . noCols −1; c++){<br />
120 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
121 i f ( b [ c ] [ r ] == 2 && b [ c +1][ r ] == 2 ) {<br />
122 b [ c ] [ r ] = 1 ;<br />
123 b [ c +1][ r ] = 0 ;<br />
124 i n t i ;<br />
125 i = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
126 // System . out . p r i n t l n (” minimax checkBoardIndi i<br />
= ”+ i ) ;<br />
127 i f ( i >= 0) {<br />
128 i f ( d % 2 == 1)<br />
129 tTree . evenGen . get ( i ) . par . add ( p ) ;<br />
130 i f ( d % 2 == 0)<br />
131 tTree . oddGen . get ( i ) . par . add ( p ) ;<br />
132 }<br />
133 i f ( i == −1){<br />
134 i f ( d % 2 == 1) {<br />
135 tTree . evenGen . add ( p . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , p ) ) ) ;<br />
136 count++;<br />
137 }<br />
138 i f ( d % 2 == 0) {
A.4 AI<strong>Taiji</strong>Minimax.java 145<br />
139 tTree . oddGen . add ( p . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , p ) ) ) ;<br />
140 count++;<br />
141 }<br />
142 }<br />
143<br />
144 b [ c ] [ r ] = 0 ;<br />
145 b [ c +1][ r ] = 1 ;<br />
146 i = c h e c k B o a r d I n d i v i d u a l i t y ( b , d ) ;<br />
147 i f ( i >= 0) {<br />
148 i f ( d % 2 == 1)<br />
149 tTree . evenGen . get ( i ) . par . add ( p ) ;<br />
150 i f ( d % 2 == 0)<br />
151 tTree . oddGen . get ( i ) . par . add ( p ) ;<br />
152 }<br />
153 i f ( i == −1){<br />
154 i f ( d % 2 == 1) {<br />
155 tTree . evenGen . add ( p . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , p ) ) ) ;<br />
156 count++;}<br />
157 i f ( d % 2 == 0) {<br />
158 tTree . oddGen . add ( p . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , p ) ) ) ;<br />
159 count++;<br />
160 }<br />
161 }<br />
162 b [ c ] [ r ] = 2 ;<br />
163 b [ c +1][ r ] = 2 ;<br />
164 // tTree . addLeave ( p . addChild ( tNode .<br />
createChildNode ( c , r , c +1, r , p ) ) ) ;<br />
165 // tTree . addLeave ( p . addChild ( tNode .<br />
createChildNode ( c +1, r , c , r , p ) ) ) ;<br />
166 }<br />
167 }<br />
168 }<br />
169 }<br />
170<br />
171 // Checker om e t b r a e t a l l e r e d e e k s i s t e r e i en node ,<br />
172 // r e t u r n e r e r i f o r p l a c e r i n g paa node med samme b r a e t e l l e r −1,<br />
h v i s der i k k e f i n d e s en<br />
173 p r i v a t e i n t c h e c k B o a r d I n d i v i d u a l i t y ( i n t [ ] [ ] b , i n t d ) {<br />
174 i f ( d % 2 == 1) {<br />
175 // System . out . p r i n t l n (” minimax checkBI s i z e even ”+tTree .<br />
evenGen . s i z e ( ) ) ;<br />
176 f o r ( i n t i = 0 ; i
146 Bilag A<br />
185 // System . out . p r i n t l n (” minimax checkBI s i z e odd ”+tTree .<br />
oddGen . s i z e ( ) ) ;<br />
186 f o r ( i n t i = 0 ; i
A.4 AI<strong>Taiji</strong>Minimax.java 147<br />
231 f o r ( i n t i = 0 ; i < tTree . oddGen . s i z e ( ) ; i ++){<br />
232 c r e a t e C h i l d r e n ( tTree . oddGen . get ( i ) , d ) ;<br />
233 }<br />
234 oddGenToLeaves ( ) ;<br />
235 // i f ( d != 1)<br />
236 tTree . oddGen . c l e a r ( ) ;<br />
237 }<br />
238 i f ( d % 2 == 0) {<br />
239 f o r ( i n t i = 0 ; i < tTree . evenGen . s i z e ( ) ; i ++){<br />
240 c r e a t e C h i l d r e n ( tTree . evenGen . get ( i ) , d ) ;<br />
241 }<br />
242 evenGenToLeaves ( ) ;<br />
243 tTree . evenGen . c l e a r ( ) ;<br />
244 }<br />
245 }<br />
246 //Node t = tNode . createCloneNode ( tTree . Leaves [ 1 ] ) ;<br />
247 // c r e a t e C h i l d r e n ( t ) ;<br />
248 // System . out . p r i n t l n (” createGen ”+tTree . Leaves . get ( 0 ) ) ;<br />
249 // f o r ( i n t i =0; i
148 Bilag A<br />
280 }<br />
281<br />
282 // f l y t t e r noder t i l Leaves h v i s de e r f i n a l s t a t e s , e l l e r s<br />
s a e t t e s s c o r e t i l min<br />
283 p r i v a t e void oddGenToLeaves ( ) {<br />
284 f o r ( i n t i = 0 ; i
A.4 AI<strong>Taiji</strong>Minimax.java 149<br />
329 i f ( tTree . evenGen . get ( i ) . a > tTree . evenGen . get ( i ) .<br />
par . get ( j ) . a )<br />
330 tTree . evenGen . get ( i ) . par . get ( j ) . a = tTree .<br />
evenGen . get ( i ) . a ;<br />
331 }<br />
332 }<br />
333 }<br />
334 i f ( d % 2 == 1) {<br />
335 f o r ( i n t i =0; i
150 Bilag A<br />
377 // i f ( tTree . max [ i ] . d > 0) { // f o r at undgaa n u l l<br />
p o i n t e r h v i s roden e r med i ”max”<br />
378 // i f ( tTree . max [ i ] . par == n u l l )<br />
379 // // System . out . p r i n t l n (”maxMax Null i ”+ i +”<br />
curMax ”+tTree . curMax+” D ”+tTree . max [ i ] . d ) ;<br />
380 // i f ( tTree . max [ i ] . par . a < tTree . max [ i ] . a ) {<br />
381 // tTree . max [ i ] . par . a = tTree . max [ i ] . a ;<br />
382 // // System . out . p r i n t l n (” minMin a ”+tTree .<br />
max [ i ] . a+” par . a ”+tTree . max [ i ] . par . a ) ;<br />
383 // i f ( ! tTree . checkMin ( tTree . max [ i ] . par ) )<br />
384 // tTree . addMin ( tTree . max [ i ] . par ) ;<br />
385 // }<br />
386 // }<br />
387 // }<br />
388 //}<br />
389<br />
390 p u b l i c Node returnMove ( ) {<br />
391 Node n ;<br />
392 n = tTree . oddGen . get ( 0 ) ;<br />
393 i f ( tTree . oddGen . s i z e ( ) > 1) {<br />
394 f o r ( i n t i = 0 ; i tTree . oddGen . get ( i ) . a ) {<br />
396 n=tTree . oddGen . get ( i ) ;<br />
397 }<br />
398 }<br />
399 }<br />
400 r e t u r n ( n ) ;<br />
401 }<br />
402<br />
403 // r e t u r n e r e r det t r a e k der s k a l t a g e s ved at r e t u r n e r e r noden<br />
med som i n d e h o l d e r t r a e k k e t , vaer opmaerksom<br />
404 // paa at nodens b r a e t i k k e e r b l e v e t r o t t e r e t kun s e l v e<br />
t r a e k k e t der s k a l f o r e t a g e s .<br />
405 p u b l i c Node returnMoveMirRot ( ) {<br />
406 Random randomVal = new Random ( ) ;<br />
407 Node n ;<br />
408 ArrayList move = new ArrayList () ;<br />
409 i n t wC,wR, bC , bR, ran ;<br />
410 n = tTree . oddGen . get ( 0 ) ;<br />
411 i f ( tTree . oddGen . s i z e ( ) > 1) {<br />
412 f o r ( i n t i = 0 ; i tTree . oddGen . get ( i ) . a ) {<br />
414 n=tTree . oddGen . get ( i ) ;<br />
415 }<br />
416 }<br />
417 f o r ( i n t i = 0 ; i
A.4 AI<strong>Taiji</strong>Minimax.java 151<br />
427 wR = n . wr ;<br />
428 bC = n . bc ;<br />
429 bR = n . br ;<br />
430 n . nodeBoard [wC ] [ wR]=2;<br />
431 n . nodeBoard [ bC ] [ bR]=2;<br />
432<br />
433 i n t mr = tModel . tBoard . compareBoardsInt ( n . nodeBoard , tModel<br />
. tBoard . board [ tModel . currentTurn ] ) ;<br />
434 i f (mr == 1) {<br />
435 r e t u r n ( n ) ;<br />
436 }<br />
437 i f (mr == 2) {<br />
438 n . br = tModel . noRows−1 − bR ;<br />
439 n . wr = tModel . noRows−1 − wR;<br />
440 r e t u r n ( n ) ;<br />
441 }<br />
442 i f (mr == 3) {<br />
443 n . bc = tModel . noCols −1 − bC ;<br />
444 n . wc = tModel . noCols −1 − wC;<br />
445 r e t u r n ( n ) ;<br />
446 }<br />
447 i f (mr == 4) {<br />
448 n . bc = tModel . noCols −1 − bC ;<br />
449 n . wc = tModel . noCols −1 − wC;<br />
450 n . br = tModel . noRows−1 − bR ;<br />
451 n . wr = tModel . noRows−1 − wR;<br />
452 r e t u r n ( n ) ;<br />
453 }<br />
454 i f (mr == 5) {<br />
455 n . bc = bR ;<br />
456 n . wc = wR;<br />
457 n . br = bC ;<br />
458 n . wr = wC;<br />
459 r e t u r n ( n ) ;<br />
460 }<br />
461 i f (mr == 6) {<br />
462 n . bc = tModel . noRows−1 − bR ;<br />
463 n . wc = tModel . noRows−1 − wR;<br />
464 n . br = bC ;<br />
465 n . wr = wC;<br />
466 r e t u r n ( n ) ;<br />
467 }<br />
468 i f (mr == 7) {<br />
469 n . bc = bR ;<br />
470 n . wc = wR;<br />
471 n . br = tModel . noCols −1 − bC ;<br />
472 n . wr = tModel . noCols −1 − wC;<br />
473 r e t u r n ( n ) ;<br />
474 }<br />
475 i f (mr == 8) {<br />
476 n . bc = tModel . noRows−1 − bR ;<br />
477 n . wc = tModel . noRows−1 − wR;<br />
478 n . br = tModel . noCols −1 − bC ;<br />
479 n . wr = tModel . noCols −1 − wC;<br />
480 r e t u r n ( n ) ;
152 Bilag A<br />
481 }<br />
482 r e t u r n ( n ) ;<br />
483 }<br />
484<br />
485<br />
486 p r i v a t e void p r i n t L e a v e s ( ) {<br />
487 System . out . p r i n t l n (” Current Leaves ”) ;<br />
488 f o r ( i n t i =0; i
A.4 AI<strong>Taiji</strong>Minimax.java 153<br />
[ 1 ] [ 2 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard<br />
[ 2 ] [ 2 ] ) ;<br />
506 System . out . p r i n t l n ( ) ;<br />
507 }<br />
508 }<br />
509<br />
510 p r i v a t e void printOddGen ( ) {<br />
511 System . out . p r i n t l n (”OddGen”) ;<br />
512 f o r ( i n t i =0; i
154 Bilag A<br />
532 // System . out . p r i n t l n ( tTree . Leaves [ i ] . c h i l d r e n . get ( j<br />
) . nodeBoard [ 0 ] [ 2 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .<br />
nodeBoard [ 1 ] [ 2 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .<br />
nodeBoard [ 2 ] [ 2 ] ) ;<br />
533 // System . out . p r i n t l n ( ) ;<br />
534 // }<br />
535 //}<br />
536<br />
537 p r i v a t e boolean checkMaxMin ( ) {<br />
538 f o r ( i n t i = 0 ; i < tTree . oddGen . s i z e ( ) ; i ++){<br />
539 i f ( tTree . oddGen . get ( i ) == n u l l ) {<br />
540 System . out . p r i n t l n (” Null i ”+ i +” s i z e even ”+tTree<br />
. curMax ) ;<br />
541 r e t u r n ( f a l s e ) ;<br />
542 }<br />
543 }<br />
544 f o r ( i n t j = 0 ; j < tTree . evenGen . s i z e ( ) ; j++){<br />
545 i f ( tTree . evenGen . get ( j ) == n u l l ) {<br />
546 System . out . p r i n t l n (” Null j ”+ j +” s i z e odd ”+tTree .<br />
curMin ) ;<br />
547 r e t u r n ( f a l s e ) ;<br />
548 }<br />
549<br />
550 }<br />
551 r e t u r n ( t r u e ) ;<br />
552 }<br />
553<br />
554 p r i v a t e boolean checkMaxMinPar ( ) {<br />
555 f o r ( i n t i = 0 ; i < tTree . oddGen . s i z e ( ) ; i ++){<br />
556 i f ( tTree . oddGen . get ( i ) . par == n u l l ) {<br />
557 System . out . p r i n t l n (” Null Par i ”+ i +” odd ”+tTree .<br />
oddGen . s i z e ( ) ) ;<br />
558 r e t u r n ( f a l s e ) ;<br />
559 }<br />
560 }<br />
561 f o r ( i n t j = 0 ; j < tTree . evenGen . s i z e ( ) ; j++){<br />
562 i f ( tTree . evenGen . get ( j ) . par == n u l l ) {<br />
563 System . out . p r i n t l n (” Null Par j ”+ j +” even ”+tTree .<br />
evenGen . s i z e ( ) ) ;<br />
564 r e t u r n ( f a l s e ) ;<br />
565 }<br />
566<br />
567 }<br />
568 r e t u r n ( t r u e ) ;<br />
569 }<br />
570<br />
571 // e r s a e t t e s maxDepth<br />
572 p r i v a t e void setMaxDepth ( i n t mode ) {<br />
573 // i ”Mode 0” f o r s o e g e r den at regne h e l e t r a e e t igennem<br />
574 i f ( mode == 0) {<br />
575 maxDepth = ( tModel . noCols ∗ tModel . noRows /2) ;<br />
576 System . out . p r i n t l n (” minimax Mode 0 maxDepth = ”+<br />
maxDepth ) ;<br />
577 }
A.5 Board.java 155<br />
578 // i ”Mode 1” s a e t t e s max fremregningen t i l 2 , h v i s der e r<br />
mere en 5 t r a e k t i l b a g e ,<br />
579 // e l l e r s r e g n e r den h e l t igennem .<br />
580 i f ( mode == 1) {<br />
581 i n t maxT = tModel . maxTurnsLeft ( ) ;<br />
582 i f (maxT > 10)<br />
583 maxDepth = 2 ;<br />
584 i f (maxT > 5 && maxT
156 Bilag A<br />
33 p u b l i c i n t [ ] [ ] getOneBoard ( i n t t )<br />
34 {<br />
35 oneBoard = board [ t ] ;<br />
36 r e t u r n oneBoard ;<br />
37<br />
38 }<br />
39<br />
40 // P l a c e r e r en b r i k ( n e u t r a l , white e l l e r black ) paa e t f e l t i<br />
den nuvaerende tur .<br />
41 // Modtager p o s i t i o n e n og f a r v e n paa brikken som argument .<br />
42 p u b l i c void s e t P i e c e ( i n t col , i n t row , i n t p i e c e )<br />
43 {<br />
44 board [ tModel . currentTurn ] [ c o l ] [ row ] = p i e c e ;<br />
45 }<br />
46<br />
47 // Reset . Toemmer b r a e t t e t , s a e t t e r o e j e b l i k s v a e r d i e r n e t i l<br />
u d g a n g s p o s i t i o n e n .<br />
48 p u b l i c void r esetBoard ( )<br />
49 {<br />
50 i n t C = tModel . getNoCols ( ) ;<br />
51 i n t R = tModel . getNoRows ( ) ;<br />
52<br />
53 f o r ( i n t c = 0 ; c < C; c++)<br />
54 {<br />
55 f o r ( i n t r = 0 ; r < R; r++)<br />
56 {<br />
57 s e t P i e c e ( c , r , 2 ) ;<br />
58 }<br />
59 }<br />
60 board [ 0 ] [ 0 ] [ 0 ] = 1 ;<br />
61 }<br />
62<br />
63 // Kopiere b r a e t t e t f r a den nuvaerende tur t i l den n a e s t e .<br />
64 p u b l i c void copyBoard ( )<br />
65 {<br />
66 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
67 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
68 board [ tModel . currentTurn +1][ c ] [ r ] = board [ tModel .<br />
currentTurn ] [ c ] [ r ] ;<br />
69 }<br />
70 // Kopiere b r a e t t e t f r a den nuvaerende tur t i l tur t .<br />
71 p u b l i c void copyBoardTo ( i n t t )<br />
72 {<br />
73 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
74 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
75 board [ tModel . currentTurn+t ] [ c ] [ r ] = board [ tModel .<br />
currentTurn ] [ c ] [ r ] ;<br />
76 }<br />
77<br />
78 // Laver en klon a f b r a e t t e t f o r tur t<br />
79 p u b l i c void cloneBoard ( i n t t )<br />
80 {<br />
81 c l o n e = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
82 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
83 f o r ( i n t r =0; r < tModel . noRows ; r++)
A.5 Board.java 157<br />
84 c l o n e [ c ] [ r ] = board [ t ] [ c ] [ r ] ;<br />
85 }<br />
86<br />
87 // Kloner e t b r a e t og r e t u n e r e r klonen<br />
88 p u b l i c i n t [ ] [ ] c l o n e ( i n t [ ] [ ] b )<br />
89 {<br />
90 c l o n e = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
91 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
92 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
93 c l o n e [ c ] [ r ] = b [ c ] [ r ] ;<br />
94 r e t u r n ( b ) ;<br />
95 }<br />
96<br />
97 // Laver og r e t u r n e r e en klon a f b r a e t t e t f o r tur t<br />
98 p u b l i c i n t [ ] [ ] getClone ( i n t t )<br />
99 {<br />
100 cloneBoard ( t ) ;<br />
101 r e t u r n ( c l o n e ) ;<br />
102 }<br />
103<br />
104 // sammenligner to braet , h v i s de e r h e l t ens r e t u r n e r e s t r u e<br />
105 p u b l i c boolean compareBoards ( i n t [ ] [ ] b , i n t [ ] [ ] d ) {<br />
106 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
107 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
108 i f ( ( b [ c ] [ r ] != d [ c ] [ r ] ) ) {<br />
109 r e t u r n ( f a l s e ) ;<br />
110 }<br />
111 }<br />
112 }<br />
113 r e t u r n ( t r u e ) ;<br />
114 }<br />
115<br />
116 // Sammenligner to braet , h v i s de e r ens ( r o t t e r e t og/ e l l e r<br />
s p e j l v e n d t ) r e t u r n e r e s en v a e r d i mellem 1 og 8<br />
117 // e f t e r hvordan de e r ens (1 e r ens uden r o t a t i o n e l l e r<br />
s p e j l v e n d i n g ) . Er de i k k e ens r e t u r n e r e s 0<br />
118 p u b l i c i n t compareBoardsInt ( i n t [ ] [ ] b , i n t [ ] [ ] d ) {<br />
119 i n t C = tModel . noCols −1;<br />
120 i n t R = tModel . noRows −1;<br />
121 boolean br = f a l s e ;<br />
122 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
123 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
124 i f ( b [ c ] [ r ] != d [ c ] [ r ] ) {<br />
125 br = t r u e ;<br />
126 break ;<br />
127 }<br />
128 }<br />
129 i f ( br )<br />
130 break ;<br />
131 }<br />
132 i f ( ! br )<br />
133 r e t u r n ( 1 ) ;<br />
134<br />
135 br = f a l s e ;<br />
136 f o r ( i n t c =0; c < tModel . noCols ; c++){
158 Bilag A<br />
137 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
138 i f ( b [ c ] [ r ] != d [ c ] [ R−r ] ) {<br />
139 br = t r u e ;<br />
140 break ;<br />
141 }<br />
142 }<br />
143 i f ( br )<br />
144 break ;<br />
145 }<br />
146 i f ( ! br )<br />
147 r e t u r n ( 2 ) ;<br />
148<br />
149 br = f a l s e ;<br />
150 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
151 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
152 i f ( b [ c ] [ r ] != d [ C−c ] [ r ] ) {<br />
153 br = t r u e ;<br />
154 break ;<br />
155 }<br />
156 }<br />
157 i f ( br )<br />
158 break ;<br />
159 }<br />
160 i f ( ! br )<br />
161 r e t u r n ( 3 ) ;<br />
162<br />
163 br = f a l s e ;<br />
164 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
165 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
166 i f ( b [ c ] [ r ] != d [ C−c ] [ R−r ] ) {<br />
167 br = t r u e ;<br />
168 break ;<br />
169 }<br />
170 }<br />
171 i f ( br )<br />
172 break ;<br />
173 }<br />
174 i f ( ! br )<br />
175 r e t u r n ( 4 ) ;<br />
176<br />
177 i f ( tModel . noCols != tModel . noRows ) // de f o e l g e n d e e r kun<br />
mulige hvis , b r a e t t e t e r k v a d r a t i s k<br />
178 r e t u r n ( 0 ) ;<br />
179<br />
180 br = f a l s e ;<br />
181 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
182 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
183 i f ( b [ c ] [ r ] != d [ r ] [ c ] ) {<br />
184 br = t r u e ;<br />
185 break ;<br />
186 }<br />
187 }<br />
188 i f ( br )<br />
189 break ;<br />
190 }
A.5 Board.java 159<br />
191 i f ( ! br )<br />
192 r e t u r n ( 5 ) ;<br />
193<br />
194 br = f a l s e ;<br />
195 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
196 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
197 i f ( b [ c ] [ r ] != d [R−r ] [ c ] ) {<br />
198 br = t r u e ;<br />
199 break ;<br />
200 }<br />
201 }<br />
202 i f ( br )<br />
203 break ;<br />
204 }<br />
205 i f ( ! br )<br />
206 r e t u r n ( 6 ) ;<br />
207<br />
208 br = f a l s e ;<br />
209 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
210 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
211 i f ( b [ c ] [ r ] != d [ r ] [ C−c ] ) {<br />
212 br = t r u e ;<br />
213 break ;<br />
214 }<br />
215 }<br />
216 i f ( br )<br />
217 break ;<br />
218 }<br />
219 i f ( ! br )<br />
220 r e t u r n ( 7 ) ;<br />
221<br />
222 br = f a l s e ;<br />
223 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
224 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
225 i f ( b [ c ] [ r ] != d [R−r ] [ C−c ] ) {<br />
226 br = t r u e ;<br />
227 break ;<br />
228 }<br />
229 }<br />
230 i f ( br )<br />
231 break ;<br />
232 }<br />
233 i f ( ! br )<br />
234 r e t u r n ( 8 ) ;<br />
235<br />
236 r e t u r n ( 0 ) ;<br />
237 }<br />
238<br />
239 // sammenligner to braet , h v i s de e r ens ( r o t t e r e t og/ e l l e r<br />
s p e j l v e n d t ) r e t u r n e r e s t r u e<br />
240 p u b l i c boolean compareBoardsBool ( i n t [ ] [ ] b , i n t [ ] [ ] d ) {<br />
241 i n t C = tModel . noCols −1;<br />
242 i n t R = tModel . noRows −1;<br />
243 boolean br = f a l s e ;<br />
244 f o r ( i n t c =0; c < tModel . noCols ; c++){
160 Bilag A<br />
245 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
246 i f ( b [ c ] [ r ] != d [ c ] [ r ] ) {<br />
247 br = t r u e ;<br />
248 break ;<br />
249 }<br />
250 }<br />
251 i f ( br )<br />
252 break ;<br />
253 }<br />
254 i f ( ! br )<br />
255 r e t u r n ( t r u e ) ;<br />
256<br />
257 br = f a l s e ;<br />
258 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
259 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
260 i f ( b [ c ] [ r ] != d [ c ] [ R−r ] ) {<br />
261 br = t r u e ;<br />
262 break ;<br />
263 }<br />
264 }<br />
265 i f ( br )<br />
266 break ;<br />
267 }<br />
268 i f ( ! br )<br />
269 r e t u r n ( t r u e ) ;<br />
270<br />
271 br = f a l s e ;<br />
272 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
273 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
274 i f ( b [ c ] [ r ] != d [ C−c ] [ r ] ) {<br />
275 br = t r u e ;<br />
276 break ;<br />
277 }<br />
278 }<br />
279 i f ( br )<br />
280 break ;<br />
281 }<br />
282 i f ( ! br )<br />
283 r e t u r n ( t r u e ) ;<br />
284<br />
285 br = f a l s e ;<br />
286 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
287 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
288 i f ( b [ c ] [ r ] != d [ C−c ] [ R−r ] ) {<br />
289 br = t r u e ;<br />
290 break ;<br />
291 }<br />
292 }<br />
293 i f ( br )<br />
294 break ;<br />
295 }<br />
296 i f ( ! br )<br />
297 r e t u r n ( t r u e ) ;<br />
298
A.5 Board.java 161<br />
299 i f ( tModel . noCols != tModel . noRows ) // de f o e l g e n d e e r kun<br />
mulige hvis , b r a e t t e t e r k v a d r a t i s k<br />
300 r e t u r n ( f a l s e ) ;<br />
301<br />
302 br = f a l s e ;<br />
303 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
304 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
305 i f ( b [ c ] [ r ] != d [ r ] [ c ] ) {<br />
306 br = t r u e ;<br />
307 break ;<br />
308 }<br />
309 }<br />
310 i f ( br )<br />
311 break ;<br />
312 }<br />
313 i f ( ! br )<br />
314 r e t u r n ( t r u e ) ;<br />
315<br />
316 br = f a l s e ;<br />
317 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
318 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
319 i f ( b [ c ] [ r ] != d [R−r ] [ c ] ) {<br />
320 br = t r u e ;<br />
321 break ;<br />
322 }<br />
323 }<br />
324 i f ( br )<br />
325 break ;<br />
326 }<br />
327 i f ( ! br )<br />
328 r e t u r n ( t r u e ) ;<br />
329<br />
330 br = f a l s e ;<br />
331 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
332 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
333 i f ( b [ c ] [ r ] != d [ r ] [ C−c ] ) {<br />
334 br = t r u e ;<br />
335 break ;<br />
336 }<br />
337 }<br />
338 i f ( br )<br />
339 break ;<br />
340 }<br />
341 i f ( ! br )<br />
342 r e t u r n ( t r u e ) ;<br />
343<br />
344 br = f a l s e ;<br />
345 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
346 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
347 i f ( b [ c ] [ r ] != d [R−r ] [ C−c ] ) {<br />
348 br = t r u e ;<br />
349 break ;<br />
350 }<br />
351 }<br />
352 i f ( br )
162 Bilag A<br />
353 break ;<br />
354 }<br />
355 i f ( ! br )<br />
356 r e t u r n ( t r u e ) ;<br />
357<br />
358 r e t u r n ( f a l s e ) ;<br />
359 }<br />
360 }<br />
A.6 FigureMap.java<br />
1<br />
2<br />
3<br />
4 p u b l i c c l a s s FigureMap {<br />
5 p r i v a t e i n t [ ] [ ] f i g B o a r d ;<br />
6 p r i v a t e i n t figW = 1 ; // Laveste nummer f o r hvide f i g u r e r , der<br />
e r endnu i k k e har v a e r e t i brug .<br />
7 p r i v a t e i n t f i g B = 2 ; // Laveste nummer f o r s o r t e f i g u r e r , der<br />
e r endnu i k k e har v a e r e t i brug .<br />
8 p r i v a t e i n t w h i t e P i e c e s = 0 , b l a c k P i e c e s = 0 ;<br />
9 p r i v a t e i n t noCols ; // a n t a l kolonner<br />
10 p r i v a t e i n t noRows ; // a n t a l r a e k k e r<br />
11<br />
12 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
13 p u b l i c Node tNode ;<br />
14<br />
15 p u b l i c FigureMap ( <strong>Taiji</strong>Model m) {<br />
16 t h i s . tModel = m;<br />
17 }<br />
18<br />
19 p u b l i c FigureMap ( Node n )<br />
20 {<br />
21 t h i s . tNode = n ;<br />
22 }<br />
23<br />
24 // udregner s c o r e n f o r b r a e t t e t b .<br />
25 p u b l i c i n t [ ] c a l S c o r e ( i n t [ ] [ ] b , i n t c o l s , i n t rows )<br />
26 {<br />
27 noCols = c o l s ;<br />
28 noRows = rows ;<br />
29 r e s e t F i g B o a r d ( ) ;<br />
30 mapFigures ( b ) ;<br />
31 c o u n t P i e c e s ( ) ;<br />
32 i n t [ ] s c o r e ;<br />
33 s c o r e = new i n t [ 2 ] ;<br />
34 s c o r e [0]= w h i t e P i e c e s ;<br />
35 s c o r e [1]= b l a c k P i e c e s ;<br />
36 r e t u r n ( s c o r e ) ;<br />
37 }<br />
38<br />
39 // udregner d i f f e r e n s e n mellem hvid og s o r t s c o r e<br />
40 p u b l i c i n t c a l D i f ( i n t [ ] [ ] b , i n t c o l s , i n t rows )
A.6 FigureMap.java 163<br />
41 {<br />
42 noCols = c o l s ;<br />
43 noRows = rows ;<br />
44 r e s e t F i g B o a r d ( ) ;<br />
45 mapFigures ( b ) ;<br />
46 c o u n t P i e c e s ( ) ;<br />
47 i n t s c o r e ;<br />
48 s c o r e = w h i t e P i e c e s − b l a c k P i e c e s ;<br />
49 // System . out . p r i n t l n (” s c o r e ”+s c o r e+” WhiteS ”+w h i t e P i e c e s<br />
+” BlackS ”+b l a c k P i e c e s ) ;<br />
50 r e t u r n ( s c o r e ) ;<br />
51 }<br />
52<br />
53 // Returner f i g B o a r d e t f o r e t b r a e t ( f i g u r B r a e t t e t )<br />
54 p u b l i c i n t [ ] [ ] getFigBoard ( i n t [ ] [ ] b , i n t c o l s , i n t rows ) {<br />
55 noCols = c o l s ;<br />
56 noRows = rows ;<br />
57 r e s e t F i g B o a r d ( ) ;<br />
58 mapFigures ( b ) ;<br />
59 r e t u r n ( f i g B o a r d ) ;<br />
60 }<br />
61<br />
62<br />
63<br />
64 // Navnegiver de e n k e l t e f e l t e r e f t e r h v i l k e n f i g u r de hoere<br />
t i l .<br />
65 //( Navnene e r l i g e t a l f o r s o r t e f i g u r e og u l i g e f o r hvide )<br />
66 p u b l i c void mapFigures ( i n t [ ] [ ] b ) {<br />
67 { // F o e r s t e kolone nedad<br />
68 f i g B o a r d = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
69 i n t c =0;<br />
70 {<br />
71 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
72 {<br />
73 i f ( b [ c ] [ r ] == 1)<br />
74 {<br />
75 i f ( f i g B o a r d [ c ] [ r ] == 0)<br />
76 {<br />
77 s e t F i g u r e ( c , r , figW ) ;<br />
78 figW = figW +2;<br />
79 }<br />
80 }<br />
81 e l s e<br />
82 {<br />
83 i f ( b [ c ] [ r ] == 0)<br />
84 {<br />
85 i f ( f i g B o a r d [ c ] [ r ] == 0)<br />
86 {<br />
87 s e t F i g u r e ( c , r , f i g B ) ;<br />
88 f i g B = f i g B +2;<br />
89 }<br />
90 }<br />
91 }<br />
92 }<br />
93 }
164 Bilag A<br />
94 }<br />
95 { // H o r i s o n t a l k o r t l a e n g i n g<br />
96 f o r ( i n t c =0; c < tModel . noCols −1; c++)<br />
97 {<br />
98 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
99 {<br />
100 i f ( b [ c ] [ r ] == 0 && b [ c +1][ r ] == 0 )<br />
101 {<br />
102 i f ( f i g B o a r d [ c ] [ r ] == 0)<br />
103 {<br />
104 s e t F i g u r e ( c , r , f i g B ) ;<br />
105 f i g B=f i g B +2;<br />
106 }<br />
107 s e t F i g u r e ( c +1, r , f i g B o a r d [ c ] [ r ] ) ;<br />
108 }<br />
109 e l s e<br />
110 {<br />
111 i f ( b [ c ] [ r ] == 1 && b [ c +1][ r ] == 1 )<br />
112 {<br />
113 i f ( f i g B o a r d [ c ] [ r ] == 0)<br />
114 {<br />
115 s e t F i g u r e ( c , r , figW ) ;<br />
116 figW=figW +2;<br />
117 }<br />
118 s e t F i g u r e ( c +1, r , f i g B o a r d [ c ] [ r ] ) ;<br />
119 }<br />
120 e l s e<br />
121 {<br />
122 i f ( b [ c ] [ r ] != 1 && b [ c +1][ r ] == 1 )<br />
123 {<br />
124 s e t F i g u r e ( c +1, r , figW ) ;<br />
125 figW = figW +2;<br />
126 }<br />
127 e l s e<br />
128 {<br />
129 i f ( b [ c ] [ r ] != 0 && b [ c +1][ r ] == 0<br />
)<br />
130 {<br />
131 s e t F i g u r e ( c +1, r , f i g B ) ;<br />
132 f i g B = f i g B +2;<br />
133 }<br />
134 }<br />
135 }<br />
136 }<br />
137 }<br />
138 }<br />
139 }<br />
140 { // V e r t i k a l t k o r t l a e n g i n g<br />
141 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
142 {<br />
143 f o r ( i n t r =0; r < tModel . noRows−1; r++)<br />
144 {<br />
145 i f ( b [ c ] [ r ] == 0 && b [ c ] [ r +1] == 0 )<br />
146 {<br />
147 i f ( f i g B o a r d [ c ] [ r ] != 0)
A.6 FigureMap.java 165<br />
148 {<br />
149 i f ( ( f i g B o a r d [ c ] [ r ] != f i g B o a r d [ c ] [ r<br />
+1]) && f i g B o a r d [ c ] [ r +1] != 0)<br />
150 {<br />
151 r e p l a c e F i g ( f i g B o a r d [ c ] [ r +1] ,<br />
f i g B o a r d [ c ] [ r ] ) ;<br />
152 }<br />
153 }<br />
154<br />
155 e l s e<br />
156 {<br />
157 i f ( f i g B o a r d [ c ] [ r +1] != 0)<br />
158 s e t F i g u r e ( c , r , f i g B o a r d [ c ] [ r +1]) ;<br />
159 e l s e<br />
160 {<br />
161 s e t F i g u r e ( c , r , f i g B ) ;<br />
162 f i g B=f i g B +2;<br />
163 }<br />
164 }<br />
165 s e t F i g u r e ( c , r +1, f i g B o a r d [ c ] [ r ] ) ;<br />
166 }<br />
167 e l s e<br />
168 {<br />
169 i f ( b [ c ] [ r ] == 1 && b [ c ] [ r +1] == 1 )<br />
170 {<br />
171 i f ( f i g B o a r d [ c ] [ r ] != 0)<br />
172 {<br />
173 i f ( ( f i g B o a r d [ c ] [ r ] != f i g B o a r d [ c ] [<br />
r +1]) && f i g B o a r d [ c ] [ r +1] != 0)<br />
174 {<br />
175 r e p l a c e F i g ( f i g B o a r d [ c ] [ r +1] ,<br />
f i g B o a r d [ c ] [ r ] ) ;<br />
176 }<br />
177 }<br />
178<br />
179 e l s e<br />
180 {<br />
181 i f ( f i g B o a r d [ c ] [ r +1] != 0)<br />
182 s e t F i g u r e ( c , r , f i g B o a r d [ c ] [ r +1])<br />
;<br />
183 e l s e<br />
184 {<br />
185 s e t F i g u r e ( c , r , figW ) ;<br />
186 figW=figW +2;<br />
187 }<br />
188 }<br />
189 s e t F i g u r e ( c , r +1, f i g B o a r d [ c ] [ r ] ) ;<br />
190 }<br />
191 }<br />
192 }<br />
193 }<br />
194 }<br />
195 }<br />
196<br />
197 // s a e t t e r e t f i g u r n r . f o r e t f e l t .
166 Bilag A<br />
198 p r i v a t e void s e t F i g u r e ( i n t col , i n t row , i n t f i g )<br />
199 {<br />
200 f i g B o a r d [ c o l ] [ row ] = f i g ;<br />
201 }<br />
202<br />
203 // Reset v a e r d i e r n e i f i g B oard .<br />
204 p u b l i c void r e s e t F i g B o ard ( )<br />
205 {<br />
206 figW = 1 ;<br />
207 f i g B = 2 ;<br />
208 f i g B o a r d = new i n t [ noCols ] [ noRows ] ;<br />
209 f o r ( i n t c = 0 ; c < noCols ; c++)<br />
210 f o r ( i n t r = 0 ; r < noRows ; r++)<br />
211 s e t F i g u r e ( c , r , 0 ) ;<br />
212 }<br />
213<br />
214 // E r s t a t e r a l l e f i g u r e med e t bestemt navn med e t nyt navn .<br />
215 p r i v a t e void r e p l a c e F i g ( i n t oldF , i n t newF)<br />
216 {<br />
217 f o r ( i n t c =0; c
A.6 FigureMap.java 167<br />
251 i n t maxW2 = −1;<br />
252 i n t maxB1 = −2;<br />
253 i n t maxB2 = −2;<br />
254<br />
255 f o r ( i n t w=1; wcountFig (maxW1) )<br />
257 {<br />
258 maxW2 = maxW1;<br />
259 maxW1 = w;<br />
260 }<br />
261 e l s e<br />
262 i f ( countFig (w)>countFig (maxW2) )<br />
263 maxW2 = w;<br />
264 f o r ( i n t b=2; bcountFig (maxB1) )<br />
266 {<br />
267 maxB2 = maxB1 ;<br />
268 maxB1 = b ;<br />
269 }<br />
270 e l s e<br />
271 i f ( countFig ( b )>countFig (maxB2) )<br />
272 maxB2 = b ;<br />
273 w h i t e P i e c e s = countFig (maxW1)+countFig (maxW2) ;<br />
274 b l a c k P i e c e s = countFig (maxB1)+countFig (maxB2) ;<br />
275 }<br />
276<br />
277 // r e t u r n e r numrene f o r de 2 s t o e r s t e hvid og de 2 s t o e r s t e<br />
s o r t e f i g u r e , som der endnu kan p l a c e r e s b r i k opad .<br />
278 p u b l i c i n t [ ] [ ] [ ] g e t F i g s ( i n t [ ] [ ] fb ) {<br />
279 i n t [ ] [ ] [ ] f = new i n t [ 2 ] [ 2 ] [ 2 ] ;<br />
280 // f [ ] [ ] [ 0 ] = f i g u r navnet (nummer) , f [ ] [ ] [ 1 ] = f i g u r e n s<br />
s t o e r r e l s e<br />
281 // f [ 1 ] [ ] [ ] = hvid f i g u r , f [ 0 ] [ ] [ ] = s o r t f i g u r<br />
282 // f [ ] [ 0 ] [ ] = s t o e r s t e f i g u r , f [ ] [ 1 ] [ ] = n a e s t s t o e r r e s t e<br />
f i g u r<br />
283 f [ 1 ] [ 0 ] [ 0 ] = −1;<br />
284 f [ 1 ] [ 1 ] [ 0 ] = −1;<br />
285 f [ 0 ] [ 0 ] [ 0 ] = −2;<br />
286 f [ 0 ] [ 1 ] [ 0 ] = −2;<br />
287 f [ 1 ] [ 0 ] [ 1 ] = 0 ;<br />
288 f [ 1 ] [ 1 ] [ 1 ] = 0 ;<br />
289 f [ 0 ] [ 0 ] [ 1 ] = 0 ;<br />
290 f [ 0 ] [ 1 ] [ 1 ] = 0 ;<br />
291 i n t [ ] figN ;<br />
292 figN = findMaxFigNames ( fb ) ;<br />
293<br />
294<br />
295 f o r ( i n t w=1; wf [ 1 ] [ 0 ] [ 1 ] )<br />
299 {<br />
300 f [ 1 ] [ 1 ] [ 0 ] = f [ 1 ] [ 0 ] [ 0 ] ;<br />
301 f [ 1 ] [ 1 ] [ 1 ] = f [ 1 ] [ 0 ] [ 1 ] ;<br />
302 f [ 1 ] [ 0 ] [ 0 ] = w;
168 Bilag A<br />
303 f [ 1 ] [ 0 ] [ 1 ] = W;<br />
304 }<br />
305 e l s e<br />
306 i f (W>f [ 1 ] [ 1 ] [ 1 ] ) {<br />
307 f [ 1 ] [ 1 ] [ 0 ] = w;<br />
308 f [ 1 ] [ 1 ] [ 1 ] = W;<br />
309 }<br />
310 }<br />
311 }<br />
312 f o r ( i n t b=2; bf [ 0 ] [ 0 ] [ 1 ] ) {<br />
316 f [ 0 ] [ 1 ] [ 0 ] = f [ 0 ] [ 0 ] [ 0 ] ;<br />
317 f [ 0 ] [ 1 ] [ 1 ] = f [ 0 ] [ 0 ] [ 1 ] ;<br />
318 f [ 0 ] [ 0 ] [ 0 ] = b ;<br />
319 f [ 0 ] [ 0 ] [ 1 ] = B;<br />
320 }<br />
321 e l s e<br />
322 i f (B>f [ 0 ] [ 1 ] [ 1 ] ) {<br />
323 f [ 0 ] [ 1 ] [ 0 ] = b ;<br />
324 f [ 0 ] [ 1 ] [ 1 ] = B;<br />
325 }<br />
326 }<br />
327 }<br />
328 r e t u r n ( f ) ;<br />
329 }<br />
330<br />
331 // r e t u r n e r numrene f o r de 3 s t o e r s t e hvid og de 3 s t o e r s t e<br />
s o r t e f i g u r e , som der endnu kan p l a c e r e s b r i k opad .<br />
332 p u b l i c i n t [ ] [ ] [ ] g e t F i g s 3 ( i n t [ ] [ ] fb ) {<br />
333 i n t [ ] [ ] [ ] f = new i n t [ 2 ] [ 3 ] [ 2 ] ;<br />
334 // f [ ] [ ] [ 0 ] = f i g u r navnet (nummer) , f [ ] [ ] [ 1 ] = f i g u r e n s<br />
s t o e r r e l s e<br />
335 // f [ 1 ] [ ] [ ] = hvid f i g u r , f [ 0 ] [ ] [ ] = s o r t f i g u r<br />
336 // f [ ] [ 0 ] [ ] = s t o e r s t e f i g u r , f [ ] [ 1 ] [ ] = n a e s t s t o e r r e s t e<br />
f i g u r , f [ ] [ 2 ] [ ] = 3 . s t o e r s t e f i g u r<br />
337 f [ 1 ] [ 0 ] [ 0 ] = −1;<br />
338 f [ 1 ] [ 1 ] [ 0 ] = −1;<br />
339 f [ 1 ] [ 2 ] [ 0 ] = −1;<br />
340 f [ 0 ] [ 0 ] [ 0 ] = −2;<br />
341 f [ 0 ] [ 1 ] [ 0 ] = −2;<br />
342 f [ 0 ] [ 2 ] [ 0 ] = −2;<br />
343 f [ 1 ] [ 0 ] [ 1 ] = 0 ;<br />
344 f [ 1 ] [ 1 ] [ 1 ] = 0 ;<br />
345 f [ 1 ] [ 2 ] [ 1 ] = 0 ;<br />
346 f [ 0 ] [ 0 ] [ 1 ] = 0 ;<br />
347 f [ 0 ] [ 1 ] [ 1 ] = 0 ;<br />
348 f [ 0 ] [ 2 ] [ 1 ] = 0 ;<br />
349 i n t [ ] figN ;<br />
350 figN = findMaxFigNames ( fb ) ;<br />
351<br />
352 f o r ( i n t w=1; w
A.6 FigureMap.java 169<br />
355 i f (W>f [ 1 ] [ 0 ] [ 1 ] ) {<br />
356 f [ 1 ] [ 2 ] [ 0 ] = f [ 1 ] [ 1 ] [ 0 ] ;<br />
357 f [ 1 ] [ 2 ] [ 1 ] = f [ 1 ] [ 2 ] [ 1 ] ;<br />
358 f [ 1 ] [ 1 ] [ 0 ] = f [ 1 ] [ 0 ] [ 0 ] ;<br />
359 f [ 1 ] [ 1 ] [ 1 ] = f [ 1 ] [ 0 ] [ 1 ] ;<br />
360 f [ 1 ] [ 0 ] [ 0 ] = w;<br />
361 f [ 1 ] [ 0 ] [ 1 ] = W;<br />
362 }<br />
363 e l s e<br />
364 i f (W>f [ 1 ] [ 1 ] [ 1 ] ) {<br />
365 f [ 1 ] [ 2 ] [ 0 ] = f [ 1 ] [ 1 ] [ 0 ] ;<br />
366 f [ 1 ] [ 2 ] [ 1 ] = f [ 1 ] [ 2 ] [ 1 ] ;<br />
367 f [ 1 ] [ 1 ] [ 0 ] = w;<br />
368 f [ 1 ] [ 1 ] [ 1 ] = W;<br />
369 }<br />
370 e l s e {<br />
371 i f (W>f [ 1 ] [ 2 ] [ 1 ] ) {<br />
372 f [ 1 ] [ 2 ] [ 0 ] = w;<br />
373 f [ 1 ] [ 2 ] [ 1 ] = W;<br />
374 }<br />
375 }<br />
376 }<br />
377 f o r ( i n t b=2; bf [ 0 ] [ 0 ] [ 1 ] )<br />
381 {<br />
382 f [ 0 ] [ 1 ] [ 0 ] = f [ 0 ] [ 0 ] [ 0 ] ;<br />
383 f [ 0 ] [ 1 ] [ 1 ] = f [ 0 ] [ 0 ] [ 1 ] ;<br />
384 f [ 0 ] [ 0 ] [ 0 ] = b ;<br />
385 f [ 0 ] [ 0 ] [ 1 ] = B;<br />
386 }<br />
387 e l s e<br />
388 i f (B>f [ 0 ] [ 1 ] [ 1 ] ) {<br />
389 f [ 0 ] [ 2 ] [ 0 ] = f [ 0 ] [ 1 ] [ 0 ] ;<br />
390 f [ 0 ] [ 2 ] [ 1 ] = f [ 0 ] [ 2 ] [ 1 ] ;<br />
391 f [ 0 ] [ 1 ] [ 0 ] = b ;<br />
392 f [ 0 ] [ 1 ] [ 1 ] = B;<br />
393 }<br />
394 e l s e {<br />
395 i f (B>f [ 0 ] [ 2 ] [ 1 ] ) {<br />
396 f [ 0 ] [ 2 ] [ 0 ] = b ;<br />
397 f [ 0 ] [ 2 ] [ 1 ] = B;<br />
398 }<br />
399 }<br />
400 }<br />
401 }<br />
402 }<br />
403 r e t u r n ( f ) ;<br />
404 }<br />
405<br />
406 // r e t u r n e r e true , h v i s der e r minimum en f r i p l a d s opad<br />
f i g u r e n<br />
407 p r i v a t e boolean checkFig ( i n t f , i n t [ ] [ ] fb ) {<br />
408 f o r ( i n t c =0; c < tModel . noCols ; c++){
170 Bilag A<br />
409 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
410 i f ( fb [ c ] [ r ] == f ) {<br />
411 i f ( c < tModel . noCols −1 && fb [ c +1][ r ] == 0) {<br />
412 i f ( r < tModel . noRows−1 && fb [ c +1][ r +1] ==<br />
0)<br />
413 r e t u r n ( t r u e ) ;<br />
414 i f ( r > 0 && fb [ c +1][ r −1] == 0)<br />
415 r e t u r n ( t r u e ) ;<br />
416 i f ( c < tModel . noCols −2 && fb [ c +2][ r ] == 0)<br />
417 r e t u r n ( t r u e ) ;<br />
418 }<br />
419 i f ( c > 0 && fb [ c −1][ r ] == 0) {<br />
420 i f ( r < tModel . noRows−1 && fb [ c −1][ r +1] ==<br />
0)<br />
421 r e t u r n ( t r u e ) ;<br />
422 i f ( r > 0 && fb [ c −1][ r −1] == 0)<br />
423 r e t u r n ( t r u e ) ;<br />
424 i f ( c > 1 && fb [ c −2][ r ] == 0)<br />
425 r e t u r n ( t r u e ) ;<br />
426 }<br />
427 i f ( r < tModel . noRows−1 && fb [ c ] [ r +1] == 0) {<br />
428 i f ( c < tModel . noCols −1 && fb [ c +1][ r +1] ==<br />
0)<br />
429 r e t u r n ( t r u e ) ;<br />
430 i f ( c > 0 && fb [ c −1][ r +1] == 0)<br />
431 r e t u r n ( t r u e ) ;<br />
432 i f ( r < tModel . noRows−2 && fb [ c ] [ r +2] == 0)<br />
433 r e t u r n ( t r u e ) ;<br />
434 }<br />
435 i f ( r > 0 && fb [ c ] [ r −1] == 0) {<br />
436 i f ( c < tModel . noCols −1 && fb [ c +1][ r −1] ==<br />
0)<br />
437 r e t u r n ( t r u e ) ;<br />
438 i f ( c > 0 && fb [ c −1][ r −1] == 0)<br />
439 r e t u r n ( t r u e ) ;<br />
440 i f ( r > 1 && fb [ c ] [ r −2] == 0)<br />
441 r e t u r n ( t r u e ) ;<br />
442 }<br />
443 }<br />
444 }<br />
445 }<br />
446 r e t u r n ( f a l s e ) ;<br />
447 }<br />
448<br />
449 // f i n d e r og r e t u r n e r de h o e j s t e f i g navne anvendt i fb<br />
450 p r i v a t e i n t [ ] findMaxFigNames ( i n t [ ] [ ] fb ) {<br />
451 i n t [ ] figN = new i n t [ 2 ] ;<br />
452 f o r ( i n t c =0; c < tModel . noCols ; c++){<br />
453 f o r ( i n t r =0; r < tModel . noRows ; r++){<br />
454 i f ( fb [ c ] [ r ]%2 == 1) {<br />
455 i f ( fb [ c ] [ r ] > figN [ 1 ] )<br />
456 figN [ 1 ] = fb [ c ] [ r ] ;<br />
457 }<br />
458 i f ( fb [ c ] [ r ]%2 == 0) {<br />
459 i f ( fb [ c ] [ r ] > figN [ 0 ] )
A.7 Node.java 171<br />
460 figN [ 0 ] = fb [ c ] [ r ] ;<br />
461 }<br />
462 }<br />
463 }<br />
464 r e t u r n ( figN ) ;<br />
465 }<br />
466<br />
467 }<br />
A.7 Node.java<br />
1<br />
2 import java . u t i l . ArrayList ;<br />
3<br />
4<br />
5<br />
6 p u b l i c c l a s s Node{<br />
7 p u b l i c i n t [ ] [ ] nodeBoard ;<br />
8 p u b l i c i n t a ; // Score o f the board<br />
9 p u b l i c i n t wc ; // Whire Column<br />
10 p u b l i c i n t wr ; // White Row<br />
11 p u b l i c i n t bc ; // Black Column<br />
12 p u b l i c i n t br ; // Black Row<br />
13 p u b l i c i n t d ; // Depth<br />
14 p u b l i c ArrayList par ;<br />
15 p u b l i c ArrayList c h i l d r e n ;<br />
16 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
17<br />
18 p u b l i c Node ( Node parent ) {<br />
19 t h i s . par = new ArrayList () ;<br />
20 t h i s . c h i l d r e n = new ArrayList () ;<br />
21 f o r ( i n t i = 0 ; i < 1 2 3 ; i ++)<br />
22 f o r ( i n t j = 0 ; j < 1 2 3 ; j++)<br />
23 nodeBoard [ i ] [ j ] = 0 ;<br />
24 }<br />
25<br />
26 p u b l i c Node ( ) {<br />
27 t h i s . c h i l d r e n = new ArrayList () ;<br />
28 nodeBoard = new i n t [ 1 2 3 ] [ 1 2 3 ] ;<br />
29 f o r ( i n t i = 0 ; i < 1 2 3 ; i ++)<br />
30 f o r ( i n t j = 0 ; j < 1 2 3 ; j++)<br />
31 nodeBoard [ i ] [ j ] = 0 ;<br />
32 }<br />
33<br />
34 p u b l i c Node addChild ( Node n ) {<br />
35 i f ( n == n u l l )<br />
36 System . out . p r i n t l n (” Null002 node”+n ) ;<br />
37 t h i s . c h i l d r e n . add ( n ) ;<br />
38<br />
39 r e t u r n ( n ) ;<br />
40 }<br />
41<br />
42 // Laver en node udfra en given tur .
172 Bilag A<br />
43 p u b l i c Node createNode ( i n t t , <strong>Taiji</strong>Model tModel )<br />
44 {<br />
45 nodeBoard = tModel . getOneBoard ( t ) ;<br />
46 a = tModel . g e t D i f ( nodeBoard ) ;<br />
47 t h i s . tModel = tModel ;<br />
48 r e t u r n t h i s ;<br />
49 }<br />
50<br />
51 // Returnerer b r a e t t e t f o r en Node<br />
52 p r i v a t e i n t [ ] [ ] getNodeBoard ( Node n )<br />
53 {<br />
54 r e t u r n ( n . nodeBoard ) ;<br />
55 }<br />
56<br />
57 // Laver en node udfra givne parameter .<br />
58 p u b l i c Node createChildNode ( i n t wC, i n t wR, i n t bC , i n t bR, Node<br />
parent )<br />
59 {<br />
60 Node n = new Node ( ) ;<br />
61 i n t [ ] [ ] c l o n e ;<br />
62 c l o n e = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
63 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
64 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
65 c l o n e [ c ] [ r ] = parent . nodeBoard [ c ] [ r ] ;<br />
66 n . nodeBoard = c l o n e ;<br />
67 n . wc = wC;<br />
68 n . wr = wR;<br />
69 n . bc = bC ;<br />
70 n . br = bR ;<br />
71 n . par = new ArrayList () ;<br />
72 n . par . add ( parent ) ;<br />
73 n . d = parent . d+1;<br />
74 i f ( n . d % 2 == 0)<br />
75 n . a = tModel . noRows∗ tModel . noCols ;<br />
76 i f ( n . d % 2 == 1)<br />
77 n . a = tModel . noRows∗ tModel . noCols ;<br />
78<br />
79 r e t u r n ( n ) ;<br />
80 }<br />
81<br />
82 // Laver en kopie a f en node .<br />
83 p u b l i c Node createCloneNode ( Node org )<br />
84 {<br />
85 Node n = new Node ( ) ;<br />
86 i n t [ ] [ ] c l o n e ;<br />
87 c l o n e = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
88 f o r ( i n t c =0; c < tModel . noCols ; c++)<br />
89 f o r ( i n t r =0; r < tModel . noRows ; r++)<br />
90 c l o n e [ c ] [ r ] = org . nodeBoard [ c ] [ r ] ;<br />
91 n . nodeBoard = c l o n e ;<br />
92 n . a = tModel . g e t D i f ( nodeBoard ) ;<br />
93 n . wc = org . wc ;<br />
94 n . wr = org . wr ;<br />
95 n . bc = org . bc ;<br />
96 n . br = org . br ;
A.8 <strong>Taiji</strong>Driver.java 173<br />
97 n . par = org . par ;<br />
98 r e t u r n ( n ) ;<br />
99 }<br />
100 }<br />
A.8 <strong>Taiji</strong>Driver.java<br />
1<br />
2 c l a s s T a i j i D r i v e r<br />
3 {<br />
4<br />
5 //Main metoden , e r d r i v e r f o r a l l e de andre k l a s s e r .<br />
Konstruerer en <strong>Taiji</strong>Frame og v i s e r den .<br />
6 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s )<br />
7 {<br />
8 <strong>Taiji</strong>Frame tFrame = new <strong>Taiji</strong>Frame ( ) ;<br />
9 tFrame . showIt ( ) ;<br />
10 }<br />
11 }<br />
A.9 <strong>Taiji</strong>Frame.java<br />
1<br />
2 import java . awt . event . ∗ ;<br />
3 import javax . swing . ∗ ;<br />
4 import java . awt . event . MouseListener ;<br />
5 import java . awt . event . MouseEvent ;<br />
6<br />
7 p u b l i c c l a s s <strong>Taiji</strong>Frame extends JFrame<br />
8 {<br />
9 // V a r i a b l e r t i l k o n s t r u k t i o n e n a f modellen .<br />
10 p r i v a t e i n t noCols = 9 ;<br />
11 p r i v a t e i n t noRows = 9 ;<br />
12<br />
13 // Elementerne i framen gemmes som p u b l i c v a r i a b l e r , saa de kan<br />
r e f e r e r e s t i l f r a metoder inde i de andre e l e m e n t e r .<br />
14 p u b l i c TurnPanel uPanel ;<br />
15 p u b l i c T a i j i P a n e l tPanel ;<br />
16 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
17 p u b l i c ScorePanel whiteScore , b l a c k S c o r e ;<br />
18 p u b l i c <strong>Taiji</strong>Menu tMenu ;<br />
19<br />
20 // Constructor . Laver a l l e de f o r s k e l l i g e e l e m e n t e r og p l a c e r e r<br />
dem i e t border−l a y o u t .<br />
21 p u b l i c <strong>Taiji</strong>Frame ( )<br />
22 {<br />
23 s e t L o c a t i o n ( 1 0 0 , 100) ;<br />
24 s e t T i t l e (” T a i j i ”) ;<br />
25<br />
26 tModel = new <strong>Taiji</strong>Model ( noCols , noRows ) ;
174 Bilag A<br />
27 whiteScore = new ScorePanel ( t h i s , 1 ) ;<br />
28 b l a c k S c o r e = new ScorePanel ( t h i s , 0 ) ;<br />
29 tPanel = new T a i j i P a n e l ( t h i s ) ;<br />
30 uPanel = new TurnPanel ( t h i s ) ;<br />
31 tMenu = new <strong>Taiji</strong>Menu ( t h i s ) ;<br />
32<br />
33 getContentPane ( ) . add ( tPanel , ” Center ”) ;<br />
34 getContentPane ( ) . add ( whiteScore , ”West ”) ;<br />
35 getContentPane ( ) . add ( blackScore , ” East ”) ;<br />
36 getContentPane ( ) . add ( uPanel , ” South ”) ;<br />
37<br />
38 t h i s . setJMenuBar ( tMenu ) ;<br />
39 t h i s . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT ON CLOSE) ;<br />
40 t h i s . pack ( ) ;<br />
41 }<br />
42<br />
43 //Metode som r e p a i n t e r a l l e elementerne i framen .<br />
44 p u b l i c void r e p a i n t A l l ( )<br />
45 {<br />
46 t h i s . tPanel . r e p a i n t ( ) ;<br />
47 t h i s . whiteScore . r e p a i n t ( ) ;<br />
48 t h i s . b l a c k S c o r e . r e p a i n t ( ) ;<br />
49 t h i s . uPanel . update ( ) ;<br />
50 }<br />
51<br />
52 // Goer <strong>Taiji</strong>Frame s y n l i g r e n t g r a f i s k .<br />
53 p u b l i c void showIt ( )<br />
54 {<br />
55 s e t V i s i b l e ( t r u e ) ;<br />
56 }<br />
57<br />
58 // S k j u l e r <strong>Taiji</strong>Frame ( b l i v e r i k k e brugt )<br />
59 p u b l i c void h i d e I t ( )<br />
60 {<br />
61 s e t V i s i b l e ( f a l s e ) ;<br />
62 }<br />
63<br />
64 }<br />
A.10 <strong>Taiji</strong>Hash.java<br />
1<br />
2 p u b l i c c l a s s <strong>Taiji</strong>Hash {<br />
3 p r i v a t e <strong>Taiji</strong>Model tModel ;<br />
4 p r i v a t e i n t [ ] [ ] valueBoard ; // valueBoard , b r a e t t e t med<br />
symmetrisk ens v a e r d i e r<br />
5<br />
6<br />
7 p u b l i c <strong>Taiji</strong>Hash ( <strong>Taiji</strong>Model m)<br />
8 {<br />
9 tModel = m;<br />
10 valueBoard = new i n t [ tModel . noCols ] [ tModel . noRows ] ;<br />
11 f o r ( i n t i = 0 ; i
A.10 <strong>Taiji</strong>Hash.java 175<br />
12 f o r ( i n t j = 0 ; j=tModel . noCols /2)<br />
51 bc = 1 ;<br />
52 e l s e<br />
53 bc = 0 ;<br />
54<br />
55 i f ( tModel . noRows%2==0 && r>=tModel . noRows /2)<br />
56 br = 1 ;<br />
57 e l s e<br />
58 br = 0 ;<br />
59<br />
60 v = ( v + ( ( ( Math . abs ( tModel . noCols/2−c )+bc ) ∗ (<br />
Math . abs ( tModel . noRows/2−r )+br ) ) /2) )%maxV ;<br />
61 }<br />
62<br />
63 i f ( b [ c ] [ r ] == 1) {<br />
64 i f ( tModel . noCols%2==0 && c>=tModel . noCols /2)
176 Bilag A<br />
65 bc = 1 ;<br />
66 e l s e<br />
67 bc = 0 ;<br />
68<br />
69 i f ( tModel . noRows%2==0 && r>=tModel . noRows /2)<br />
70 br = 1 ;<br />
71 e l s e<br />
72 br = 0 ;<br />
73<br />
74 v = ( v +( (Math . abs ( tModel . noCols/2−c )+bc ) ∗ (<br />
Math . abs ( tModel . noRows/2−r )+br ) ) )%maxV ;<br />
75 }<br />
76 }<br />
77 }<br />
78 r e t u r n ( v ) ;<br />
79 }<br />
80<br />
81 // r e t u r n e r e r den h o e j s t mulige v a e r d i f o r hashFunction2<br />
82 p u b l i c i n t getMaxH2 ( ) {<br />
83 i n t maxH = ( tModel . noCols ∗ tModel . noRows ) −1;<br />
84 r e t u r n (maxH) ;<br />
85 }<br />
86<br />
87 // r e t u r n e r en hash v a e r d i som e r sammen s a t a f hashFunction 1<br />
og 2<br />
88 p u b l i c i n t hashFunction3 ( i n t [ ] [ ] b ) {<br />
89 i n t v = ( hashFunction ( b )+hashFunction2 ( b ) )%getMaxH ( ) ;<br />
90 r e t u r n ( v ) ;<br />
91 }<br />
92<br />
93 // r e t u r n e r e r den h o e j s t mulige v a e r d i f o r hashFunction3<br />
94 p u b l i c i n t getMaxH3 ( ) {<br />
95 r e t u r n ( getMaxH ( ) ) ;<br />
96 }<br />
97 }<br />
A.11 <strong>Taiji</strong>Listeners.java<br />
1<br />
2 import java . awt . event . ∗ ;<br />
3 import java . awt . ∗ ;<br />
4 import javax . swing . ∗ ;<br />
5 import java . i o . ∗ ;<br />
6<br />
7 // L i s t e n e r e n t i l s e l v e b r a e t t e t , T a i j i P a n e l .<br />
8 c l a s s T a i j i P a n e l L i s t e n e r implements MouseListener<br />
9 {<br />
10 // Variablen som i n d e h o l d e r den <strong>Taiji</strong>Frame h v o r i p a n e l e t<br />
T a i j i P a n e l L i s t e n e r b l i v e r i n i t i a l i s e r e t .<br />
11 p r i v a t e <strong>Taiji</strong>Frame tFrame ;<br />
12<br />
13 // V a r i a b l e r t i l k o o r d i n a t e r n e f r a de mouseevents som l i s t e n e r e n<br />
f a n g e r .
A.11 <strong>Taiji</strong>Listeners.java 177<br />
14 p r i v a t e i n t c l i c k C o l , clickRow ;<br />
15<br />
16 // V a r i a b l e r som bruges i mouseClicked t i l at bestemme om det e r<br />
f o e r s t e l l e r andet ryk , e l l e r t i l at gemme vinderen .<br />
17 p r i v a t e S t r i n g winner ;<br />
18<br />
19 // Constructor<br />
20 // Modtager en <strong>Taiji</strong>Frame som argument .<br />
21 p u b l i c T a i j i P a n e l L i s t e n e r ( <strong>Taiji</strong>Frame frame )<br />
22 {<br />
23 tFrame = frame ;<br />
24 }<br />
25<br />
26 //Den metode som modtager MouseEvent og k a l d e r move metoden i<br />
modellen , h v i s<br />
27 // det f l e t der k l i k k e s paa f o e r s t gang e r den f r i t .<br />
28 // Hvis s p i l l e t a f s l u t t e s i det paagaeldende ryk , v i s e r den en<br />
d i a l o g med vinderen .<br />
29 // Modtager e t MouseEvent som argument .<br />
30 p u b l i c void mouseClicked ( MouseEvent event )<br />
31 {<br />
32 i n t x , y ;<br />
33 x = event . getX ( ) ;<br />
34 y = event . getY ( ) ;<br />
35<br />
36 c l i c k C o l = x /( tFrame . tPanel . getWidth ( ) /tFrame .<br />
tModel . getNoCols ( ) ) ;<br />
37 clickRow = y /( tFrame . tPanel . getHeight ( ) /tFrame .<br />
tModel . getNoRows ( ) ) ;<br />
38 winner = tFrame . tModel . move ( c l i c k C o l , clickRow ) ;<br />
39 i f ( ! winner . e q u a l s (” None ”) )<br />
40 {<br />
41 i f ( winner . e q u a l s (”Draw”) )<br />
42 JOptionPane . showMessageDialog ( n u l l , ”<br />
The game i s a draw . \ n ” , ”Game over<br />
. ” , JOptionPane .INFORMATION MESSAGE<br />
) ;<br />
43 e l s e<br />
44 JOptionPane . showMessageDialog ( n u l l ,<br />
winner +” wins ! ” , ”Game over . ” ,<br />
JOptionPane .INFORMATION MESSAGE) ;<br />
45 }<br />
46 tFrame . r e p a i n t A l l ( ) ;<br />
47 }<br />
48<br />
49 // Metoder t i l at o v e r s k r i v e de a b s t r a k t e metoder f r a<br />
f o r a e l d r e r e n MouseListener .<br />
50 p u b l i c void mousePressed ( MouseEvent event )<br />
51 {<br />
52 }<br />
53<br />
54 p u b l i c void mouseReleased ( MouseEvent event )<br />
55 {<br />
56 }<br />
57
178 Bilag A<br />
58 p u b l i c void mouseExited ( MouseEvent event )<br />
59 {<br />
60 }<br />
61<br />
62 p u b l i c void mouseEntered ( MouseEvent event )<br />
63 {<br />
64 }<br />
65<br />
66 }<br />
67<br />
68 //Denne k l a s s e ” l y t t e r ” t i l de to knapper paa e t TurnPanel . Den kan<br />
enten s t i l l e en tur frem e l l e r en t i l b a g e .<br />
69 c l a s s TurnListener implements A c t i o n L i s t e n e r<br />
70 {<br />
71 p r i v a t e <strong>Taiji</strong>Frame tFrame ;<br />
72<br />
73 // Constructor .<br />
74 // Modtager en <strong>Taiji</strong>Frame som argument .<br />
75 p u b l i c TurnListener ( <strong>Taiji</strong>Frame frame )<br />
76 {<br />
77 tFrame = frame ;<br />
78 }<br />
79<br />
80 //Den metode der r e a g e r e r paa e t ActionEvent . S t i l l e r enten<br />
turen en frem<br />
81 // e l l e r t i l b a g e , og k a l d e r r e p a i n t A l l ( ) f r a framen .<br />
82 p u b l i c void actionPerformed ( ActionEvent event )<br />
83 {<br />
84 S t r i n g aCommand = event . getActionCommand ( ) ;<br />
85<br />
86 i f (aCommand . e q u a l s (” Next Turn ”) )<br />
87 {<br />
88 tFrame . tModel . turnForward ( ) ;<br />
89 tFrame . r e p a i n t A l l ( ) ;<br />
90 }<br />
91 e l s e<br />
92 {<br />
93 tFrame . tModel . turnBack ( ) ;<br />
94 tFrame . r e p a i n t A l l ( ) ;<br />
95 }<br />
96 }<br />
97 }<br />
98<br />
99 // L i s t e n e r e n t i l <strong>Taiji</strong>Menuen tMenu .<br />
100 c l a s s TMListener implements A c t i o n L i s t e n e r<br />
101 {<br />
102<br />
103 //En <strong>Taiji</strong>Frame som kan i n d e h o l d e tFrame , saa der kan r e f e r e r s<br />
t i l den .<br />
104 p r i v a t e <strong>Taiji</strong>Frame tFrame ;<br />
105<br />
106 // C o n s t r u c t e r .<br />
107 // Modtager en <strong>Taiji</strong>Frame som argument .<br />
108 p u b l i c TMListener ( <strong>Taiji</strong>Frame frame )<br />
109 {
A.11 <strong>Taiji</strong>Listeners.java 179<br />
110 tFrame = frame ;<br />
111 }<br />
112<br />
113 //Metode som r e a g e r e r paa det event som a k t i v e r e r l i s t e n e r e n .<br />
Konstruerer en J F i l e C h ooser der enten kan bruges t i l at<br />
gemme e l l e r<br />
114 // aabne gemte s p i l . Kan ogsaa lukke programmet ned e l l e r s t a r t e<br />
e t nyt s p i l .<br />
115 // Modtager e t ActionEvent som argument .<br />
116 p u b l i c void actionPerformed ( ActionEvent evt )<br />
117 {<br />
118 J F i leChooser c h o o s e r = new J F i l e C hooser ( ) ;<br />
119<br />
120 i f ( evt . g e t S o u r c e ( ) i n s t a n c e o f JMenuItem )<br />
121 {<br />
122 S t r i n g command = evt . getActionCommand ( ) ;<br />
123 i f (command . e q u a l s (”Same s e t t i n g s ”) )<br />
124 {<br />
125 tFrame . tModel . r e s e t ( ) ;<br />
126 tFrame . r e p a i n t A l l ( ) ;<br />
127 }<br />
128 e l s e i f (command . e q u a l s (” Change s e t t i n g s ”) )<br />
129 {<br />
130 T a i j i S e t t i n g s s e t t i n g s = new T a i j i S e t t i n g s (<br />
tFrame ) ;<br />
131 s e t t i n g s . showIt ( ) ;<br />
132 }<br />
133 e l s e i f (command . e q u a l s (” Save ”) )<br />
134 {<br />
135 i n t returnVal = c h o o s e r . showSaveDialog (<br />
tFrame . tPanel ) ;<br />
136 i f ( returnVal == JFileChooser .<br />
APPROVE OPTION)<br />
137 {<br />
138 boolean save = t r u e ;<br />
139 i f ( c h o o s e r . g e t S e l e c t e d F i l e ( ) .<br />
e x i s t s ( ) == t r u e )<br />
140 i f ( JOptionPane .<br />
showConfirmDialog ( n u l l , ”<br />
F i l e a l r e a d y e x i s t s ,<br />
o v e r w r i t e ?” , ”Warning ” ,<br />
JOptionPane . YES NO OPTION)<br />
!= JOptionPane . YES OPTION)<br />
141 save = f a l s e ;<br />
142<br />
143 i f ( save == t r u e )<br />
144 {<br />
145 i n t noCols = tFrame . tModel .<br />
getNoCols ( ) ;<br />
146 i n t noRows = tFrame . tModel .<br />
getNoRows ( ) ;<br />
147 i n t [ ] [ ] [ ] board = tFrame .<br />
tModel . getBoard ( ) ;<br />
148 i n t lastTurn = board<br />
[ 0 ] [ 0 ] [ 0 ] ;
180 Bilag A<br />
149 S t r i n g t x t = ” ” ;<br />
150 t x t = t x t + lastTurn + ”T” ;<br />
151 f o r ( i n t t =1; t
A.11 <strong>Taiji</strong>Listeners.java 181<br />
181 FileReader l o a d e r = new<br />
FileReader ( c h o o s e r .<br />
g e t S e l e c t e d F i l e ( ) ) ;<br />
182 BufferedReader input = new<br />
BufferedReader ( l o a d e r ) ;<br />
183 S t r i n g l i n e = input .<br />
readLine ( ) ;<br />
184 i n t pos = 0 ;<br />
185 S t r i n g l a s t T u r n S t r i n g = ” ” ;<br />
186 w h i l e ( l i n e . charAt ( pos ) !=<br />
’T’ )<br />
187 {<br />
188 l a s t T u r n S t r i n g =<br />
l a s t T u r n S t r i n g<br />
+ l i n e . charAt (<br />
pos ) ;<br />
189 pos++;<br />
190 }<br />
191 pos++;<br />
192 i n t lastTurn = I n t e g e r .<br />
p a r s e I n t ( l a s t T u r n S t r i n g<br />
) ;<br />
193 board [ 0 ] [ 0 ] [ 0 ] = lastTurn ;<br />
194 f o r ( i n t t =1; t
182 Bilag A<br />
l o a d i n g the f i l e . ” ) ;<br />
209 }<br />
210 }<br />
211 }<br />
212 e l s e i f (command . e q u a l s (” Exit ”) )<br />
213 {<br />
214 System . e x i t ( 0 ) ;<br />
215 }<br />
216 e l s e i f (command . e q u a l s (” Rules ”) )<br />
217 {<br />
218 JOptionPane . showMessageDialog ( n u l l , ” Each<br />
p l a y e r t a k e s t u r n s p l a c i n g one p e i c e on<br />
the board . \ nAll p i e c e s has a Dark and<br />
a Light end . \nThe winner i s the one to<br />
have the g r e a s t number\ nof t h i e r<br />
c o l o u r placed t o g e h t e r i n two f i g u r e s . \<br />
nOnly the two b i g g e s t f i g u r e s count f o r<br />
each p l a y e r . ” , ”Game r u l e s ” ,<br />
JOptionPane .INFORMATION MESSAGE) ;<br />
219 }<br />
220 e l s e i f (command . e q u a l s (” About ”) )<br />
221 {<br />
222 JOptionPane . showMessageDialog ( n u l l , ”The<br />
boardgame , T a i j i i s the c r e a t i o n o f<br />
223 }<br />
224 }<br />
225 }<br />
226 }<br />
A.12 <strong>Taiji</strong>Menu.java<br />
Nà c○stor Romeral Andrà c○s \ nThis<br />
implementation was made by Morten Rask<br />
” , ”About T a i j i ” , JOptionPane .<br />
INFORMATION MESSAGE) ;<br />
1<br />
2 import java . awt . event . ∗ ;<br />
3 import javax . swing . ∗ ;<br />
4 import java . awt . ∗ ;<br />
5<br />
6 //Denne k l a s s e e r menuen som e r p l a c e r e t i <strong>Taiji</strong>Frame . Den<br />
i n d e h o l d e r menu<br />
7 // o b j e k t e r t i l at s t a r t e nyt s p i l , samt hente e l l e r gemme s p i l .<br />
8 //Der e r ogsaa mulighed f o r at l a e s e r e g l e r n e .<br />
9 // <strong>Taiji</strong>Menu e r nedarvet f r a JMenuBar .<br />
10 c l a s s <strong>Taiji</strong>Menu extends JMenuBar<br />
11 {<br />
12<br />
13 // C o n s t r u c t e r . Laver a l l e menu−o b j e k t e r og t i l f o e j e r en<br />
l i s t e n e r t i l dem .<br />
14 // Modtager en <strong>Taiji</strong>Frame som argument og g i v e r den v i d e r e t i l<br />
l i s t e n e r e n .<br />
15 p u b l i c <strong>Taiji</strong>Menu ( <strong>Taiji</strong>Frame frame )
A.13 <strong>Taiji</strong>Model.java 183<br />
16 {<br />
17 JMenu fileMenu = new JMenu(”Game”) ;<br />
18 add ( fileMenu ) ;<br />
19<br />
20 //JMenuItem gameItem = new JMenuItem (”New game ”) ;<br />
21 JMenuItem saveItem = new JMenuItem (” Save ”) ;<br />
22 JMenuItem loadItem = new JMenuItem (” Load ”) ;<br />
23 JMenuItem e x i t I t e m = new JMenuItem (” Exit ”) ;<br />
24<br />
25 JMenu subMenu = new JMenu(”New game ”) ;<br />
26 JMenuItem sameSet = new JMenuItem (”Same s e t t i n g s ”) ;<br />
27 JMenuItem changeSet = new JMenuItem (” Change s e t t i n g s ”) ;<br />
28 subMenu . add ( sameSet ) ;<br />
29 subMenu . add ( changeSet ) ;<br />
30<br />
31 fileMenu . add ( subMenu ) ;<br />
32 fileMenu . addSeparator ( ) ;<br />
33 fileMenu . add ( saveItem ) ;<br />
34 fileMenu . add ( loadItem ) ;<br />
35 fileMenu . addSeparator ( ) ;<br />
36 fileMenu . add ( e x i t I t e m ) ;<br />
37<br />
38 JMenu helpMenu = new JMenu(” Help ”) ;<br />
39 add ( helpMenu ) ;<br />
40<br />
41 JMenuItem r u l e s I t e m = new JMenuItem (” Rules ”) ;<br />
42 JMenuItem aboutItem = new JMenuItem (” About ”) ;<br />
43<br />
44 helpMenu . add ( r u l e s I t e m ) ;<br />
45 helpMenu . add ( aboutItem ) ;<br />
46<br />
47 TMListener TMLi = new TMListener ( frame ) ;<br />
48<br />
49 sameSet . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
50 changeSet . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
51 saveItem . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
52 loadItem . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
53 e x i t I t e m . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
54 r u l e s I t e m . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
55 aboutItem . a d d A c t i o n L i s t e n e r (TMLi) ;<br />
56 }<br />
57<br />
58 }<br />
A.13 <strong>Taiji</strong>Model.java<br />
1 import java . u t i l . Date ; // b e n y t t e s t i l at tage t i d paa AI ’ erne<br />
2<br />
3 // Klassen <strong>Taiji</strong>Model som r e p r a e s e n t e r e r h e l e den ikke −g r a f i s k e d e l<br />
a f s p i l l e t .<br />
4 p u b l i c c l a s s <strong>Taiji</strong>Model<br />
5 {<br />
6
184 Bilag A<br />
7 p u b l i c AI<strong>Taiji</strong>Minimax minimax ;<br />
8 p u b l i c FigureMap fMap ;<br />
9 p u b l i c Board tBoard ;<br />
10 p u b l i c <strong>Taiji</strong>Hash tHash ;<br />
11 p u b l i c T a i j i P r i n t t P r i n t ;<br />
12 p u b l i c AI<strong>Taiji</strong>AlphaBeta alphaBeta ;<br />
13 p u b l i c AI<strong>Taiji</strong>PureAlphaBeta pureAlphaBeta ;<br />
14 p u b l i c AI<strong>Taiji</strong>Minimax2 minimax2 ;<br />
15 p u b l i c AI<strong>Taiji</strong>Growth growth ;<br />
16 p u b l i c AI<strong>Taiji</strong>LocalAreaAB localAreaAB ;<br />
17<br />
18<br />
19 // V a r i a b l e r<br />
20 p u b l i c i n t noRows , noCols ; // a n t a l l e t a f r a e k k e r og kolonner<br />
21 p u b l i c i n t maxTurns = 1 0 0 0 ; // max a n t a l t u r e programmet kan<br />
haandtere<br />
22 p u b l i c i n t maxScore ; // Score h v i s e t h e l t b r a e t var daekket a f<br />
en f a r v e .<br />
23 p u b l i c i n t maxS ; // den maximale s c o r e f o r en s p i l l e r .<br />
24 // ( h v i s a l l e b r i k k e r a f en f a r v e e r med i<br />
enten den s t o e r s t e e l l e r n a e s t s t o e r s t e<br />
f i g u r )<br />
25<br />
26 f i n a l p r i v a t e i n t white = 1 , black = 0 , n e u t r a l = 2 ; //<br />
Konstanter f o r de f o r s k e l l i g e b r i k k e r paa b r a e t t e t .<br />
27<br />
28 // o e j e b l i k s −i n f o r m a t i o n f o r s p i l l e t .<br />
29 p r i v a t e i n t c u r r e n t P l a y e r = 1 ;<br />
30 p u b l i c i n t currentTurn = 1 , noTurns = 1 , showTurn = 0 , s t a r t e r<br />
= 1 ;<br />
31 p r i v a t e i n t whScore =0, b l S c o r e =0;<br />
32 p r i v a t e i n t whitePlayer = 0 , b l a c k P l a y e r = 2 ; // 0 human , 1<br />
minimax , 2 ab , 3 pure ab , 4 growth , 5 minimax2 , 6<br />
localAreaAB<br />
33<br />
34 p r i v a t e i n t preCol , preRow ; // husker f o r r i g e k l i k , som sammen<br />
med det nye k l i k b l i v e r t i l p l a c e r i n g e n a f en b r i k .<br />
35 p r i v a t e boolean c l i c k = f a l s e ;<br />
36 p r i v a t e boolean gameOver = f a l s e ;<br />
37<br />
38<br />
39 // Konstruktor . Laver b r a e t t e t . Modtager a n t a l l e t a f s o e j l e r og<br />
r a e k k e r som argumenter .<br />
40 p u b l i c <strong>Taiji</strong>Model ( i n t col , i n t row )<br />
41 {<br />
42 noCols = c o l ;<br />
43 minimax = new AI<strong>Taiji</strong>Minimax ( t h i s ) ;<br />
44 alphaBeta = new AI<strong>Taiji</strong>AlphaBeta ( t h i s ) ;<br />
45 pureAlphaBeta = new AI<strong>Taiji</strong>PureAlphaBeta ( t h i s ) ;<br />
46 minimax2 = new AI<strong>Taiji</strong>Minimax2 ( t h i s ) ;<br />
47 growth = new AI<strong>Taiji</strong>Growth ( t h i s ) ;<br />
48 localAreaAB = new AI<strong>Taiji</strong>LocalAreaAB ( t h i s ) ;<br />
49 fMap = new FigureMap ( t h i s ) ;<br />
50 tBoard = new Board ( t h i s ) ;<br />
51 tHash = new <strong>Taiji</strong>Hash ( t h i s ) ;
A.13 <strong>Taiji</strong>Model.java 185<br />
52 t P r i n t = new T a i j i P r i n t ( t h i s ) ;<br />
53 noRows = row ;<br />
54 tBoard . board = new i n t [ maxTurns ] [ noCols ] [ noRows ] ;<br />
55 maxScore = noCols ∗noRows ;<br />
56 maxS = noCols ∗noRows / 2 ;<br />
57 r e s e t ( ) ;<br />
58 }<br />
59<br />
60<br />
61 // Reset . Toemmer b r a e t t e t , s a e t t e r o e j e b l i k s v a e r d i e r n e t i l<br />
u d g a n g s p o s i t i o n e n .<br />
62 p u b l i c void r e s e t ( )<br />
63 {<br />
64 currentTurn = 1 ;<br />
65 showTurn = 0 ;<br />
66 f o r ( i n t c = 0 ; c < noCols ; c++)<br />
67 {<br />
68 f o r ( i n t r = 0 ; r < noRows ; r++)<br />
69 {<br />
70 tBoard . s e t P i e c e ( c , r , 2 ) ;<br />
71 }<br />
72 }<br />
73 c u r r e n t P l a y e r = 1 ;<br />
74 tBoard . board [ 0 ] [ 0 ] [ 0 ] = 1 ;<br />
75 }<br />
76<br />
77<br />
78 // haandtere t r a e k f o r menneskelig s p i l l e r e r og AI ’ erne<br />
79 // r e t u r n e r e om der e r en v i n d e r .<br />
80 p u b l i c S t r i n g move ( i n t curCol , i n t curRow )<br />
81 {<br />
82 S t r i n g winner = ”None ” ;<br />
83<br />
84 i f ( showTurn % 2 != s t a r t e r ) { // == 0 , s t a r t e r s p i l l e r e n (<br />
hvid ) , == 1 s t a r t e r ai ’ en ( s o r t )<br />
85 i f ( whitePlayer == 0)<br />
86 playerTurn ( curCol , curRow , f a l s e ) ;<br />
87 i f ( whitePlayer == 2)<br />
88 alphaBetaTurn ( f a l s e ) ;<br />
89 i f ( whitePlayer == 4)<br />
90 growthTurn ( f a l s e ) ;<br />
91 i f ( whitePlayer == 6)<br />
92 localAreaABTurn ( f a l s e ) ;<br />
93<br />
94 }<br />
95 e l s e<br />
96 {<br />
97 i f ( b l a c k P l a y e r == 0)<br />
98 playerTurn ( curCol , curRow , t r u e ) ;<br />
99 i f ( b l a c k P l a y e r == 1)<br />
100 minimaxTurn ( ) ;<br />
101 i f ( b l a c k P l a y e r == 2)<br />
102 alphaBetaTurn ( t r u e ) ;<br />
103 i f ( b l a c k P l a y e r == 3)<br />
104 pureAlphaBetaTurn ( ) ;
186 Bilag A<br />
105 i f ( b l a c k P l a y e r == 4)<br />
106 growthTurn ( t r u e ) ;<br />
107 i f ( b l a c k P l a y e r == 5)<br />
108 minimax2Turn ( ) ;<br />
109 i f ( b l a c k P l a y e r == 6)<br />
110 localAreaABTurn ( t r u e ) ;<br />
111 }<br />
112<br />
113 switch ( gameOver ( ) )<br />
114 {<br />
115 c a s e −1:<br />
116 break ;<br />
117 c a s e 0 :<br />
118 winner = ” Black ” ;<br />
119 r e t u r n ( winner ) ;<br />
120 c a s e 1 :<br />
121 winner = ”White ” ;<br />
122 r e t u r n ( winner ) ;<br />
123 c a s e 2 :<br />
124 winner = ”Draw ” ;<br />
125 r e t u r n ( winner ) ;<br />
126 }<br />
127<br />
128<br />
129<br />
130 r e t u r n ( winner ) ;<br />
131 }<br />
132<br />
133 // Lader den menneskelige s p i l l e r f o r e t a g e e t ryk<br />
134 // F o r e t a g e r e t ryk , h v i s det e r l o v l i g t . ( Et ryk e r d e l t op i<br />
en hvid og en s o r t d e l )<br />
135 // Modtager p o s i t i o n f r a k l i k som argument<br />
136 p r i v a t e void playerTurn ( i n t curCol , i n t curRow , boolean b ) {<br />
137 i n t b1 = 1 ;<br />
138 i n t b2 = 0 ;<br />
139 i f ( b ) {<br />
140 b1=0;<br />
141 b2=1;<br />
142 }<br />
143<br />
144 i f ( c l i c k == f a l s e )<br />
145 {<br />
146 i f ( checkMove ( tBoard . board [ currentTurn ] , curCol ,<br />
curRow ) )<br />
147 {<br />
148 tBoard . copyBoard ( ) ;<br />
149 currentTurn++;<br />
150 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
151 tBoard . s e t P i e c e ( curCol , curRow , b1 ) ;<br />
152 c l i c k = t r u e ;<br />
153 preCol = curCol ;<br />
154 preRow = curRow ;<br />
155 tBoard . getOneBoard ( currentTurn ) ;<br />
156 }<br />
157 }
A.13 <strong>Taiji</strong>Model.java 187<br />
158 e l s e<br />
159 {<br />
160 i f ( checkMove ( tBoard . board [ currentTurn ] , curCol , curRow<br />
) ) {<br />
161 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
162 tBoard . s e t P i e c e ( curCol , curRow , b2 ) ;<br />
163 c u r r e n t P l a y e r = ( c u r r e n t P l a y e r +1) % 2 ;<br />
164 c l i c k = f a l s e ;<br />
165 preCol = curCol ;<br />
166 preRow = curRow ;<br />
167 showTurn++;<br />
168 }<br />
169 e l s e {<br />
170 tBoard . s e t P i e c e ( preCol , preRow , 2) ;<br />
171 preCol = curCol ;<br />
172 preRow = curRow ;<br />
173 c l i c k = f a l s e ;<br />
174 currentTurn −−;<br />
175 }<br />
176<br />
177 }<br />
178 }<br />
179<br />
180 // f o r e t a g e r e t t r a e k ved h j a e l p a f minimax ai ’ en . ( s p i l l e r kun<br />
som s o r t )<br />
181 p r i v a t e void minimaxTurn ( ) {<br />
182 Date time = new Date ( ) ;<br />
183 long t1 = time . getTime ( ) ;<br />
184 minimax . c r e a t e T r e e ( ) ;<br />
185 Node n ;<br />
186 n = minimax . returnMoveMirRot ( ) ;<br />
187 tBoard . copyBoard ( ) ;<br />
188 currentTurn++;<br />
189 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
190 showTurn++;<br />
191 tBoard . s e t P i e c e ( n . wc , n . wr , white ) ;<br />
192 tBoard . s e t P i e c e ( n . bc , n . br , black ) ;<br />
193 Date time2 = new Date ( ) ;<br />
194 long t2 = time2 . getTime ( ) ;<br />
195 long t3 = t2−t1 ;<br />
196 System . out . p r i n t l n (”TM − minimaxTurn time : ”+t3 ) ;<br />
197 }<br />
198<br />
199 // f o r e t a g e r e t t r a e k ved h j a e l p a f AlphaBeta ai ’ en .<br />
200 // b = t r u e h v i s den s k a l s p i l l e s o r t , f a l s e f o r hvid<br />
201 p r i v a t e void alphaBetaTurn ( boolean b ) {<br />
202 Date time = new Date ( ) ;<br />
203 long t1 = time . getTime ( ) ;<br />
204 Node n ;<br />
205 n = alphaBeta . returnMove ( b ) ;<br />
206 tBoard . copyBoard ( ) ;<br />
207 currentTurn++;<br />
208 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
209 showTurn++;<br />
210 tBoard . s e t P i e c e ( n . wc , n . wr , white ) ;
188 Bilag A<br />
211 tBoard . s e t P i e c e ( n . bc , n . br , black ) ;<br />
212 Date time2 = new Date ( ) ;<br />
213 long t2 = time2 . getTime ( ) ;<br />
214 long t3 = t2−t1 ;<br />
215 System . out . p r i n t l n (”TM − ABTurn time : ”+t3 ) ;<br />
216 }<br />
217 // f o r e t a g e r e t t r a e k ved h j a e l p a f pureAlphaBeta AI ’ en . (<br />
s p i l l e r kun som s o r t )<br />
218 p r i v a t e void pureAlphaBetaTurn ( ) {<br />
219 Date time = new Date ( ) ;<br />
220 long t1 = time . getTime ( ) ;<br />
221 Node n ;<br />
222 n = pureAlphaBeta . returnMoveBlack ( ) ;<br />
223 tBoard . copyBoard ( ) ;<br />
224 currentTurn++;<br />
225 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
226 showTurn++;<br />
227 tBoard . s e t P i e c e ( n . wc , n . wr , white ) ;<br />
228 tBoard . s e t P i e c e ( n . bc , n . br , black ) ;<br />
229 Date time2 = new Date ( ) ;<br />
230 long t2 = time2 . getTime ( ) ;<br />
231 long t3 = t2−t1 ;<br />
232 System . out . p r i n t l n (”TM − PureABTurn time : ”+t3 ) ;<br />
233 }<br />
234 // f o r e t a g e r e t t r a e k ved h j a e l p a f minimax2 AI ’ en . ( s p i l l e r<br />
kun som s o r t )<br />
235 p r i v a t e void minimax2Turn ( ) {<br />
236 Date time = new Date ( ) ;<br />
237 long t1 = time . getTime ( ) ;<br />
238 Node n ;<br />
239 n = minimax2 . returnMoveBlack ( ) ;<br />
240 tBoard . copyBoard ( ) ;<br />
241 currentTurn++;<br />
242 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
243 showTurn++;<br />
244 tBoard . s e t P i e c e ( n . wc , n . wr , white ) ;<br />
245 tBoard . s e t P i e c e ( n . bc , n . br , black ) ;<br />
246 Date time2 = new Date ( ) ;<br />
247 long t2 = time2 . getTime ( ) ;<br />
248 long t3 = t2−t1 ;<br />
249 System . out . p r i n t l n (”TM − growthTurn time : ”+t3 ) ;<br />
250 }<br />
251 // f o r e t a g e r e t t r a e k ved h j a e l p a f Growth AI ’ en .<br />
252 // b = t r u e h v i s den s k a l s p i l l e s o r t , f a l s e f o r hvid<br />
253 p r i v a t e void growthTurn ( boolean b ) {<br />
254 Date time = new Date ( ) ;<br />
255 long t1 = time . getTime ( ) ;<br />
256 Node n ;<br />
257 n = growth . returnMove ( b ) ;<br />
258 tBoard . copyBoard ( ) ;<br />
259 currentTurn++;<br />
260 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
261 showTurn++;<br />
262 tBoard . s e t P i e c e ( n . wc , n . wr , white ) ;<br />
263 tBoard . s e t P i e c e ( n . bc , n . br , black ) ;
A.13 <strong>Taiji</strong>Model.java 189<br />
264 Date time2 = new Date ( ) ;<br />
265 long t2 = time2 . getTime ( ) ;<br />
266 long t3 = t2−t1 ;<br />
267 System . out . p r i n t l n (”TM − growthTurn time : ”+t3 ) ;<br />
268 }<br />
269<br />
270 // f o r e t a g e r e t t r a e k ved h j a e l p a f LocalArea AI ’ en .<br />
271 // b = t r u e h v i s den s k a l s p i l l e s o r t , f a l s e f o r hvid<br />
272 p r i v a t e void localAreaABTurn ( boolean b ) {<br />
273 Date time = new Date ( ) ;<br />
274 long t1 = time . getTime ( ) ;<br />
275 Node n ;<br />
276 n = localAreaAB . returnMove ( b ) ;<br />
277 tBoard . copyBoard ( ) ;<br />
278 currentTurn++;<br />
279 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;<br />
280 showTurn++;<br />
281 tBoard . s e t P i e c e ( n . wc , n . wr , white ) ;<br />
282 tBoard . s e t P i e c e ( n . bc , n . br , black ) ;<br />
283 Date time2 = new Date ( ) ;<br />
284 long t2 = time2 . getTime ( ) ;<br />
285 long t3 = t2−t1 ;<br />
286 System . out . p r i n t l n (”TM − LAABTurn time : ”+t3 ) ;<br />
287 }<br />
288<br />
289 // Bestemmer om der e r n o g l e l o v l i g e ryk t i l b a g e .<br />
290 p u b l i c boolean movesLeft ( )<br />
291 {<br />
292 f o r ( i n t c =0; c < noCols ; c++)<br />
293 {<br />
294 f o r ( i n t r =0; r < noRows−1; r++)<br />
295 {<br />
296 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 2 &&<br />
tBoard . board [ currentTurn ] [ c ] [ r +1] == 2<br />
)<br />
297 r e t u r n ( t r u e ) ;<br />
298 }<br />
299 }<br />
300 f o r ( i n t c =0; c < noCols −1; c++)<br />
301 {<br />
302 f o r ( i n t r =0; r < noRows ; r++)<br />
303 {<br />
304 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 2 &&<br />
tBoard . board [ currentTurn ] [ c +1][ r ] == 2<br />
)<br />
305 r e t u r n ( t r u e ) ;<br />
306 }<br />
307 }<br />
308 r e t u r n ( f a l s e ) ;<br />
309 }<br />
310<br />
311 // Bestemmer om der e r n o g l e l o v l i g e ryk t i l b a g e f o r Noden n .<br />
312 p u b l i c boolean movesLeftN ( Node n )<br />
313 {<br />
314 f o r ( i n t c =0; c < noCols ; c++)
190 Bilag A<br />
315 {<br />
316 f o r ( i n t r =0; r < noRows−1; r++)<br />
317 {<br />
318 i f ( n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c<br />
] [ r +1] == 2 )<br />
319 r e t u r n ( t r u e ) ;<br />
320 }<br />
321 }<br />
322 f o r ( i n t c =0; c < noCols −1; c++)<br />
323 {<br />
324 f o r ( i n t r =0; r < noRows ; r++)<br />
325 {<br />
326 i f ( n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c<br />
+1][ r ] == 2 )<br />
327 r e t u r n ( t r u e ) ;<br />
328 }<br />
329 }<br />
330 r e t u r n ( f a l s e ) ;<br />
331 }<br />
332<br />
333 // r e t u r n e r e r e t g y l d i g t t r a e k<br />
334 p u b l i c i n t [ ] getAMove ( Node n ) {<br />
335 i n t [ ] m = new i n t [ 4 ] ;<br />
336 f o r ( i n t c =0; c < noCols ; c++)<br />
337 {<br />
338 f o r ( i n t r =0; r < noRows−1; r++)<br />
339 {<br />
340 i f ( n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c ] [ r +1]<br />
== 2 ) {<br />
341 m[ 0 ] = c ;<br />
342 m[ 1 ] = r ;<br />
343 m[ 2 ] = c ;<br />
344 m[ 3 ] = r +1;<br />
345 r e t u r n (m) ;<br />
346 }<br />
347 }<br />
348 }<br />
349 f o r ( i n t c =0; c < noCols −1; c++){<br />
350 {<br />
351 f o r ( i n t r =0; r < noRows ; r++)<br />
352 {<br />
353 i f ( n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c +1][ r ]<br />
== 2 ) {<br />
354 m[ 0 ] = c ;<br />
355 m[ 1 ] = r ;<br />
356 m[ 2 ] = c +1;<br />
357 m[ 3 ] = r ;<br />
358 r e t u r n (m) ;<br />
359 }<br />
360 }<br />
361 }<br />
362 }<br />
363 r e t u r n (m) ;<br />
364 }<br />
365
A.13 <strong>Taiji</strong>Model.java 191<br />
366 // Undersoeger om e t ryk e r l o v l i g t i s p i l l e t s nuvaerende tur .<br />
367 // Modtager p o s i t i o n e n der rykkes f r a og t i l som argumenter ,<br />
r e t u r n e r e r t r u e h v i s rykket e r l o v l i g t .<br />
368 p u b l i c boolean checkMove ( i n t [ ] [ ] b , i n t curCol , i n t curRow )<br />
369 {<br />
370 boolean r e s u l t = f a l s e ;<br />
371 i f ( c l i c k == f a l s e )<br />
372 {<br />
373 // M i d t e r s e k t i o n e n<br />
374 i f ( ( curCol > 0) && ( curCol < noCols −1) && ( curRow > 0) &&<br />
( curRow < noRows−1) )<br />
375 {<br />
376 i f ( checkMidle ( b , curCol , curRow ) )<br />
377 {<br />
378 r e s u l t = t r u e ;<br />
379 }<br />
380 r e t u r n ( r e s u l t ) ;<br />
381 }<br />
382 e l s e<br />
383 {<br />
384 // Venstre s i d e<br />
385 i f ( ( curCol == 0) && ( curRow > 0) && ( curRow < noRows<br />
−1) )<br />
386 {<br />
387 i f ( c h e c k L e f t ( b , curCol , curRow ) )<br />
388 {<br />
389 r e s u l t = t r u e ;<br />
390 }<br />
391 r e t u r n ( r e s u l t ) ;<br />
392 }<br />
393 e l s e<br />
394 {<br />
395 // Hoejre s i d e<br />
396 i f ( ( curCol == noCols −1) && ( curRow > 0) && ( curRow<br />
< noRows−1) )<br />
397 {<br />
398 i f ( checkRight ( b , curCol , curRow ) )<br />
399 {<br />
400 r e s u l t = t r u e ;<br />
401 }<br />
402 r e t u r n ( r e s u l t ) ;<br />
403 }<br />
404 e l s e<br />
405 {<br />
406 //Toppen<br />
407 i f ( ( curCol > 0) && ( curCol < noCols −1) && (<br />
curRow == 0) )<br />
408 {<br />
409 i f ( checkTop ( b , curCol , curRow ) )<br />
410 {<br />
411 r e s u l t = t r u e ;<br />
412 }<br />
413 r e t u r n ( r e s u l t ) ;<br />
414 }<br />
415 e l s e
192 Bilag A<br />
416 {<br />
417 //Bunden<br />
418 i f ( ( curCol > 0) && ( curCol < noCols −1) &&<br />
( curRow == noRows−1) )<br />
419 {<br />
420 i f ( checkBottom ( b , curCol , curRow ) )<br />
421 {<br />
422 r e s u l t = t r u e ;<br />
423 }<br />
424 r e t u r n ( r e s u l t ) ;<br />
425 }<br />
426 e l s e<br />
427 {<br />
428 // o e v e r s t e v e n s t r e h j o e r n e<br />
429 i f ( curCol == 0 && curRow == 0)<br />
430 {<br />
431 i f ( checkTLC ( b , curCol , curRow ) )<br />
432 {<br />
433 r e s u l t = t r u e ;<br />
434 }<br />
435 r e t u r n ( r e s u l t ) ;<br />
436 }<br />
437 e l s e<br />
438 {<br />
439 // o e v e r s t e h o e j r e h j o e r n e<br />
440 i f ( curCol == noCols −1 && curRow ==<br />
0)<br />
441 {<br />
442 i f ( checkTRC ( b , curCol , curRow )<br />
)<br />
443 {<br />
444 r e s u l t = t r u e ;<br />
445 }<br />
446 r e t u r n ( r e s u l t ) ;<br />
447 }<br />
448 e l s e<br />
449 {<br />
450 // Nederste v e n s t r e h j o e r n e<br />
451 i f ( curCol == 0 && curRow ==<br />
noRows−1)<br />
452 {<br />
453 i f ( checkBLC ( b , curCol ,<br />
curRow ) )<br />
454 {<br />
455 r e s u l t = t r u e ;<br />
456 }<br />
457 r e t u r n ( r e s u l t ) ;<br />
458 }<br />
459 e l s e<br />
460 {<br />
461 // Nederste h o e j r e h j o e r n e<br />
462 i f ( curCol == noCols −1 &&<br />
curRow == noRows−1)<br />
463 {
A.13 <strong>Taiji</strong>Model.java 193<br />
464 i f ( checkBRC ( b , curCol ,<br />
curRow ) )<br />
465 {<br />
466 r e s u l t = t r u e ;<br />
467 }<br />
468 r e t u r n ( r e s u l t ) ;<br />
469 }<br />
470 }<br />
471 }<br />
472 }<br />
473 }<br />
474 }<br />
475 }<br />
476 }<br />
477 }<br />
478 }<br />
479 e l s e<br />
480 // check f o r andet k l i k ( p l a c e r i n g e n a f den s o r t e d e l a f<br />
brikken )<br />
481 i f ( ( b [ curCol ] [ curRow ] == 2) && ( ( ( curCol == preCol +1) && (<br />
curRow == preRow ) ) | | ( ( curCol == preCol −1) && ( curRow<br />
== preRow ) ) | | ( ( curCol == preCol ) && ( curRow ==<br />
preRow+1) ) | | ( ( curCol == preCol ) && ( curRow == preRow<br />
−1) ) ) )<br />
482 {<br />
483 r e s u l t = t r u e ;<br />
484 r e t u r n ( r e s u l t ) ;<br />
485 }<br />
486 r e t u r n ( r e s u l t ) ;<br />
487 }<br />
488<br />
489 // anvendes i checkMove<br />
490 p r i v a t e boolean checkMidle ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
491 {<br />
492 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | ( b [ Col ] [<br />
Row−1] == 2 ) | | ( b [ Col +1][Row ] == 2 ) | | ( b [ Col −1][Row ] ==<br />
2 ) ) ) )<br />
493 {<br />
494 r e t u r n ( t r u e ) ;<br />
495 }<br />
496 r e t u r n ( f a l s e ) ;<br />
497 }<br />
498<br />
499 // anvendes i checkMove<br />
500 p r i v a t e boolean c h e c k L e f t ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
501 {<br />
502 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | ( b [ Col ] [<br />
Row−1] == 2 ) | | ( b [ Col +1][Row ] == 2 ) ) ) )<br />
503 {<br />
504 r e t u r n ( t r u e ) ;<br />
505 }<br />
506 r e t u r n ( f a l s e ) ;<br />
507 }<br />
508<br />
509 // anvendes i checkMove
194 Bilag A<br />
510 p r i v a t e boolean checkRight ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
511 {<br />
512 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | ( b [ Col<br />
] [ Row−1] == 2 ) | | ( b [ Col −1][Row ] == 2 ) ) ) )<br />
513 {<br />
514 r e t u r n ( t r u e ) ;<br />
515 }<br />
516 r e t u r n ( f a l s e ) ;<br />
517 }<br />
518<br />
519 // anvendes i checkMove<br />
520 p r i v a t e boolean checkTop ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
521 {<br />
522 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | ( b [ Col<br />
+1][Row ] == 2 ) | | ( b [ Col −1][Row ] == 2 ) ) ) )<br />
523 {<br />
524 r e t u r n ( t r u e ) ;<br />
525 }<br />
526 r e t u r n ( f a l s e ) ;<br />
527 }<br />
528<br />
529 // anvendes i checkMove<br />
530 p r i v a t e boolean checkBottom ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
531 {<br />
532 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row−1] == 2 ) | | ( b [ Col<br />
+1][Row ] == 2 ) | | ( b [ Col −1][Row ] == 2 ) ) ) )<br />
533 {<br />
534 r e t u r n ( t r u e ) ;<br />
535 }<br />
536 r e t u r n ( f a l s e ) ;<br />
537 }<br />
538<br />
539 // anvendes i checkMove<br />
540 p r i v a t e boolean checkTLC ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
541 {<br />
542 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | ( b [ Col<br />
+1][Row ] == 2 ) ) ) )<br />
543 {<br />
544 r e t u r n ( t r u e ) ;<br />
545 }<br />
546 r e t u r n ( f a l s e ) ;<br />
547 }<br />
548<br />
549 // anvendes i checkMove<br />
550 p r i v a t e boolean checkTRC ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
551 {<br />
552 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | ( b [ Col<br />
−1][Row ] == 2 ) ) ) )<br />
553 {<br />
554 r e t u r n ( t r u e ) ;<br />
555 }<br />
556 r e t u r n ( f a l s e ) ;<br />
557 }<br />
558<br />
559 // anvendes i checkMove
A.13 <strong>Taiji</strong>Model.java 195<br />
560 p r i v a t e boolean checkBLC ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
561 {<br />
562 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row−1] == 2 ) | | ( b [ Col<br />
+1][Row ] == 2 ) ) ) )<br />
563 {<br />
564 r e t u r n ( t r u e ) ;<br />
565 }<br />
566 r e t u r n ( f a l s e ) ;<br />
567 }<br />
568<br />
569 // anvendes i checkMove<br />
570 p r i v a t e boolean checkBRC ( i n t [ ] [ ] b , i n t Col , i n t Row)<br />
571 {<br />
572 i f ( ( b [ Col ] [ Row ] == 2) && ( ( ( b [ Col ] [ Row−1] == 2 ) | | ( b [ Col<br />
−1][Row ] == 2 ) ) ) )<br />
573 {<br />
574 r e t u r n ( t r u e ) ;<br />
575 }<br />
576 r e t u r n ( f a l s e ) ;<br />
577 }<br />
578<br />
579<br />
580<br />
581<br />
582<br />
583<br />
584 // Undersoeger om der e r en vinder , i den nuvaerende tur .<br />
585 p r i v a t e i n t gameOver ( )<br />
586 {<br />
587 i f ( fMap == n u l l )<br />
588 System . out . p r i n t l n (” Null ”) ;<br />
589 i n t [ ] s ;<br />
590 s = new i n t [ 2 ] ;<br />
591 s = fMap . c a l S c o r e ( tBoard . board [ currentTurn ] , noCols<br />
, noRows ) ;<br />
592 whScore = s [ 0 ] ;<br />
593 b l S c o r e = s [ 1 ] ;<br />
594 i n t winner= −1;<br />
595 i f ( movesLeft ( ) == f a l s e && c l i c k == f a l s e )<br />
596 {<br />
597 i f ( whScore > b l S c o r e )<br />
598 {<br />
599 winner = 1 ;<br />
600 }<br />
601 i f ( b l S c o r e > whScore )<br />
602 {<br />
603 winner = 0 ;<br />
604 }<br />
605 i f ( b l S c o r e == whScore )<br />
606 {<br />
607 winner = 2 ;<br />
608 }<br />
609 }<br />
610<br />
611 r e t u r n winner ;
196 Bilag A<br />
612 }<br />
613<br />
614 // b e r e g n e r det h o e j s t a n t a l mulige t i l b a g e v a e r e n d e t r a e k<br />
615 p u b l i c i n t maxTurnsLeft ( ) {<br />
616 i n t turns , boxed ; // Boxed e r a n t a l l e t a f e n k e l t e<br />
i n d l y k k e d e f r i e f e l t e r<br />
617 boxed = getBoxedIn ( ) ;<br />
618 t u r n s = ( noRows∗ noCols /2) − ( currentTurn −1) − ( boxed /2) ;<br />
619 r e t u r n ( t u r n s ) ;<br />
620 }<br />
621<br />
622 // f i n d e r a n t a l l e t a f f r i e i n d e l u k k e d e f e l t e r . (De f r i e f e l t e r<br />
hvor det i k k e l a e n g e r e e r muligt at p l a c e r e en b r i k paa . )<br />
623 p u b l i c i n t getBoxedIn ( ) {<br />
624 i n t boxed = 0 ;<br />
625 f o r ( i n t r =0; r < noRows ; r++){<br />
626 f o r ( i n t c =0; c < noCols ; c++){ // was noRows<br />
627 i f ( getPieceAt ( c , r ) == 2) {<br />
628 i f (0 < r && r < noRows−1){ // Midten a f<br />
r a e k k e r n e<br />
629 i f (0 < c && c < noCols −1)<br />
630 i f ( getPieceAt ( c+1 , r ) != 2 &&<br />
getPieceAt ( c−1 , r ) != 2 &&<br />
getPieceAt ( c , r +1) != 2 &&<br />
getPieceAt ( c , r −1) != 2)<br />
631 boxed++;<br />
632 i f ( c == 0)<br />
633 i f ( getPieceAt ( c+1 , r ) != 2 &&<br />
getPieceAt ( c , r +1) != 2 &&<br />
getPieceAt ( c , r −1) != 2)<br />
634 boxed++;<br />
635 i f ( c == noCols −1)<br />
636 i f ( getPieceAt ( c−1 , r ) != 2 &&<br />
getPieceAt ( c , r +1) != 2 &&<br />
getPieceAt ( c , r −1) != 2)<br />
637 boxed++;<br />
638 }<br />
639 i f ( r == 0) { // o e v e r s t e raekke<br />
640 i f (0 < c && c < noCols −1)<br />
641 i f ( getPieceAt ( c+1 , r ) != 2 &&<br />
getPieceAt ( c−1 , r ) != 2 &&<br />
getPieceAt ( c , r +1) != 2)<br />
642 boxed++;<br />
643 i f ( c == 0)<br />
644 i f ( getPieceAt ( c+1 , r ) != 2 &&<br />
getPieceAt ( c , r +1) != 2)<br />
645 boxed++;<br />
646 i f ( c == noCols −1)<br />
647 i f ( getPieceAt ( c−1 , r ) != 2 &&<br />
getPieceAt ( c , r +1) != 2)<br />
648 boxed++;<br />
649 }<br />
650 i f ( r == noRows−1){ // Nedereste raekke<br />
651 i f (0 < c && c < noCols −1)
A.13 <strong>Taiji</strong>Model.java 197<br />
652 i f ( getPieceAt ( c+1 , r ) != 2 &&<br />
getPieceAt ( c−1 , r ) != 2 &&<br />
getPieceAt ( c , r −1) != 2)<br />
653 boxed++;<br />
654 i f ( c == 0)<br />
655 i f ( getPieceAt ( c+1 , r ) != 2 &&<br />
getPieceAt ( c , r −1) != 2)<br />
656 boxed++;<br />
657 i f ( c == noCols −1)<br />
658 i f ( getPieceAt ( c−1 , r ) != 2 &&<br />
getPieceAt ( c , r −1) != 2)<br />
659 boxed++;<br />
660 }<br />
661 }<br />
662 }<br />
663 }<br />
664<br />
665<br />
666<br />
667 r e t u r n ( boxed ) ;<br />
668 }<br />
669<br />
670 // r e t u r n e r e r whScore<br />
671 p u b l i c i n t getWhiteScore ( )<br />
672 {<br />
673 r e t u r n ( whScore ) ;<br />
674 }<br />
675 // r e t u r n e r e r b l S c o r e<br />
676 p u b l i c i n t g e t B l a c k S c o r e ( )<br />
677 {<br />
678 r e t u r n ( b l S c o r e ) ;<br />
679 }<br />
680<br />
681 // Returnere den nuvaerende tur .<br />
682 p u b l i c i n t getCurrentTurn ( )<br />
683 {<br />
684 r e t u r n ( currentTurn ) ;<br />
685 }<br />
686<br />
687 // Returnere den tur /” a n t a l b r i k k e r paa b r a e t t e t ” der s k a l v i s e s<br />
i GUI ’ en .<br />
688 p u b l i c i n t getShowTurn ( )<br />
689 {<br />
690 r e t u r n ( showTurn ) ;<br />
691 }<br />
692<br />
693 // s a e t t e r showTurn , bruges kun ved i n d l a e s n i n g a f gemt s p i l .<br />
694 p u b l i c void setShowTurn ( )<br />
695 {<br />
696 showTurn = currentTurn −1;<br />
697 }<br />
698<br />
699 // s a e t t e r om hvid e l l e r s o r t s t a r t e r (0 = s o r t , 1 = hvid )<br />
700 p u b l i c void s e t S t a r t e r ( i n t s ) {<br />
701 s t a r t e r = s ;
198 Bilag A<br />
702 }<br />
703<br />
704 // s a e t t e r hvem der s p i l l e r hvid<br />
705 p u b l i c void setWhitePlayer ( i n t w) {<br />
706 whitePlayer = w;<br />
707 }<br />
708<br />
709 // s a e t t e r hvem der s p i l l e r s o r t<br />
710 p u b l i c void s e t B l a c k P l a y e r ( i n t b ) {<br />
711 b l a c k P l a y e r = b ;<br />
712 }<br />
713<br />
714 // Returnere a n t a l l e t a f kolonner .<br />
715 p u b l i c i n t getNoCols ( )<br />
716 {<br />
717 r e t u r n ( noCols ) ;<br />
718 }<br />
719<br />
720 // Returnere a n t a l l e t a f r a e k k e r .<br />
721 p u b l i c i n t getNoRows ( )<br />
722 {<br />
723 r e t u r n ( noRows ) ;<br />
724 }<br />
725<br />
726 // Returnerer den nuvaerende s p i l l e r .<br />
727 p u b l i c i n t g e t C u r r e n t P l a y e r ( )<br />
728 {<br />
729 r e t u r n ( c u r r e n t P l a y e r ) ;<br />
730 }<br />
731<br />
732 // r e t u r n e r e r h e l e b r a e t h i s t o r i e n f o r nuvaerende s p i l<br />
733 p u b l i c i n t [ ] [ ] [ ] getBoard ( )<br />
734 {<br />
735 i n t [ ] [ ] [ ] b = tBoard . getBoard ( ) ;<br />
736 r e t u r n ( b ) ;<br />
737 }<br />
738<br />
739 // r e t u r n e r e r b r a e t f o r t r a e k nr . t<br />
740 p u b l i c i n t [ ] [ ] getOneBoard ( i n t t )<br />
741 {<br />
742 // tBoard . copyBoardTo ( t +1) ;<br />
743 // i n t [ ] [ ] b = tBoard . getOneBoard ( t ) ;<br />
744 i n t [ ] [ ] b = tBoard . getClone ( t ) ;<br />
745 r e t u r n ( b ) ;<br />
746 }<br />
747<br />
748 // r e t u r n e r e r f a r v e n a f brikken paa p l a d s ( col , row ) ( s o r t , hvid<br />
, f r i )<br />
749 p u b l i c i n t getPieceAt ( i n t col , i n t row )<br />
750 {<br />
751 i n t p = tBoard . getPieceAt ( col , row ) ;<br />
752 r e t u r n ( p ) ;<br />
753 }<br />
754
A.13 <strong>Taiji</strong>Model.java 199<br />
755 // r e t u r n e r e r f o r s k e l l e n mellem hvid og s o r t s c o r e f o r b r a e t t e t<br />
nb<br />
756 p u b l i c i n t g e t D i f ( i n t [ ] [ ] nb )<br />
757 {<br />
758 i n t d i f = fMap . c a l D i f ( nb , noCols , noRows ) ;<br />
759 r e t u r n ( d i f ) ;<br />
760 }<br />
761<br />
762 // S t i l l e r turen en t i l b a g e , s k i f t e r s p i l l e r . Hvid , h v i s der<br />
s k i f t e s t i l u l i g e tur , s o r t , h v i s det e r en l i g e tur .<br />
763 p u b l i c void turnBack ( )<br />
764 {<br />
765 i f ( currentTurn > 1)<br />
766 {<br />
767 currentTurn −−;<br />
768 showTurn−−;<br />
769 c u r r e n t P l a y e r = currentTurn % 2 ;<br />
770 i n t [ ] s ;<br />
771 s = new i n t [ 2 ] ;<br />
772 s = fMap . c a l S c o r e ( tBoard . board [ currentTurn ] , noCols<br />
, noRows ) ;<br />
773 whScore = s [ 0 ] ;<br />
774 b l S c o r e = s [ 1 ] ;<br />
775 }<br />
776 }<br />
777<br />
778 // S t i l l e r turen en frem , s k i f t e r s p i l l e r . Hvid , h v i s der<br />
s k i f t e s t i l en u l i g e tur , s o r t , h v i s der s k i f t e s t i l en<br />
l i g e tur .<br />
779 p u b l i c void turnForward ( )<br />
780 {<br />
781 i f ( currentTurn < tBoard . board [ 0 ] [ 0 ] [ 0 ] )<br />
782 {<br />
783 currentTurn++;<br />
784 showTurn++;<br />
785 c u r r e n t P l a y e r = currentTurn % 2 ;<br />
786 i n t [ ] s ;<br />
787 s = new i n t [ 2 ] ;<br />
788 s = fMap . c a l S c o r e ( tBoard . board [ currentTurn ] , noCols<br />
, noRows ) ;<br />
789 whScore = s [ 0 ] ;<br />
790 b l S c o r e = s [ 1 ] ;<br />
791 }<br />
792 }<br />
793<br />
794 // S k i f t e r t i l den n a e s t e s p i l l e r , s o r t h v i s nuvaerende e r hvid ,<br />
og v i c e v e r s a .<br />
795 p u b l i c void changePlayer ( )<br />
796 {<br />
797 c u r r e n t P l a y e r = ( c u r r e n t P l a y e r +1) % 2 ;<br />
798 }<br />
799<br />
800 // Modtager e t nyt b r a e t ( f r a e t gemt s p i l ) , s a e t t e r den<br />
nuvaerende tur t i l turen gemt i [ 0 ] [ 0 ] [ 0 ] i det nye board .<br />
801 // Modtager e t 3−d i m e n s i o n e l t array som argument .
200 Bilag A<br />
802 p u b l i c void newBoard ( i n t [ ] [ ] [ ] board )<br />
803 {<br />
804 t h i s . tBoard . board = board ;<br />
805 currentTurn = board [ 0 ] [ 0 ] [ 0 ] ;<br />
806 c u r r e n t P l a y e r = currentTurn % 2 ;<br />
807 i n t [ ] s ;<br />
808 s = new i n t [ 2 ] ;<br />
809 s = fMap . c a l S c o r e ( board [ currentTurn ] , noCols , noRows ) ;<br />
810 whScore = s [ 0 ] ;<br />
811 b l S c o r e = s [ 1 ] ;<br />
812 }<br />
813<br />
814 // Returnerer det maksimale a n t a l t u r e programmet kan haandtere .<br />
815 p u b l i c i n t getMaxTurns ( )<br />
816 {<br />
817 r e t u r n ( maxTurns ) ;<br />
818 }<br />
819<br />
820 // Returnerer det s e n e s t e traek , u a f h a e n g i g t a f h v i l k e n type<br />
s p i l l e r der har f o r e t a g e t det<br />
821 p u b l i c i n t [ ] getLatestMove ( ) {<br />
822 i n t [ ] t = new i n t [ 4 ] ;<br />
823 i f ( currentTurn == 0) {<br />
824 r e t u r n ( t ) ;<br />
825 }<br />
826 f o r ( i n t c =0; c < noCols ; c++){<br />
827 f o r ( i n t r =0; r < noRows ; r++){<br />
828 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] != tBoard . board<br />
[ currentTurn −1][ c ] [ r ] ) {<br />
829 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 1) {<br />
830 t [0]= c ;<br />
831 t [1]= r ;<br />
832 }<br />
833 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 0) {<br />
834 t [2]= c ;<br />
835 t [3]= r ;<br />
836 }<br />
837 }<br />
838 }<br />
839 }<br />
840 r e t u r n ( t ) ;<br />
841 }<br />
842<br />
843<br />
844 }<br />
A.14 <strong>Taiji</strong>Panels.java<br />
1<br />
2 import javax . swing . ∗ ;<br />
3 import java . awt . ∗ ;<br />
4 import java . lang . ∗ ;<br />
5
A.14 <strong>Taiji</strong>Panels.java 201<br />
6 // Klassen T a i j i P a n e l e r s e l v e b r a e t t e t hvor a l l e ryk f o r e t a g e s og<br />
a l l e b r i k k e r v i s e s .<br />
7 //Er nedarvet f r a JPanel .<br />
8 c l a s s T a i j i P a n e l extends JPanel<br />
9 {<br />
10<br />
11 // V a r i a b l e r med i n f o r m a t i o n om b r a e t t e t s udseende .<br />
12 p r i v a t e i n t noRows , noCols ;<br />
13<br />
14 //En <strong>Taiji</strong>Frame som metoderne i T a i j i P a n e l kan r e f e r e r e t i l .<br />
15 p r i v a t e <strong>Taiji</strong>Frame tFrame ;<br />
16 // p r i v a t e Board tBoard ;<br />
17<br />
18 // Constructor . Giver tFrame en v a e r d i saa der kan r e f e r e r e s t i l<br />
den , d e f i n e r e r a n t a l l e t a f r a e k k e r og s o e j l e r .<br />
19 // Modtager en tFrame som argument .<br />
20 p u b l i c T a i j i P a n e l ( <strong>Taiji</strong>Frame frame )<br />
21 {<br />
22 tFrame = frame ;<br />
23 T a i j i P a n e l L i s t e n e r a b l i s = new T a i j i P a n e l L i s t e n e r ( tFrame ) ;<br />
24 t h i s . addMouseListener ( a b l i s ) ;<br />
25 noRows = tFrame . tModel . getNoRows ( ) ;<br />
26 noCols = tFrame . tModel . getNoCols ( ) ;<br />
27 t h i s . setBackground ( Color . gray ) ;<br />
28 t h i s . s e t P r e f e r r e d S i z e ( new Dimension ( 5 0 0 , 5 0 0 ) ) ;<br />
29 }<br />
30<br />
31 // Tegner s e l v e b r a e t t e t .<br />
32 p u b l i c void paintComponent ( Graphics g )<br />
33 {<br />
34 super . paintComponent ( g ) ;<br />
35 i n t width = t h i s . getWidth ( ) ;<br />
36 i n t h e i g h t = t h i s . getHeight ( ) ;<br />
37 i n t colWidth = width / noCols ;<br />
38 i n t rowHeight = h e i g h t /noRows ;<br />
39<br />
40 g . s e t C o l o r ( Color . black ) ;<br />
41<br />
42 f o r ( i n t i = 1 ; i
202 Bilag A<br />
59 g . f i l l R e c t ( c ∗ colWidth , r ∗ rowHeight ,<br />
colWidth , rowHeight ) ;<br />
60 }<br />
61 e l s e i f ( tFrame . tModel . getPieceAt ( c , r ) == 0)<br />
62 {<br />
63 g . s e t C o l o r ( Color . black ) ;<br />
64 g . f i l l R e c t ( c ∗ colWidth , r ∗ rowHeight ,<br />
colWidth , rowHeight ) ;<br />
65 }<br />
66 }<br />
67 }<br />
68 }<br />
69 }<br />
70<br />
71 // Klassen ScorePanel v i s e r s c o r e n f o r enten hvid e l l e r s o r t s p i l l e r<br />
.<br />
72 //Er nedarvet f r a JPanel .<br />
73 c l a s s ScorePanel extends JPanel<br />
74 {<br />
75<br />
76 // V a r i a b e l der v i s e r s c o r e n i o e j e b l i k k e t . Samt a n g i v e r h v i l k e n<br />
s p i l l e r s c o r e ScorePanel s k a l v i s e .<br />
77 p r i v a t e i n t s c o r e ;<br />
78 p r i v a t e i n t playerNumber ;<br />
79<br />
80 //En <strong>Taiji</strong>Frame som metoderne i T a i j i P a n e l kan r e f e r e r e t i l .<br />
81 p r i v a t e <strong>Taiji</strong>Frame tFrame ;<br />
82<br />
83 // Constructor .<br />
84 // Modtager en frame og en s p i l l e r som argumenter .<br />
85 p u b l i c ScorePanel ( <strong>Taiji</strong>Frame frame , i n t p l a y e r )<br />
86 {<br />
87 tFrame = frame ;<br />
88 playerNumber = p l a y e r ;<br />
89 t h i s . s e t P r e f e r r e d S i z e ( new Dimension ( 5 0 , 5 0 0 ) ) ;<br />
90 }<br />
91<br />
92 // V i s e r g r a f i s k s t i l l i n g e n f o r de to s p i l l e r .<br />
93 p u b l i c void paintComponent ( Graphics g )<br />
94 {<br />
95 super . paintComponent ( g ) ;<br />
96 S t r i n g s c o r e S t r i n g ;<br />
97 i n t middleHeight = ( t h i s . getHeight ( ) /2) ;<br />
98 i n t middleWidth = ( t h i s . getWidth ( ) /2) ;<br />
99 i f ( playerNumber == 1)<br />
100 {<br />
101 s c o r e = tFrame . tModel . getWhiteScore ( ) ;<br />
102 s c o r e S t r i n g = ”” + s c o r e ;<br />
103 t h i s . setBackground ( Color . gray ) ;<br />
104 g . s e t C o l o r ( Color . white ) ;<br />
105 g . drawString ( s c o r e S t r i n g , middleWidth , middleHeight<br />
) ;<br />
106 }<br />
107 e l s e<br />
108 {
A.14 <strong>Taiji</strong>Panels.java 203<br />
109 s c o r e = tFrame . tModel . g e t B l a c k S c o r e ( ) ;<br />
110 s c o r e S t r i n g = ”” + s c o r e ;<br />
111 t h i s . setBackground ( Color . gray ) ;<br />
112 g . s e t C o l o r ( Color . black ) ;<br />
113 g . drawString ( s c o r e S t r i n g , middleWidth , middleHeight<br />
) ;<br />
114 }<br />
115 }<br />
116 }<br />
117<br />
118 // Klassen TurnPanel v i s e r h v i l k e n f a r v e s tur det e r . Bruges ogsaa<br />
t i l at gaa frem og t i l b a g e gennem t urene .<br />
119 //Er nedarvet f r a JPanel .<br />
120 c l a s s TurnPanel extends JPanel<br />
121 {<br />
122 p r i v a t e <strong>Taiji</strong>Frame uFrame ;<br />
123<br />
124 //En l a b e l som v i s e r hvor mange b r i k k e r der e r b l e v e t l a g t ( tur<br />
) .<br />
125 p r i v a t e JLabel uLabel ;<br />
126<br />
127 // Constructor .<br />
128 // Modtager <strong>Taiji</strong>Frame som argument .<br />
129 p u b l i c TurnPanel ( <strong>Taiji</strong>Frame frame )<br />
130 {<br />
131 uFrame = frame ;<br />
132<br />
133 t h i s . s e t P r e f e r r e d S i z e ( new Dimension ( 5 0 0 , 5 0 ) ) ;<br />
134 t h i s . setBackground ( Color . l i g h t G r a y ) ;<br />
135<br />
136<br />
137 BorderLayout bLayout = new BorderLayout ( ) ;<br />
138 t h i s . setLayout ( bLayout ) ;<br />
139<br />
140 JButton fButton = new JButton (” Next Turn ”) ;<br />
141 JButton bButton = new JButton (” Last Turn ”) ;<br />
142 uLabel = new JLabel (””+ uFrame . tModel . getShowTurn ( ) ,<br />
SwingConstants .CENTER) ;<br />
143<br />
144 t h i s . add ( fButton , ” East ”) ;<br />
145 t h i s . add ( uLabel , ” Center ”) ;<br />
146 t h i s . add ( bButton , ”West ”) ;<br />
147<br />
148 TurnListener t L i s t = new TurnListener ( uFrame ) ;<br />
149 fButton . a d d A c t i o n L i s t e n e r ( t L i s t ) ;<br />
150 bButton . a d d A c t i o n L i s t e n e r ( t L i s t ) ;<br />
151<br />
152 }<br />
153<br />
154 // Opdaterer uLabel og s k i f t e r baggrundsfarven e f t e r h v i l k e n<br />
s p i l l e r s tur det e r .<br />
155 p u b l i c void update ( )<br />
156 {<br />
157 uLabel . setText (””+uFrame . tModel . getShowTurn ( ) ) ;<br />
158 i f ( uFrame . tModel . g e t C u r r e n t P l a y e r ( ) == 1)
204 Bilag A<br />
159 {<br />
160 t h i s . setBackground ( Color . l i g h t G r a y ) ;<br />
161 }<br />
162 e l s e<br />
163 {<br />
164 t h i s . setBackground ( Color . gray ) ;<br />
165 }<br />
166 }<br />
167<br />
168 }<br />
A.15 <strong>Taiji</strong>Print.java<br />
1 // denne k l a s s e r s t a a r f o r at u d s k r i v e r i n d e h o l d e t a f Nodes t i l<br />
t e s t formaal<br />
2 p u b l i c c l a s s T a i j i P r i n t {<br />
3 p u b l i c <strong>Taiji</strong>Model tModel ;<br />
4<br />
5 p u b l i c T a i j i P r i n t ( <strong>Taiji</strong>Model m) {<br />
6 t h i s . tModel = m;<br />
7 }<br />
8<br />
9 // u d s k r i v e r v a e r d i e r n e f o r f o r a e l d r e n e t i l Noden n<br />
10 p u b l i c void p r i n t P a r S c o r e ( Node n ) {<br />
11 System . out . p r i n t (” t P r i n t p r i n t P a r S c o r e d=”+n . d+” n . par<br />
s c o r e s : ”) ;<br />
12 f o r ( i n t i =0; i
A.15 <strong>Taiji</strong>Print.java 205<br />
39 e l s e<br />
40 i f ( tModel . noCols == 8)<br />
41 f o r ( i n t i =0; i
206 Bilag A<br />
81 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 1 ] ) ;<br />
82 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 2 ] ) ;<br />
83 i f ( tModel . noRows > 3) {<br />
84 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 3 ] ) ;<br />
85 i f ( tModel . noRows > 4) {<br />
86 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 4 ] ) ;<br />
87 i f ( tModel . noRows > 5) {<br />
88 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 5 ] ) ;<br />
89 i f ( tModel . noRows > 6) {<br />
90 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 6 ] ) ;<br />
91 i f ( tModel . noRows > 7) {<br />
92 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 7 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 7 ] ) ;<br />
93 i f ( tModel . noRows > 8) {<br />
94 System . out . p r i n t l n ( n .<br />
c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 8 ] ) ;<br />
95 i f ( tModel . noRows > 9) {<br />
96 System . out . p r i n t l n ( n .<br />
c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 9 ] + ”<br />
”+n . c h i l d r e n . get ( i )<br />
. nodeBoard [ 1 ] [ 9 ] + ”<br />
”+n . c h i l d r e n . get ( i )<br />
. nodeBoard [ 2 ] [ 9 ] ) ;<br />
97 }<br />
98 }<br />
99 }<br />
100 }<br />
101 }<br />
102 }
A.15 <strong>Taiji</strong>Print.java 207<br />
103 }<br />
104 System . out . p r i n t l n ( ) ;<br />
105 }<br />
106 }<br />
107<br />
108 // f o r b r a e t med 4 k o l o n e r<br />
109 p u b l i c void p r i n t C h i l d r e n 4 x ( Node n ) {<br />
110 System . out . p r i n t l n (” t P r i n t P r i n t Children ”+n ) ;<br />
111 f o r ( i n t i =0; i 3) {<br />
118 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] ) ;<br />
119 i f ( tModel . noRows > 4) {<br />
120 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 4 ] ) ;<br />
121 i f ( tModel . noRows > 5) {<br />
122 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 5 ] ) ;<br />
123 i f ( tModel . noRows > 6) {<br />
124 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] ) ;<br />
125 i f ( tModel . noRows > 7) {<br />
126 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard
208 Bilag A<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 3 ] [ 7 ] ) ;<br />
127 i f ( tModel . noRows > 8) {<br />
128 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 8 ] ) ;<br />
129<br />
130 }<br />
131 }<br />
132 }<br />
133 }<br />
134 }<br />
135 }<br />
136 System . out . p r i n t l n ( ) ;<br />
137 }<br />
138 }<br />
139<br />
140 // f o r b r a e t med 5 k o l o n e r<br />
141 p u b l i c void p r i n t C h i l d r e n 5 x ( Node n ) {<br />
142 System . out . p r i n t l n (” t P r i n t P r i n t Children ”+n ) ;<br />
143 f o r ( i n t i =0; i 3) {<br />
150 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 4 ] [ 3 ] ) ;<br />
151 i f ( tModel . noRows > 4) {
A.15 <strong>Taiji</strong>Print.java 209<br />
152 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 4 ] ) ;<br />
153 i f ( tModel . noRows > 5) {<br />
154 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 4 ] [ 5 ] ) ;<br />
155 i f ( tModel . noRows > 6) {<br />
156 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 6 ] ) ;<br />
157 i f ( tModel . noRows > 7) {<br />
158 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 7 ] ) ;<br />
159 i f ( tModel . noRows > 8) {<br />
160 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 4 ] [ 8 ] ) ;<br />
161<br />
162 }<br />
163 }<br />
164 }<br />
165 }<br />
166 }<br />
167 }<br />
168 System . out . p r i n t l n ( ) ;<br />
169 }<br />
170 }<br />
171<br />
172 // f o r b r a e t med 6 k o l o n e r<br />
173 p u b l i c void p r i n t C h i l d r e n 6 x ( Node n ) {<br />
174 System . out . p r i n t l n (” t P r i n t P r i n t Children ”+n ) ;<br />
175 f o r ( i n t i =0; i
210 Bilag A<br />
176 System . out . p r i n t l n ( i +” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n<br />
. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;<br />
177 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . par+” ”+n . c h i l d r e n<br />
. get ( i ) . a+” b ”+n . c h i l d r e n . get ( i ) . bc+”,”+n . c h i l d r e n<br />
. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .<br />
c h i l d r e n . get ( i ) . wr+” ”+n . c h i l d r e n . get ( i ) . c h i l d r e n +”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard ) ;<br />
178 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 0 ] ) ;<br />
179 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 1 ] ) ;<br />
180 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 2 ] ) ;<br />
181 i f ( tModel . noRows > 3) {<br />
182 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 3 ] ) ;<br />
183 i f ( tModel . noRows > 4) {<br />
184 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 4 ] ) ;<br />
185 i f ( tModel . noRows > 5) {<br />
186 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 5 ] ) ;<br />
187 i f ( tModel . noRows > 6) {<br />
188 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 6 ] ) ;<br />
189 i f ( tModel . noRows > 7) {
A.15 <strong>Taiji</strong>Print.java 211<br />
190 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 7 ] ) ;<br />
191 i f ( tModel . noRows > 8) {<br />
192 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 8 ] ) ;<br />
193<br />
194 }<br />
195 }<br />
196 }<br />
197 }<br />
198 }<br />
199 }<br />
200 System . out . p r i n t l n ( ) ;<br />
201 }<br />
202 }<br />
203<br />
204 // f o r b r a e t med 7 k o l o n e r<br />
205 p u b l i c void p r i n t C h i l d r e n 7 x ( Node n ) {<br />
206 System . out . p r i n t l n (” t P r i n t P r i n t Children ”+n ) ;<br />
207 f o r ( i n t i =0; i
212 Bilag A<br />
212 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 2 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 2 ] ) ;<br />
213 i f ( tModel . noRows > 3) {<br />
214 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 6 ] [ 3 ] ) ;<br />
215 i f ( tModel . noRows > 4) {<br />
216 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 6 ] [ 4 ] ) ;<br />
217 i f ( tModel . noRows > 5) {<br />
218 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 6 ] [ 5 ] ) ;<br />
219 i f ( tModel . noRows > 6) {<br />
220 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 6 ] [ 6 ] ) ;<br />
221 i f ( tModel . noRows > 7) {<br />
222 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 6 ] [ 7 ] ) ;<br />
223 i f ( tModel . noRows > 8) {
A.15 <strong>Taiji</strong>Print.java 213<br />
224 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 6 ] [ 8 ] ) ;<br />
225<br />
226 }<br />
227 }<br />
228 }<br />
229 }<br />
230 }<br />
231 }<br />
232 System . out . p r i n t l n ( ) ;<br />
233 }<br />
234 }<br />
235<br />
236 // f o r b r a e t med 8 k o l o n e r<br />
237 p u b l i c void p r i n t C h i l d r e n 8 x ( Node n ) {<br />
238 System . out . p r i n t l n (” t P r i n t P r i n t Children ”+n ) ;<br />
239 f o r ( i n t i =0; i 3) {
214 Bilag A<br />
246 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 6 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 7 ] [ 3 ] ) ;<br />
247 i f ( tModel . noRows > 4) {<br />
248 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 6 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 7 ] [ 4 ] ) ;<br />
249 i f ( tModel . noRows > 5) {<br />
250 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 6 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 7 ] [ 5 ] ) ;<br />
251 i f ( tModel . noRows > 6) {<br />
252 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 6 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 7 ] [ 6 ] ) ;<br />
253 i f ( tModel . noRows > 7) {<br />
254 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 6 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 7 ] [ 7 ] ) ;<br />
255 i f ( tModel . noRows > 8) {<br />
256 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard
A.15 <strong>Taiji</strong>Print.java 215<br />
[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 6 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 7 ] [ 8 ] ) ;<br />
257<br />
258 }<br />
259 }<br />
260 }<br />
261 }<br />
262 }<br />
263 }<br />
264 System . out . p r i n t l n ( ) ;<br />
265 }<br />
266<br />
267<br />
}<br />
268 // f o r b r a e t med 9 k o l o n e r<br />
269 p u b l i c void p r i n t C h i l d r e n 9 x ( Node n ) {<br />
270 System . out . p r i n t l n (” t P r i n t P r i n t Children ”+n ) ;<br />
271 f o r ( i n t i =0; i
216 Bilag A<br />
[ 8 ] [ 2 ] ) ;<br />
277 i f ( tModel . noRows > 3) {<br />
278 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 6 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 7 ] [ 3 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard [ 8 ] [ 3 ] ) ;<br />
279 i f ( tModel . noRows > 4) {<br />
280 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 6 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 7 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 8 ] [ 4 ] ) ;<br />
281 i f ( tModel . noRows > 5) {<br />
282 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 6 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 7 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 8 ] [ 5 ] ) ;<br />
283 i f ( tModel . noRows > 6) {<br />
284 System . out . p r i n t l n ( n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ”<br />
”+n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 6 ] + ” ”+n . c h i l d r e n . get (<br />
i ) . nodeBoard [ 6 ] [ 6 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 7 ] [ 6 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard [ 8 ] [ 6 ] ) ;<br />
285 i f ( tModel . noRows > 7) {<br />
286 System . out . p r i n t l n ( n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 5 ] [ 7 ] + ” ”+n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 6 ] [ 7 ] + ” ”+n .
A.15 <strong>Taiji</strong>Print.java 217<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 7 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .<br />
nodeBoard [ 8 ] [ 7 ] ) ;<br />
287 i f ( tModel . noRows > 8) {<br />
288 System . out . p r i n t l n ( n . c h i l d r e n .<br />
get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+<br />
n . c h i l d r e n . get ( i ) . nodeBoard<br />
[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 5 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 6 ] [ 8 ] + ” ”+n .<br />
c h i l d r e n . get ( i ) . nodeBoard<br />
[ 7 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i<br />
) . nodeBoard [ 8 ] [ 8 ] ) ;<br />
289<br />
290 }<br />
291 }<br />
292 }<br />
293 }<br />
294 }<br />
295 }<br />
296 System . out . p r i n t l n ( ) ;<br />
297 }<br />
298 }<br />
299<br />
300 // u d s k r i v e r i n f o r m a t i o n f o r en e n k e l t node<br />
301 p u b l i c void printNode ( Node n ) {<br />
302 i f ( tModel . noCols == 3)<br />
303 printNode3x ( n ) ;<br />
304 e l s e<br />
305 i f ( tModel . noCols == 4)<br />
306 printNode4x ( n ) ;<br />
307 e l s e<br />
308 i f ( tModel . noCols == 5)<br />
309 printNode5x ( n ) ;<br />
310 e l s e<br />
311 i f ( tModel . noCols == 6)<br />
312 printNode6x ( n ) ;<br />
313 e l s e<br />
314 i f ( tModel . noCols == 7)<br />
315 printNode7x ( n ) ;<br />
316 e l s e<br />
317 i f ( tModel . noCols == 8)<br />
318 printNode8x ( n ) ;<br />
319 e l s e<br />
320 i f ( tModel . noCols == 9)<br />
321 printNode9x ( n ) ;<br />
322<br />
323 }<br />
324<br />
325 // f o r b r a e t med 3 k o l o n e r
218 Bilag A<br />
326 p u b l i c void printNode3x ( Node n ) {<br />
327 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
328 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] ) ;<br />
329 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] ) ;<br />
330 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] ) ;<br />
331 i f ( tModel . noRows > 3) {<br />
332 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] ) ;<br />
333 i f ( tModel . noRows > 4) {<br />
334 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] ) ;<br />
335 i f ( tModel . noRows > 5) {<br />
336 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] ) ;<br />
337 i f ( tModel . noRows > 6) {<br />
338 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] ) ;<br />
339 i f ( tModel . noRows > 7) {<br />
340 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] ) ;<br />
341 i f ( tModel . noRows > 8) {<br />
342 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] ) ;<br />
343<br />
344<br />
345 }<br />
346 }<br />
347 }<br />
348 }<br />
349 }<br />
350 }<br />
351 System . out . p r i n t l n ( ) ;<br />
352 }<br />
353<br />
354 // f o r b r a e t med 4 k o l o n e r<br />
355 p u b l i c void printNode4x ( Node n ) {<br />
356 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
357 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] ) ;<br />
358 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] ) ;<br />
359 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] ) ;<br />
360 i f ( tModel . noRows > 3) {<br />
361 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard [ 3 ] [ 3 ] )
A.15 <strong>Taiji</strong>Print.java 219<br />
;<br />
362 i f ( tModel . noRows > 4) {<br />
363 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 4 ] ) ;<br />
364 i f ( tModel . noRows > 5) {<br />
365 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n<br />
. nodeBoard [ 3 ] [ 5 ] ) ;<br />
366 i f ( tModel . noRows > 6) {<br />
367 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 3 ] [ 6 ] ) ;<br />
368 i f ( tModel . noRows > 7) {<br />
369 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] ) ;<br />
370 i f ( tModel . noRows > 8) {<br />
371 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 8 ] ) ;<br />
372<br />
373<br />
374 }<br />
375 }<br />
376 }<br />
377 }<br />
378 }<br />
379 }<br />
380 System . out . p r i n t l n ( ) ;<br />
381 }<br />
382<br />
383 // f o r b r a e t med 5 k o l o n e r<br />
384 p u b l i c void printNode5x ( Node n ) {<br />
385 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
386 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 0 ] ) ;<br />
387 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 1 ] ) ;<br />
388 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 2 ] ) ;<br />
389 i f ( tModel . noRows > 3) {<br />
390 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] ) ;<br />
391 i f ( tModel . noRows > 4) {<br />
392 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] ) ;
220 Bilag A<br />
393 i f ( tModel . noRows > 5) {<br />
394 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n<br />
. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] ) ;<br />
395 i f ( tModel . noRows > 6) {<br />
396 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 6 ] ) ;<br />
397 i f ( tModel . noRows > 7) {<br />
398 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 4 ] [ 7 ] ) ;<br />
399 i f ( tModel . noRows > 8) {<br />
400 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 8 ] ) ;<br />
401<br />
402<br />
403 }<br />
404 }<br />
405 }<br />
406 }<br />
407 }<br />
408 }<br />
409 System . out . p r i n t l n ( ) ;<br />
410 }<br />
411<br />
412 // f o r b r a e t med 6 k o l o n e r<br />
413 p u b l i c void printNode6x ( Node n ) {<br />
414 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
415 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] ) ;<br />
416 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] ) ;<br />
417 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] ) ;<br />
418 i f ( tModel . noRows > 3) {<br />
419 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard [ 5 ] [ 3 ] )<br />
;<br />
420 i f ( tModel . noRows > 4) {<br />
421 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 5 ] [ 4 ] ) ;
A.15 <strong>Taiji</strong>Print.java 221<br />
422 i f ( tModel . noRows > 5) {<br />
423 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n<br />
. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+<br />
n . nodeBoard [ 5 ] [ 5 ] ) ;<br />
424 i f ( tModel . noRows > 6) {<br />
425 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] ) ;<br />
426 i f ( tModel . noRows > 7) {<br />
427 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 7 ] ) ;<br />
428 i f ( tModel . noRows > 8) {<br />
429 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] ) ;<br />
430<br />
431<br />
432 }<br />
433 }<br />
434 }<br />
435 }<br />
436 }<br />
437 }<br />
438 System . out . p r i n t l n ( ) ;<br />
439 }<br />
440<br />
441 // f o r b r a e t med 7 k o l o n e r<br />
442 p u b l i c void printNode7x ( Node n ) {<br />
443 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
444 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 0 ] ) ;<br />
445 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 1 ] ) ;<br />
446 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 2 ] ) ;<br />
447 i f ( tModel . noRows > 3) {<br />
448 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 3 ] + ” ”+n . nodeBoard [ 6 ] [ 3 ] ) ;
222 Bilag A<br />
449 i f ( tModel . noRows > 4) {<br />
450 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 5 ] [ 4 ] + ” ”+n . nodeBoard [ 6 ] [ 4 ] ) ;<br />
451 i f ( tModel . noRows > 5) {<br />
452 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n<br />
. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+<br />
n . nodeBoard [ 5 ] [ 5 ] + ” ”+n . nodeBoard [ 6 ] [ 5 ] ) ;<br />
453 i f ( tModel . noRows > 6) {<br />
454 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 6 ] [ 6 ] ) ;<br />
455 i f ( tModel . noRows > 7) {<br />
456 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 7 ] + ” ”+n . nodeBoard [ 6 ] [ 7 ] ) ;<br />
457 i f ( tModel . noRows > 8) {<br />
458 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 6 ] [ 8 ] ) ;<br />
459<br />
460<br />
461 }<br />
462 }<br />
463 }<br />
464 }<br />
465 }<br />
466 }<br />
467 System . out . p r i n t l n ( ) ;<br />
468 }<br />
469<br />
470 // f o r b r a e t med 8 k o l o n e r<br />
471 p u b l i c void printNode8x ( Node n ) {<br />
472 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
473 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 0 ] + ” ”+n . nodeBoard [ 7 ] [ 0 ] ) ;<br />
474 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 1 ] + ” ”+n . nodeBoard [ 7 ] [ 1 ] ) ;<br />
475 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+
A.15 <strong>Taiji</strong>Print.java 223<br />
n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 2 ] + ” ”+n . nodeBoard [ 7 ] [ 2 ] ) ;<br />
476 i f ( tModel . noRows > 3) {<br />
477 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 3 ] + ” ”+n . nodeBoard [ 6 ] [ 3 ] + ” ”+n . nodeBoard [ 7 ] [ 3 ] )<br />
;<br />
478 i f ( tModel . noRows > 4) {<br />
479 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 5 ] [ 4 ] + ” ”+n . nodeBoard [ 6 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 7 ] [ 4 ] ) ;<br />
480 i f ( tModel . noRows > 5) {<br />
481 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n<br />
. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+<br />
n . nodeBoard [ 5 ] [ 5 ] + ” ”+n . nodeBoard [ 6 ] [ 5 ] + ”<br />
”+n . nodeBoard [ 7 ] [ 5 ] ) ;<br />
482 i f ( tModel . noRows > 6) {<br />
483 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 6 ] [ 6 ] + ” ”+n . nodeBoard [ 7 ] [ 6 ] ) ;<br />
484 i f ( tModel . noRows > 7) {<br />
485 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 7 ] + ” ”+n . nodeBoard [ 6 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 7 ] [ 7 ] ) ;<br />
486 i f ( tModel . noRows > 8) {<br />
487 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 6 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 7 ] [ 8 ] ) ;<br />
488<br />
489<br />
490 }<br />
491 }<br />
492 }<br />
493 }<br />
494 }<br />
495 }<br />
496 System . out . p r i n t l n ( ) ;<br />
497 }<br />
498<br />
499 // f o r b r a e t med 9 k o l o n e r<br />
500 p u b l i c void printNode9x ( Node n ) {
224 Bilag A<br />
501 System . out . p r i n t l n (” t P r i n t PrintNode ”+n+” Depth : ”+n . d+”<br />
Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .<br />
bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;<br />
502 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 0 ] + ” ”+n . nodeBoard [ 7 ] [ 0 ] + ” ”+n . nodeBoard [ 8 ] [ 0 ] ) ;<br />
503 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 1 ] + ” ”+n . nodeBoard [ 7 ] [ 1 ] + ” ”+n . nodeBoard [ 8 ] [ 1 ] ) ;<br />
504 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+<br />
n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] + ” ”+n . nodeBoard<br />
[ 6 ] [ 2 ] + ” ”+n . nodeBoard [ 7 ] [ 2 ] + ” ”+n . nodeBoard [ 8 ] [ 2 ] ) ;<br />
505 i f ( tModel . noRows > 3) {<br />
506 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 3 ] + ” ”+n . nodeBoard [ 6 ] [ 3 ] + ” ”+n . nodeBoard<br />
[ 7 ] [ 3 ] + ” ”+n . nodeBoard [ 8 ] [ 3 ] ) ;<br />
507 i f ( tModel . noRows > 4) {<br />
508 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 5 ] [ 4 ] + ” ”+n . nodeBoard [ 6 ] [ 4 ] + ” ”+n .<br />
nodeBoard [ 7 ] [ 4 ] + ” ”+n . nodeBoard [ 8 ] [ 4 ] ) ;<br />
509 i f ( tModel . noRows > 5) {<br />
510 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n<br />
. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+<br />
n . nodeBoard [ 5 ] [ 5 ] + ” ”+n . nodeBoard [ 6 ] [ 5 ] + ”<br />
”+n . nodeBoard [ 7 ] [ 5 ] + ” ”+n . nodeBoard [ 8 ] [ 5 ] ) ;<br />
511 i f ( tModel . noRows > 6) {<br />
512 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] + ” ”+n .<br />
nodeBoard [ 6 ] [ 6 ] + ” ”+n . nodeBoard [ 7 ] [ 6 ] + ”<br />
”+n . nodeBoard [ 8 ] [ 6 ] ) ;<br />
513 i f ( tModel . noRows > 7) {<br />
514 System . out . p r i n t l n ( n . nodeBoard [ 0 ] [ 7 ] + ”<br />
”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 5 ] [ 7 ] + ” ”+n . nodeBoard [ 6 ] [ 7 ] + ” ”+n .<br />
nodeBoard [ 7 ] [ 7 ] + ” ”+n . nodeBoard<br />
[ 8 ] [ 7 ] ) ;<br />
515 i f ( tModel . noRows > 8) {<br />
516 System . out . p r i n t l n ( n . nodeBoard<br />
[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .<br />
nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard<br />
[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] + ”<br />
”+n . nodeBoard [ 6 ] [ 8 ] + ” ”+n .
A.16 <strong>Taiji</strong>Settings.java 225<br />
517<br />
518<br />
519 }<br />
520 }<br />
521 }<br />
522 }<br />
523 }<br />
524 }<br />
525 System . out . p r i n t l n ( ) ;<br />
526 }<br />
527 }<br />
A.16 <strong>Taiji</strong>Settings.java<br />
nodeBoard [ 7 ] [ 8 ] + ” ”+n . nodeBoard<br />
[ 8 ] [ 8 ] ) ;<br />
1 import java . awt . event . ∗ ;<br />
2 import javax . swing . ∗ ;<br />
3 import java . awt . ∗ ;<br />
4<br />
5 p u b l i c c l a s s T a i j i S e t t i n g s extends JDialog {<br />
6 // S e l v e d i a l o g e n s panel .<br />
7 p r i v a t e JPanel mainPanel = new JPanel ( ) ;<br />
8<br />
9 // Radiobuttons t i l at v a e l g e AI og andre s e t t i n g s .<br />
10 p r i v a t e JRadioButton oneButton = new JRadioButton (” Player VS<br />
Player ”) ;<br />
11 p r i v a t e JRadioButton twoButton = new JRadioButton (” Player VS<br />
LocalArea ”) ;<br />
12 p r i v a t e JRadioButton threeButton = new JRadioButton (” Player VS<br />
AlphaBeta ”) ;<br />
13 p r i v a t e JRadioButton fourButton = new JRadioButton (” Player VS<br />
Growth ”) ;<br />
14 p r i v a t e JRadioButton f i v e B u t t o n = new JRadioButton (” LocalArea<br />
VS Player ”) ;<br />
15 p r i v a t e JRadioButton sixButton = new JRadioButton (” AlphaBeta VS<br />
Player ”) ;<br />
16 p r i v a t e JRadioButton sevenButton = new JRadioButton (” Growth VS<br />
Player ”) ;<br />
17 p r i v a t e ButtonGroup group = new ButtonGroup ( ) ;<br />
18<br />
19 //To knapper som godkende e l l e r a f v i s e r det a n t a l b l o c k s som e r<br />
v a l g t .<br />
20 p r i v a t e JButton okButton = new JButton (”Ok”) ;<br />
21 p r i v a t e JButton cancelButton = new JButton (” Cancel ”) ;<br />
22<br />
23 p r i v a t e <strong>Taiji</strong>Frame tFrame ;<br />
24<br />
25 // Constructor .<br />
26 // Modtager en AtaxxFrame som argument .<br />
27 p u b l i c T a i j i S e t t i n g s ( <strong>Taiji</strong>Frame frame )<br />
28 {<br />
29 super ( frame , ” T a i j i s e t t i n g s ” , t r u e ) ;
226 Bilag A<br />
30<br />
31 tFrame = frame ;<br />
32<br />
33 JLabel q u e s t i o n = new JLabel (” S h a l l we play a game ?”) ;<br />
34 JLabel f i r s t F i l l e r = new JLabel ( ) ;<br />
35 JLabel s e c o n d F i l l e r = new JLabel ( ) ;<br />
36 JLabel t h i r d F i l l e r = new JLabel ( ) ;<br />
37 JLabel f o u r t h F i l l e r = new JLabel ( ) ;<br />
38 JLabel f i f t h F i l l e r = new JLabel ( ) ;<br />
39 JLabel s i x t h F i l l e r = new JLabel ( ) ;<br />
40<br />
41 t h i s . getContentPane ( ) . setLayout ( new BorderLayout ( ) ) ;<br />
42 t h i s . getContentPane ( ) . add ( mainPanel , ” Center ”) ;<br />
43<br />
44 mainPanel . setLayout ( new GridLayout ( 8 , 2 , 1 0 , 0 ) ) ;<br />
45 mainPanel . add ( q u e s t i o n ) ;<br />
46 mainPanel . add ( oneButton ) ;<br />
47 mainPanel . add ( f i r s t F i l l e r ) ;<br />
48 mainPanel . add ( twoButton ) ;<br />
49 mainPanel . add ( s e c o n d F i l l e r ) ;<br />
50 mainPanel . add ( threeButton ) ;<br />
51 mainPanel . add ( t h i r d F i l l e r ) ;<br />
52 mainPanel . add ( fourButton ) ;<br />
53 mainPanel . add ( f o u r t h F i l l e r ) ;<br />
54 mainPanel . add ( f i v e B u t t o n ) ;<br />
55 mainPanel . add ( f i f t h F i l l e r ) ;<br />
56 mainPanel . add ( sixButton ) ;<br />
57 mainPanel . add ( s i x t h F i l l e r ) ;<br />
58 mainPanel . add ( sevenButton ) ;<br />
59 mainPanel . add ( okButton ) ;<br />
60 mainPanel . add ( cancelButton ) ;<br />
61<br />
62 group . add ( oneButton ) ;<br />
63 group . add ( twoButton ) ;<br />
64 group . add ( threeButton ) ;<br />
65 group . add ( fourButton ) ;<br />
66 group . add ( f i v e B u t t o n ) ;<br />
67 group . add ( sixButton ) ;<br />
68 group . add ( sevenButton ) ;<br />
69 oneButton . setActionCommand ( ” 1 ” ) ;<br />
70 twoButton . setActionCommand ( ” 2 ” ) ;<br />
71 threeButton . setActionCommand ( ” 3 ” ) ;<br />
72 fourButton . setActionCommand ( ” 4 ” ) ;<br />
73 f i v e B u t t o n . setActionCommand ( ” 5 ” ) ;<br />
74 sixButton . setActionCommand ( ” 6 ” ) ;<br />
75 sevenButton . setActionCommand ( ” 7 ” ) ;<br />
76 oneButton . s e t S e l e c t e d ( t r u e ) ;<br />
77 twoButton . s e t S e l e c t e d ( f a l s e ) ;<br />
78 threeButton . s e t S e l e c t e d ( f a l s e ) ;<br />
79 fourButton . s e t S e l e c t e d ( f a l s e ) ;<br />
80 f i v e B u t t o n . s e t S e l e c t e d ( f a l s e ) ;<br />
81 sixButton . s e t S e l e c t e d ( f a l s e ) ;<br />
82 sevenButton . s e t S e l e c t e d ( f a l s e ) ;<br />
83<br />
84 S e t t i n g s L i s t e n e r BLis = new S e t t i n g s L i s t e n e r ( ) ;
A.16 <strong>Taiji</strong>Settings.java 227<br />
85 okButton . a d d A c t i o n L i s t e n e r ( BLis ) ;<br />
86 cancelButton . a d d A c t i o n L i s t e n e r ( BLis ) ;<br />
87<br />
88 t h i s . pack ( ) ;<br />
89 }<br />
90<br />
91 //Metode der goer d i a l o g e n s y n l i g .<br />
92 p u b l i c void showIt ( )<br />
93 {<br />
94 s e t V i s i b l e ( t r u e ) ;<br />
95 }<br />
96<br />
97 // L i s t e n e r −k l a s s e n t i l d i a l o g e n . Implementerer i n t e r f a c e t<br />
A c t i o n L i s t e n e r .<br />
98 // Giver enten e t s a e t b l o c k s v i d e r e t i l r e s e t i AtaxxModel ,<br />
e l l e r gaar ud a f d i a l o g e n uden at s t a r t e e t nyt s p i l .<br />
99 c l a s s S e t t i n g s L i s t e n e r implements A c t i o n L i s t e n e r<br />
100 {<br />
101 //Metode der r e a g e r e r paa e t ActionEvent . Ved ok gaar den<br />
v i d e r e t i l at s t a r t e e t nyt s p i l , ved e t h v e r t andet<br />
event l u k k e s d i a l o g e n .<br />
102 // Modtager e t ActionEvent som argument .<br />
103 p u b l i c void actionPerformed ( ActionEvent evt )<br />
104 {<br />
105 i f ( evt . getActionCommand ( ) . e q u a l s (”Ok”) )<br />
106 {<br />
107 i n t s e t = I n t e g e r . p a r s e I n t ( group . g e t S e l e c t i o n ( )<br />
. getActionCommand ( ) ) ;<br />
108 System . out . p r i n t l n (” S e t t i n g ”+s e t ) ;<br />
109 i f ( s e t == 1) { // Player VS Player<br />
110 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
111 tFrame . tModel . setWhitePlayer ( 0 ) ;<br />
112 tFrame . tModel . s e t B l a c k P l a y e r ( 0 ) ;<br />
113 }<br />
114 i f ( s e t == 2) { // Player VS LocalArea<br />
115 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
116 tFrame . tModel . setWhitePlayer ( 0 ) ;<br />
117 tFrame . tModel . s e t B l a c k P l a y e r ( 6 ) ;<br />
118 }<br />
119 i f ( s e t == 3) { // Player VS AlphaBeta<br />
120 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
121 tFrame . tModel . setWhitePlayer ( 0 ) ;<br />
122 tFrame . tModel . s e t B l a c k P l a y e r ( 2 ) ;<br />
123 }<br />
124 i f ( s e t == 4) { // Player VS Growth<br />
125 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
126 tFrame . tModel . setWhitePlayer ( 0 ) ;<br />
127 tFrame . tModel . s e t B l a c k P l a y e r ( 4 ) ;<br />
128 }<br />
129 i f ( s e t == 5) { // LocalAera VS Player<br />
130 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
131 tFrame . tModel . setWhitePlayer ( 6 ) ;<br />
132 tFrame . tModel . s e t B l a c k P l a y e r ( 0 ) ;<br />
133 }<br />
134 i f ( s e t == 6) { // AlphaBeta VS Player
228 Bilag A<br />
135 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
136 tFrame . tModel . setWhitePlayer ( 2 ) ;<br />
137 tFrame . tModel . s e t B l a c k P l a y e r ( 0 ) ;<br />
138 }<br />
139 i f ( s e t == 7) { // Growth VS Player<br />
140 tFrame . tModel . s e t S t a r t e r ( 1 ) ;<br />
141 tFrame . tModel . setWhitePlayer ( 4 ) ;<br />
142 tFrame . tModel . s e t B l a c k P l a y e r ( 0 ) ;<br />
143 }<br />
144 tFrame . tModel . r e s e t ( ) ;<br />
145 tFrame . r e p a i n t A l l ( ) ;<br />
146 s e t V i s i b l e ( f a l s e ) ;<br />
147 }<br />
148 e l s e<br />
149 {<br />
150 s e t V i s i b l e ( f a l s e ) ;<br />
151 }<br />
152 }<br />
153 }<br />
154 }<br />
A.17 Tree.java<br />
1 import java . u t i l . ArrayList ;<br />
2 p u b l i c c l a s s Tree { // denne k l a s s e e r kun anvendt i Minimax AI ’ en<br />
3 p u b l i c Node Root ;<br />
4 p u b l i c Node Cur ; // c u r r e n t node<br />
5 p u b l i c ArrayList evenGen ;<br />
6 p u b l i c ArrayList oddGen ;<br />
7 p u b l i c ArrayList Leaves ;<br />
8 p u b l i c i n t curLeaves ; // Current number o f l e a v e s<br />
9 p u b l i c i n t t o t a l L e a v e s ; // Temperary number o f l e a v e s . curLeaves<br />
+newly added l e a v e s .<br />
10 p u b l i c i n t curMin ;<br />
11 p u b l i c i n t curMax ;<br />
12<br />
13<br />
14 p u b l i c Tree ( ) {<br />
15 Root = new Node ( ) ;<br />
16 Cur = new Node ( ) ;<br />
17 Leaves = new ArrayList () ;<br />
18 evenGen = new ArrayList () ;<br />
19 oddGen = new ArrayList () ;<br />
20<br />
21 }<br />
22<br />
23 // s a e t t e r roden<br />
24 p u b l i c void setRoot ( Node n ) {<br />
25 Root = n ;<br />
26 }<br />
27 // s a e t t e r c u r r e n t node<br />
28 p u b l i c void setCur ( Node n ) {<br />
29 Cur = n ;
A.17 Tree.java 229<br />
30 }<br />
31<br />
32 // t i l f o e j e r e t blad<br />
33 p u b l i c void addLeave ( Node n ) {<br />
34 Leaves . add ( n ) ;<br />
35 }<br />
36<br />
37 p u b l i c void addMin ( Node n ) {<br />
38 curMin++;<br />
39 }<br />
40<br />
41<br />
42 p u b l i c void addMax( Node n ) {<br />
43 curMax++;<br />
44 }<br />
45<br />
46 p u b l i c void resetMin ( ) {<br />
47 curMin =0;<br />
48 }<br />
49<br />
50 p u b l i c void resetMax ( ) {<br />
51 curMax=0;<br />
52 }<br />
53<br />
54 p u b l i c void addLeaveT ( Node n ) {<br />
55 t o t a l L e a v e s ++;<br />
56 }<br />
57<br />
58 p u b l i c void removeLeave ( i n t l ) {<br />
59 Leaves . remove ( l ) ;<br />
60 }<br />
61<br />
62 p u b l i c void removeLeaveT ( i n t l ) {<br />
63 t o t a l L e a v e s −−;<br />
64 }<br />
65<br />
66 p u b l i c void removeLeaveC ( i n t l ) {<br />
67 curLeaves −−;<br />
68 t o t a l L e a v e s −−;<br />
69 }<br />
70<br />
71<br />
72 p u b l i c i n t getCurLeaves ( ) {<br />
73 r e t u r n ( curLeaves ) ;<br />
74 }<br />
75<br />
76 }
230
Bilag B<br />
B.1 Hjemmesider:<br />
<strong>Taiji</strong> beskrivelse p˚a boardgamegeek.com<br />
http://www.boardgamegeek.com/boardgame/31926<br />
Sidst besøgt: 1/10-09<br />
<strong>Taiji</strong> anmeldelse p˚a ogrecave.com<br />
http://ogrecave.com/reviews/taiji.shtml<br />
Sidst besøgt: 1/10-09<br />
Opfriskning af Java<br />
http://javabog.dk/<br />
Sidst besøgt: 1/10-09<br />
B.2 Bøger:<br />
Kildeliste<br />
”Artificial Inteligence - A Moderne Approach - Second Edition”<br />
af Stuart J. Russel og Peter Norvig
232 Bilag B<br />
”Introduction to Algorithms - Second Edition”<br />
af Thmos H. Cormen, Charles E. Leiserson, Ronald L. Rivest og Clifford Stein
233
234