09.09.2013 Views

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

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!