244
Kunstig Intelligens til Brætspillet Taiji Morten Rask Kongens Lyngby 2009 IMM-MSC-2009-66

Kunstig Intelligens til Brætspillet Taijietd.dtu.dk/thesis/250864/ep09_66.pdf · Summary This project concerns the development of several arti cial intelligences to the board game

  • Upload
    dangdan

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

Kunstig Intelligens til BrætspilletTaiji

Morten Rask

Kongens Lyngby 2009IMM-MSC-2009-66

Technical University of DenmarkInformatics and Mathematical ModellingBuilding 321, DK-2800 Kongens Lyngby, DenmarkPhone +45 45253351, Fax +45 [email protected]

Summary

This project concerns the development of several artificial intelligences to theboard game Taiji. Taiji is a fully observable abstract strategic game where twoopponents each will try to score the most points by forming a larger figure onthe board than the opponent’s figure.

Taiji is a relatively new game released in the year 2007 and therefore therehas not yet been developed an effective artificial intelligence (AI) for the game.The game’s designer, Nestor Romeral Andres, has developed a simple AI for thegame, but it requires great computing power at the high difficulty levels withouteven necessarily defeating a human opponent.

The project aims to develop an effective AI to Taiji. In the first phase is im-plemented a classical AI-based search in a Minimax game tree. This involves,among other, construction of an appropriate heuristics for the game. The nextstage is to examine further opportunities for improvement and development ofmore advanced AI’er. This includes, inter alia, an upgrade from game tree togame graph. Game tree gives as the name indicates only the opportunity tofollow structure of the path, while the game graph allows move across structureof the path and thus is considerably more comprehensive.

The project also includes an analysis of the game’s complexity and a scoreof winning strategies for different board sizes.

The physical implementation of the game and the artificial intelligences havebeen made in Java.

ii

Resume

Dette projekt omhandler udviklingen af flere kunstige intelligenser til brætspilletTaiji. Taiji er et fuldt observerbart abstrakt strategisk spil, hvor to modstanderhver især forsøger at score flest point ved at danne en større figur pa brættetend modstanderens figur.

Taiji er et forholdsvis nyt spil udgivet i ar 2007 og derfor er der endnu ikkeblevet udviklet en effektiv Artificial intelligence (AI) til spillet. Spillets designer,Nestor Romeral Andres, har udviklet en simpel AI til spillet, men den kræverstor computerkraft pa de høje sværhedsgrader uden nødvendigvis at besejre enmenneskelig modstander.

Malet med projektet er at udvikle en effektiv AI til Taiji. I første fase imple-menteres en klassisk AI baseret pa minimax søgning i et spiltræ. Dette involvereblandt andet konstruktion af en passende heuristik for spillet. I næste fase un-dersøges yderligere muligheder for forbedringer og udvikling af mere avanceredeAI’er. Dette inkludere blandt andet en opgradering fra spiltræ til spilgraf. Spil-træ giver som navnet angiver kun mulighed for at følge stistruktur, mens spilgrafgiver mulighed for ga pa tværs af stistruktur og dermed er væsentligt mere om-fattende.

Projektet indeholder ogsa en analyse af spillets kompleksitet og en vurderingaf vinderstrategier for forskellige brætstørrelser.

Den fysiske Implementeringen af spillet og de kunstige intelligenser er blevetforetaget i Java.

iv

Forord

Dette speciale er udarbejdet ved Institut for Informatik og Matematisk Model-lering, Danmarks Tekniske Universitet, som en del af kravene til færdiggørelsenaf kandidatuddannelsen.

Dette speciale omhandler kunstig intelligens i brætspillet Taiji og en analyseaf spillet.

Dette projekt blev lavet i perioden fra den 6. april 2009 til den 5. oktober2009 under vejledning af Thomas Bolander.

Jeg vil gerne takke Thomas Bolander for hjælp og vejledning gennem heleforløbet, og David Christian Askirk for feedback pa rapporten. Rapporten kun-ne ikke være udført uden bogen ”Artificial Intelligence - A Modern Approach”afStuart J. Russel og Peter Norvig. Og sidst, men ikke mindst et tak til NestorRomeral Andres for at have bragt brætspillet Taiji til verden.

Lyngby, oktober 2009

Morten Rasks031736

vi

Indhold

Summary i

Resume iii

Forord v

1 Taiji 11.1 Spillets regler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Nestors AI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.3 Generele egenskaber for Taiji . . . . . . . . . . . . . . . . . . . . 41.4 Spillets kompleksitet . . . . . . . . . . . . . . . . . . . . . . . . . 14

2 Design og brugervenlighed 212.1 Vurdering af Nestors Interface . . . . . . . . . . . . . . . . . . . . 212.2 Design af eget Interface . . . . . . . . . . . . . . . . . . . . . . . 26

3 Kunstig Intelligens 313.1 Programmet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313.2 Generelle datastrukturer og metoder . . . . . . . . . . . . . . . . 353.3 Heuristik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4 Minimax 394.1 Beskrivelse af Minimax med brede-først søgning . . . . . . . . . . 404.2 Beskrivelse af Minimax med dybde-først søgning . . . . . . . . . 414.3 Spilgraf for 3x3 Taiji spil: . . . . . . . . . . . . . . . . . . . . . . 42

5 Optimering af Minimax 515.1 Spilgraf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2 Rotationer og spejlinger . . . . . . . . . . . . . . . . . . . . . . . 53

viii INDHOLD

5.3 Hash funktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555.4 Alpha-beta pruning . . . . . . . . . . . . . . . . . . . . . . . . . . 60

6 Begrænsning af antallet af undersøgte træk 716.1 Local Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716.2 Growth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

7 Test og sammenligning af de implementerede AI’er 777.1 Test af Nestor’s AI . . . . . . . . . . . . . . . . . . . . . . . . . . 777.2 Test af AlphaBeta AI (udviklet af Morten Rask) . . . . . . . . . 817.3 Test af LocalArea AI (designet og udviklet af Morten Rask) . . . 857.4 Test af Growth AI (designet og udviklet af Morten Rask) . . . . 877.5 Sammenligning af AI’erne . . . . . . . . . . . . . . . . . . . . . . 90

8 Konklusion 91

A Kildekode 95A.1 AITaijiAlphaBeta.java . . . . . . . . . . . . . . . . . . . . . . . . 95A.2 AITaijiGrowth.java . . . . . . . . . . . . . . . . . . . . . . . . . . 106A.3 AITaijiLocalAreaAB.java . . . . . . . . . . . . . . . . . . . . . . 130A.4 AITaijiMinimax.java . . . . . . . . . . . . . . . . . . . . . . . . . 142A.5 Board.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155A.6 FigureMap.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162A.7 Node.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171A.8 TaijiDriver.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173A.9 TaijiFrame.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173A.10 TaijiHash.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174A.11 TaijiListeners.java . . . . . . . . . . . . . . . . . . . . . . . . . . 176A.12 TaijiMenu.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182A.13 TaijiModel.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183A.14 TaijiPanels.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200A.15 TaijiPrint.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204A.16 TaijiSettings.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 225A.17 Tree.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

B Kildeliste 231B.1 Hjemmesider: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231B.2 Bøger: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

Kapitel 1

Taiji

Taiji er kinesisk og kan oversættes til Den Store Absolut. Taiji opfattes som detstørst tænkelige princip, der indeholder yin og yang, hvor af alt udspringer. Yinog yang, lyset og mørket, modstandere, der ikke kan eksister uden hinanden.Deraf udspringer ideen i spillet Taiji. For hver brik du lægger, lægger du badeen lys og en mørk side, den ene vil hjælpe dig og den anden vil kunne hjælpedin modstander. Taiji er designet af Nestor Romeral Andres og udgivet af BluePanther Games i 2007. Her under ses Taiji-brættet pa ni gange ni felter og enTaiji-brik:

2 Taiji

Figur 1.1: Standard Taiji bræt pa 9x9 felter og en Taiji-brik.

1.0.1 Kildemateriale for Taiji

Da Taiji er et forholdsvis nyt spil, har det eneste tilgængelige kildematerialeomkring Taiji, været de officielle regler til spillet. Det er heller ikke lykkedes atfinde et ældre spil, der i sin natur ligger sa tæt opad Taiji, at materiale om etsadan spil har kunne anvendes direkte pa Taiji eller som inspiration til skabelsenaf en effektiv AI for spillet Taiji.Dette betyder at konklusioner draget omkring spillet Taiji er baseret pa mineegne undersøgelser og ideer, medmindre andet er angivet.

1.1 Spillets regler 3

1.1 Spillets regler

Taiji spilles af to spiller pa en plade af ni gange ni felter. Spillerne skiftes til atlægge en brik pa brættet. Nar en brik bliver lagt pa brættet er den endeligt lagt,der bliver hverken fjernet eller flyttet brikker undervejs i spillet. Brikkerne haren størrelse der svare til to felter pa spillepladen. Disse brikker har alle en lysog en mørk ende og er ens for begge spillere. Selvom de to spillere spiller medsamme brikker, spiller den ene som hvid og den anden som sort. Det gælderfor begge spillere om at bygge de to største figurer i sin farve. En figur bestaraf sammenhængende felter i en farve. To felter skal ligge opad hinanden entenlodret eller vandret for at kunne siges at hænge sammen, diagonalt tæller ikke.Scoren tælles op for hver spiller ved at tælle antallet af felter, der indgar i spil-lerens to største figurer. Den spiller der har den højeste score, nar der ikke kanlægges flere brikker, har vundet. Et eksempel pa et afsluttet spil kan se saledesud:

Figur 1.2: Afsluttet spil med score.

I dette tilfælde er det sort som vinder med 17 point mod hvids 15 point.

4 Taiji

1.1.1 Forskelle mellem de officielle regler og mine

Ifølge de officielle regler skal brætstørrelsen være minimum ni gange ni, kva-dratisk og side længden skal være pa et ulige tal. Jeg ser derimod pa allebrætstørrelser, med lige sider, rektangulære og mindre end ni gange ni.De officielle regler siger ogsa at et spil, hvor scoren ender lige, tæller som ensejr til sort. Som udgangspunkt i denne opgave ser jeg pa et lige resultat somet uafgjort resultat. Det vil undervejs blive set pa hvilke forskelle dette har forspillet.

1.2 Nestors AI

Nestor skaberen af Taiji har selv lavet en AI til spillet med fire sværhedsgra-der. Nestor har dog ikke oplyst hvordan disse AI er lavet og der vides derforhvordan de faktisk fungerer. Pa den højeste sværhedsgrad bruger AI’en godt ogvel 30 sekunder pa at beregne sit træk. Beregningstiden bliver dog lavere somspillet nærmere sig sin afslutning, og de mulige træk bliver færre. Selvom pro-grammet bruger forholdsvis megen computerkraft - deraf den forholdsvis langeberegningstid - er det muligt for en rutineret Taiji-spiller at sla af den kunsti-ge intelligens og sa endda rimeligt overbevisende. Efter selv at have arbejdetmed spillet gennem længere tid lykkedes det mig at sla Nestors AI pa højestesværhedsgrad med scoren 19-8.

1.3 Generele egenskaber for Taiji

Der er et begrænset antal træk i et Taiji-spil. Dette skyldes, at der hverken fjer-nes eller flyttes brikker undervejs i spillet og det er derfor begrænset hvor mangetræk, der kan fortages i et spil. Antallet af brikker, der kan lægges bestemmesfra start af brætstørrelsen, men som spillet skrider frem vil dette antal oftestfalde yderligere, da spillerne kun kan lægge deres brikker som dækker to felter,sa nogle de fri felter pa brættet bliver uanvendelige.

1.3 Generele egenskaber for Taiji 5

1.3.1 Maksimum antal træk

Da der hverken fjernes eller flyttes brikker undervejs i spillet, er spillets længdeudelukkende styret af hvor mange brikker det er muligt at lægge pa brættet.Hver brik fylder to fletter og spillepladen er normalt er pa 9 gange 9 felter.Dette betyder at det maksimale antal brikker der ville kunne lægges og dermeddet maksimale antal træk, vil være brættets størrelse divideret med brikkernesstørrelse. I tilfælde af decimaltal vil der naturligvis skulle rundes ned, da detikke er tilladt at lægge halve eller pa anden made delte brikker. For en stan-dardspilleplade betyder dette at spillet vil strække sig over maksimalt 40 træk.Altsa ni gange ni divideret med to og rundet ned ((9 ·9)/2 = 81/2 = 40, 5 ∼ 40).

Brætlængde x Brætbredde / 2 ≥ antallet af træk

Som spillet skrider frem kan det maksimale antal tilbageværende træk falde.Selvfølgelig vil antallet af træk blive reduceret med en for hver brik der bliverlagt. Derudover vil nogle træk tage pladsen for mere end en brik. Dette sker narbrikker placeres saledes, at de efterlader tomme omrader der ikke er store noktil at en brik kan placeres i dem. Ud fra dette er det muligt undervejs i spilletat beregne et opdateret og derved mere præcist upper-bound for antallet aftilbageværende træk. Denne nye beregning tager udgangspunkt i den foregaendeberegning og tilføjer en reducering af antal af træk baseret pa antal af brikkerpa brættet og antal af tomme omrader, hvor det ikke længere er muligt at læggebrikker. Da brikkerne er pa et gange to felter, vil et frit omrade der ikke længerekan spilles pa altid kun være pa et enkelt flet.

( Brætlængde x Brætbredde / 2) - antallet af træk - ( enkeltstaende frie felter/ 2 ) ≤ tilbageværende træk

eks:

Figur 1.3: 4x4 Taiji-plade med 3 brikker.

(4 x 4 / 2) - 3 - (1 / 2) = 4,5

6 Taiji

Altsa kan der maksimalt fortages yderligere 4 træk.

1.3.2 Minimum antal træk

Den mindste forekomst af Taiji, hvor mængden af træk kan reduceres undervejs,er 3x2. Her er det muligt at reducere antallet af træk fra 3 til 2. Dette sker vedat brikkerne lægges saledes at der opstar to indelukkede tomme felter:

Figur 1.4: 3x2 Taiji-plade afsluttet med minimum antal brikker.

Der bruges her en brik per indelukket tomt felt.

For 4x2 felter er det kun muligt at lave to tomme indelukkede felter:

Figur 1.5: To 4x2 Taiji-plader afsluttet med minimum antal brikker.

I dette tilfæde er det dog ikke muligt at skabe et tomt felt per brik, men derbruges stadig minimum en brik per tomt indelukket felt.

For 3x3 felter:

Figur 1.6: En 3x3 Taiji-plade afsluttet med minimum antal brikker.

1.3 Generele egenskaber for Taiji 7

Resultatet er her et tomt felt per brik.

For 4x3 felter:

Figur 1.7: To 4x3 Taiji-plader afsluttet med minimum antal brikker.

Resultatet er igen et tomt felt per brik.

For at bevise at det ikke er muligt at danne et tomt felt per brik, ses der pa detmest repræsentative eksempel pa et bræt, hvor der skal absolut mindst til forat danne et indelukket tomt felt, nemlig et bræt der kun har et felt pa den eneled:

Figur 1.8: En vilkarligt lang og en høj Taiji-plade med minimum antal brikker.

Her er det tydeligt at der skal en brik til for at danne et nyt indelukket tomtfelt. Hvis det forsøges med færre brikker, vil hulerne blive sa store, at der kanplaceres brikker i dem. Det er simpelthen ikke muligt at danne tomme feltermed mindre en brik per tomt felt.Derfor bliver det minimale antal træk følgende:

Brætlængde x Brætbredde / (2 + 1) ≤ = antallet af træk

Et standard spil, hvor brætstørrelsen er pa ni gange ni felter, vil derfor ikkevære slut før minimum 27 brikker er blevet lagt pa brættet.

For 9x9 felter er det muligt at lave dette eksempel pa et bræt med det minimaleantal træk for denne størrelse:

8 Taiji

Figur 1.9: Et standard Taiji-bræt afsluttet med minimum antal brikker.

Ud fra disse antagelser er det muligt at beregne det minimale antal træk for stan-dardbrætstørrelsen 9x9. Det kan ses som værende blot gentagelser af mønstretfra brættet pa 2x3 felter:

1.3 Generele egenskaber for Taiji 9

Figur 1.10: Standard Taiji-brættet opdelt i stykker pa 3x2.

Med denne metode er det muligt at beregne det minimale antal træk, sa længe3 gar op i enten højden eller bredden af brættet. Det er dog ikke et krav, at 3skal ga op i højden eller bredden, for at det er muligt at opna et tomt felt perbrik. Men da et tomt felt og en brik optager 3 felter, er det et krav at 3 gar opi det samlede antal felter, før dette er muligt.

X · Y = Z · 3⇔ X · Y3

= Z ⇔ X

3=

Z

Y

3 skal ga op i X før X/3 kan blive et helt tal. Er dette ikke tilfældet skal 3 ga opi Y for at kunne matche X antal tredjedele pa den anden side, da 3 er et primtalog brøken derfor ikke kan reduceres yderligere.Det er altsa kun muligt at opna det minimale antal træk, hvis 3 gar op i entenhøjden eller bredden. Dette vil ogsa kunne ses i formlen i form af decimaltal.I disse tilfælde vil formlen for det minimale antal træk ikke give et helt tal, mendet er ikke helt enkelt om dette resultat sa skal rundes op eller ned. Her er nogleeksempler:

1x5: Formlen giver her 1,67, mens det er ikke muligt at afslutte spillet medmindre end to brikker.

4x4: Her giver formlen 5,3, hvilket normalt ville være et tal der rundes ned, mendet er ikke muligt at afslutte et spil af denne størrelse med mindre end 6 brikker.

10 Taiji

Der er dog en række special tilfælde, hvor det med en brik er muligt at danneto enkeltstaende tomme felter, et pa hver side af brikken. Disse er bræt pa 1gange 3 ·X + 1 og selvfølgelig ogsa 3 ·X + 1 gange 1.Det første eksempel her pa er 4x1. Her vil en brik, der placeret i midten af dettebræt, resultere i to uanvendelige tomme felter:

Figur 1.11: 4x1 Taiji-bræt afsluttet med minimum antal brikker.

Resultatet af formlen bliver 1,33, men det er muligt at afslutte spillet med enenkelt brik.

For et større tilfælde som f.eks. 13 gange 1:

Figur 1.12: 13x1 Taiji-bræt afsluttet med minimum antal brikker.

Resultatet af formlen bliver her 4,33, men igen er det muligt at afslutte spilletmed kun 4 brikker.

Det er en mulighed at runde resultaterne op og se pa disse tilfælde som und-tagelser pa formlen, men da formelen skal bruges som et lower-bound estimat,vil det være en udmærket løsning altid at runde resultatet ned, da det ikke vilvære et problem at nogle brætstørrelser ikke vil kunne na deres beregnede mini-mum for antallet af træk. Det ville være langt mere problematisk, hvis noglebrætstørrelser kunne afsluttes før forventet.

1.3.3 Maksimum antal point

Teoretisk set vil det størst mulige antal point nas ved at forbinde alle brikker afen farve i en eller to figurer. Antallet vil svare til halvdelen af brættets størrelse,da den anden halvdel selvfølgelig vil ga til modstanderens farve. Her skal antalletnaturligvis ogsa rundes ned til et helt tal. I praksis viser dette sig ogsa at væretilfældet. Dette forekommer især ved sma plader. Ved det ekstreme tilfælde af

1.3 Generele egenskaber for Taiji 11

den minimale størrelse pa to gange to felter, ville begge spiller altid na topscorenpa to points uanset hvordan de bære sig ad, enten i form af to figurer pa hvertet felt eller en figur pa to felter.

Figur 1.13: Mulige afslutninger for et Taiji-bræt pa 2x2.

Dette gør ogsa denne minimale brætstørrelse højst uinteressant at arbejde med.Men uanset størrelsen vil det altid være muligt at sammensætte et spil der giverden maksimale score for en eller begge spillere. Dette er muligt ved at fylde etbræt ud saledes, at alle felter for hver farve er del af en af de to største figurerfor farven. Det er selvfølgelig ogsa nødvendigt, at brikkerne ligger sa de ikkeskaber uanvendelige tomme felter. Det kan f.eks. gøres saledes:

Figur 1.14: Eksempel pa maksimal score for begge spiller.

Det kræver lidt mere variation at opna den højeste score for begge spiller, narbrættets sider er ulige, men dette kan ogsa opnas:

12 Taiji

Figur 1.15: Eksempel pa maksimal score for begge spiller pa en standardplade.

Disse og lignende mønstre kan altid anvendes til at lave den maksimale score,hvis begge spiller gar efter det. Det kan f.eks. gøres ud fra denne form:

Figur 1.16: Formel for creation af bræt med max point med minimum en ligeside.

1.3 Generele egenskaber for Taiji 13

Figur 1.17: Formel for creation af bræt med max point med ulige sider.

1.3.4 Sammenfatning af de generelle træk

Det er muligt fra spillets start at beregne et minimum og maksimum for hvormange træk spillet vil strække sig over. Minimum vil være en hjælpende faktori at bedømme spillets kompleksitet. Det samme gælder maksimum, men det vilf.eks. ogsa kunne anvendes til at bedømme hvornar det bliver muligt at beregneen fuldstændig løsning, efter et spil er gaet i gang.Det viste sig at scoren for de to spillere kunne blive sa høj, som det overhovedetkunne forventes, nemlig højden gange bredden divideret med to, da hver brikfylder to felter og tilføjer bade et sort og et hvidt felt. Hvor mængden af trækforholdsvist nemt kan beregnes undervejs i et spil, er det en langt mere krævendeopgave at beregne scorens muligheder inde i spillet, da denne afhænger af allebrikkerne og deres placeringer, ikke kun antallet af brikker og antallet af uan-vendelige felter pa brættet. Det ville ellers give mulighed for at stoppe spillet,nar f.eks. den ene spillers mulige maksimum bliver overgaet af den anden spil-lers nuværende score. Disse værdi kunne ogsa bruges af en kunstig intelligens,ved at forsøge at holde sin mulige maksimum score sa høj som mulig og øge sinminimums score, samtidig med at reducere modstanderens mulige maksimumscore og holde den minimums scoren nede.

14 Taiji

1.4 Spillets kompleksitet

Standard størrelsen for et spil Taiji er pa ni gange ni felter. Dette lyder maskeikke til at være sa stort, men sammenlignes det f.eks. med skak er det et feltmere pa hver led og selvom antallet af træk er begrænset i Taiji, sa er der færrerestriktioner pa hvilke træk, der kan foretages. Forsker har estimeret antal aflovlige spilstadier i skak til at være 1043. 1

1.4.1 Upper-bound estimat for antal af spilstadier

Et forholdsvist simpelt upper-bound estimat kan laves ved at se pa antallet afmulige spilstadier, hvis restriktionerne af brikker fjernes, saledes at der er nigange ni felt som hvert kan patage sig værdierne sort, hvid og tomt uafhængigtaf hinanden. I sa fald bliver antal af mulige spilstadier antallet af værdier perfelt opløftet i antallet af felter.

381 = 4, 43 · 1038

Brikker giver vise restriktioner og derved reduceres dette tal. Restriktionen atder skal være minimum et hvidt felt opad hvert sort felt og minimum et sortfelt opad alle hvide felter, er meget svær at indføre.En anden restriktion, der ogsa kommer af brikkernes udformning, er at derfor alle spilstadier skal være lige mange sorte og hvide felter. Denne er ogsa, imodsætning til forrige restriktion, uafhængig af brættets form, om brættet er 9gange 9 eller 81 gange 1 er ligegyldigt.Pa et bræt med et enkelt felt, hvor der normalt vil være tre kombinationsmu-ligheder, vil den eneste mulighed med lige mange hvide og sorte felter, væreet tomt bræt. For et bræt med to felter, hvor der normalt vil være ni kom-binationsmuligheder, vil der være tre gyldige kombinationer, et tomt bræt, tobrætter med et sort og et hvidt felt.Herunder ses en tabel over antallet af kombinationsmuligheder for op til 6 felterog antallet af kombinations muligheder med og uden restriktionen, at der skalvære lige mange sorte og hvide felter:

1Tallet kommer af estimatet 64!32!·8!2·2!6 ≈ 1043 som er givet af Claude E. Shannon i ”Pro-

gramming a Computer for Playing Chess”, Phil. Mag. 41 (1950) 256-275).

1.4 Spillets kompleksitet 15

Antal felter Kombinationer Efter Restriktionen Procentdel1 3 1 33,3%2 9 3 33,3%3 27 7 25,9%4 81 19 23,5%5 243 49 20,2%6 729 137 18,8%

Tabellen viser at procentdelen af gyldige kombinationsmuligheder falder somantallet af felter stiger. Derfor kan antallet af spilstadier i alle tilfælde roligt re-duceres med en tredjedel. Ligeledes kan antallet af spilstadier for standardbræt-tet pa ni gange ni felter roligt reduceres til en 20% . Derved kan upper-boundestimatet reduceres fra 4,43 · 1038 til 1038.

1.4.2 Lower-bound estimat for antal af spil forløb

I dette afsnit estimeres der et lower-bound for antal spil forløb, eller kombina-tionsmuligheder for trækkene gennem et spil.I Taiji er der med et bræt pa ni gange ni felter maksimalt 40 træk, da dette erdet maksimale antal brikker, der kan lægges. Der er ni gange ni felter at gøregodt med pa brættet og hver brik fylder to felter.

9 · 92

= 40, 5

Og det er naturligvis ikke muligt at lægge en halv brik. Der vil ikke altid være40 træk, da det er muligt at lægge brikkerne saledes at de efterlader fri felterhvor det ikke er muligt at fa plads til en brik. Dette forekommer nar et enkelttomt felt omkredses af brikker og evt. brættets kanter.

Figuren her under illustrerer de mulige træk:

16 Taiji

Figur 1.18: Alle trækmuligheder for et standardbræt. Hver streg repræsentereen brik og de to mader, som brikken kan vende pa.

Der er ni gange ni felter. Hver sort streg illustrere to mulige træk, nemlig de træksom kan laves pa de to felter stregen indgar i. En sort-hvid brik lagt vandret,hvis stregen er vandret, og lodret, hvis stregen er lodret og samme brik medsamme placering blot vendt 180 grader.I dette tilfælde er der i alt 144 sorte streger (8x9 vandrette og 9x8 lodrette), medandre ord er der 288 mulige træk. Til sammenligning er der i skak 20 mulighederfor første træk (otte bønder med to mulige træk hver og to springer med hverto mulige træk).Nar der lægges en brik pa brættet udelukkes der maksimalt 14 mulige træk, daen brik pa to felter højst vil overlappe 7 streger:

Figur 1.19: Repræsentation af det største antal træk en brik kan udelukke.

Det minimale antal mulige træk, der kan udelukkes vil, være 2. Dette vil kunske i tilfælde hvor alle felter omkring brikken er optaget:

1.4 Spillets kompleksitet 17

Figur 1.20: Repræsentation af det mindeste antal træk en brik kan udelukke.

Et lower-bound resultat kan udregnes ved at tage de 288 mulige træk og gangedem sammen med de efterfølgende træk, hvor antallet af mulige træk hver gangreduceres med de maksimale 14 træk per tur:

28814≈ 20, 57

20, 57! · 1420,57 ≈ 5, 208 · 1042

eller mere præcist:

288·274·260·246·232·218·204·190·176·162·148·134·120·106·92·78·64·50·36·22·8

≈ 1, 035 · 1043

Dette minimum vil dog være et godt stykke under det reelle antal mulige træk-kombinationer. Dette lower-bound estimat resulterer f.eks. i at der kun er i alt21 træk, hvor det tidligere er blevet vist at der minimum vil blive foretaget 27træk i et spil Taiji pa et bræt med ni gange ni felter.

Udover at lower-bound estimat har færre træk end et rigtigt spil, reducere detogsa antallet af mulige træk med de maksimale 14 træk per tur. At reducereantallet af muligheder med 14 er kun muligt, nar en brik kan lægges uden athave nogen restriktioner omkring sig. Dette forventes med et bræt pa ni gangeni felter højst at kunne gøres 11 gange, som det ses i eksemplet herunder:

18 Taiji

Figur 1.21: Denne figur viser en af maderne de 11 brikker kan lægges, hvor dehver især reducerer antal af mulige træk mest.

Efter at de 11 brikker er blevet lagt, er det ikke længere muligt at finde enplacering hvor en brik kan reducere antallet af mulige træk med mere end 12.Og der kan ikke foretages mange træk før det bliver mindre end 12.

1.4.3 Estimat af antallet af mulige trækkombinationer i etgennemsnits spil:

For at lave et estimat pa gennemsnits antallet af mulige trækkombinationer iet standard spil, bør bade antallet af træk og antallet af reducerede mulighederper træk ligge sa tæt pa gennemsnittet som muligt.Gennemsnits antallet af træk kan forventes at ligge lige mellem det maksimaleog det minimale antal af træk!

27 + 402

= 33, 5

Og reduceringen af træk per træk kan ogsa forventes at ligge lige mellem detmaksimale og minimale.

14 + 22

= 8

2888

= 36

Med en reducering af 8 per træk bliver der i alt 36 træk. Hvilket er et stykkefra de gennemsnitlige 33,5 træk. Alternativ kan der reduceres med 9 mulighederper træk, hvilket resultere i 32 træk. Estimatet af træk bliver med en reduceringpa 8 følgende:

36! · 836 = 1, 207x1072

1.4 Spillets kompleksitet 19

Estimatet af træk bliver med en reducering pa 9 følgende:

32! · 932 = 9, 035x1065

Et mere præcist estimat vil være at starte med et en høj reducering og sænkeden under vejs sa den ender ved minimum efter omkring en 33-34 træk.

1.4.4 Sammenfatning af spillets kompleksitet

Selvom Taiji’s regler er meget simple og hurtige at sætte sig ind i, sammenlignetmed f.eks. skak, er Taiji meget tæt pa kompleksitets niveauet for skak, f.eks.nar det kommer til antallet af mulige brættilstande, hvor de ikke er langt frahinanden. Taiji kan ogsa meget hurtigt overga skak ved blot at øge dimensionernepa Taiji-brættet. Ifølge de officielle regler er den næste godkendte brætstørrelse11 gange 11, da side længderne ifølge dem skal være ulige. Hvor ubber-boundestimatet for 9 gange 9 la omkring 1038 vil det for 11 gange 11 ligge omkring1057 2 , hvilket er langt over det estimerede 1043 for skak. Skak vil dog via sinemuligheder forMuligheden for at estimere antallet af tilbageværende træk en en vigtigt faktorfor at optimere performance uden tab af kvalitet, da antal tilbageværende trækkan bruges til at estimere hvor meget regnekraft der skal til for at regne etbestemt antal generationer ned i spiltræet. Jo færre antal træk der er tilbage,jo færre mulige træk vil der være tilbage, og jo længere vil det være muligtat regne ned i spiltræet indenfor en rimelig tid. Det gør det samtidig muligtberegne grundigst pa de sidste træk i spillet uden at ødelægge performance, ogde sidste træk er ofte afgørende for at vinde spillet.

2 311·11 reduceret med 80%

20 Taiji

Kapitel 2

Design og brugervenlighed

Da der skal arbejdes meget med programmet gennem forløbet, er det vigtigtat det har en god brugerflade som er hurtig, brugbar og nem at anvende. Dogbehøver ikke nødvendigvis nem at tilegne sig, da det ville blive anvendt rigeligtsa en hurtig og smidig anvendelse for en erfaren bruger er vigtigere, end atbrugerfladen er let at ga i gang med som ny bruger.

2.1 Vurdering af Nestors Interface

Inden jeg designer og udvikler min egen brugerflade vil jeg kigge pa hvordanNestor Romeral Andres har lavet sin og gøre mig nogle erfaringer ud fra den.

2.1.1 At starte et spil:

For at starte et spil abnes menupunktet ”Game”og ”1-Player”vælges.

22 Design og brugervenlighed

Figur 2.1: Nestor’s brugerflade nar ”Game”er aben.

Her bliver brugeren sa mødt med en menu, hvor man kan vælge sin farve og enmodstander, i form af de fire sværhedsgrader for Nestor’s egen AI.

2.1 Vurdering af Nestors Interface 23

Figur 2.2: Opsætningen for starte et nyt spil.

Dette fungerer godt, men jeg ser ingen grund til at undlade at have et spil klar tilstart nar programmet abnes. Et spil mod en sort AI pa et af de lave niveauer vilvære at foretrække, da en sadan ikke vil lave nogen beregningen før spilleren selvlægger den først brik, og fordi de lave niveauer af AI svarer forholdsvis hurtigtefter spilleren har foretaget sit træk. Det kan tænkes at Nestor Romeral Andreshar undladt dette med vilje for at lede brugeren op i Game menuen og dervedgøre brugen opmærksom pa at der ogsa er en ”2-Player-funktion, der spilles overnettet, hvilket kan være mere spændende for brugeren. Hvorfor der dog ikke eren 2-Player funktion, for to spillere ved samme computer kan man dog undresig over. Der er selvfølgelig den mulighed, at det er et ønske fra Nestor Rome-ral Andres’ side om at fa brugeren til at anskaffe sig den fysiske version af spillet.

2.1.2 Placering af brikker:

Nar spillet er i gang, placeres en brik ved at bevæge musen hen over brættetindtil man har den rette placering. Brikken kan hele tiden ses pa brættet og haren hvid markering rundt om sig, der gør det tydeligt at skelne den fra andrebrikker pa brættet. Det kan dog være lidt besværligt at fa placeret brikkenkorrekt. Brikken vendes lodret eller vandret efter om musen lige er passeretgennem en vandret eller lodret væg mellem felterne, hvilket ikke altid virker lige

24 Design og brugervenlighed

naturligt. Skal brikken vendes sa hvid og sort skifter plads, er det nødvendigtat bruge højre musetast, hvilket formentligt kræver et kig i ”Help”og menuen”Controls”for at gennemskue. Nar brikken først er placeret kræver det kun etenkelt klik pa venstre musetast at lægge brikken. Dette kan dog give anledningtil frustration, da der ikke skal meget til at komme til at lægge en brik ved enfejl, og spilles der samtidigt mod højeste niveau AI, kan man sidde og ærgre sigover fejl trækket i et halv til et helt minut før det bliver ens tur igen.

2.1.3 Information pa displayet:

Displayet viser to væsentlige ting, hvilken farve spilleren selv har i form af etfelt i den farve i nederste højre hjørne og sa fortæller en kort tekst om det erspillerens tur eller om AI’en er ved at beregne sit træk og hvor langt den er naetved hjælp af en lille bar ved siden af.Der vises ingen score undervejs i spillet, men nar spillet afsluttes viser et pop-op vindue den endelige stilling og vinderen, derudover vises størrelse pa de tostørste figurer for hver spiller i form af et tal placeret pa selve figurerne.

2.1 Vurdering af Nestors Interface 25

Figur 2.3: Eksempel pa afsluttet spil med score vist pa figurerne.

2.1.4 Det overordnede indtryk:

Nestor Romeral Andres’ brugerflade er pa alle omrader god, nar det gælder omat lærer spillet at kende. Brikkernes form og hvor de kan lægges vises fint, narmusen bevæges hen over brættet. Nar spillet er afsluttet vises scoren pa figurer-ne, sa det er nemt at se og forsta, hvor den endelige resultat kommer fra. Denplacerer ogsa to plus’er pa den brik som AI senest har placeret, hvilket gør detnye træk lettere at finde, hvilket ofte er nødvendigt for de høje sværhedsgrader,da spilleren ofte har mistet interessen inden AI bliver færdig med at beregne sittræk.Fra et lærings synspunkt er Nestor’s interface glimrende, men nar det kommertil effektivitet kunne man ønske sig mere. Mulighederne nar spillet derimod førster startet er stort set ikke eksisterende, du kan foretage dine træk og vente pamodstanderens, og evt. starte et nyt spil, hvis du bliver træt af det. Der er ingen

26 Design og brugervenlighed

muligheder for at fortryde træk eller ga frem og tilbage i spillet. Det ville ogsavære rart at kunne gemme spillet undervejs, nar de netop bliver sa langvarigeved den højeste sværhedsgrad.

2.2 Design af eget Interface

Min egen brugerflade er designet med henblik pa langvarigt brug med test afAI’er som hovedformal, ikke at lære brugeren spillet hurtigst muligt eller atskabe den ultimative spil oplevelse.

2.2.1 At starte et spil:

Et spil kan startes op med indstillinger opsat i programmet blot ved at klikkepa spilbrættet. Enten vil brugeren begynde med at sætte sin brik eller ogsa vilen AI begynde at beregne sit træk.Det er ogsa muligt at ændre pa indstillingerne gennem menuen, men disse valg-muligheder er begrænsede og anvendes hovedsageligt til at vise programmetfrem. I testsammenhæng vil ændringerne af indstillingerne blive foretaget i sel-ve koden. Spillet med disse indstillinger vil sa være tilgængeligt med det sammeprogrammet abnes og det vil ikke være nødvendigt at skulle igennem menuernefor at starte det ønskede spil.For at starte et nyt spil op med samme indstillinger kan dette hurtigt gøres imenuen. Der vælges blot ”New Game”og ”Same settings”

2.2 Design af eget Interface 27

Figur 2.4: Min brugerflade nar ”Game”er aben og ”New Game”markeret.

Vælges ”Change settings”mødes brugeren med denne menu, hvor bruger kanvælge at spille menneske mod et menneske pa samme computer eller mod en afde tre hoved AI’er.

Figur 2.5: Opsætningen for starte et nyt spil med nye indstillinger.

28 Design og brugervenlighed

2.2.2 Placering af brikker:

Placering af brikker udføres ved at klikke pa et frit felt, hvor man ønsker atplacere sin farves halvdel af brikken, og derefter klikker man pa et frit felt vedsiden af for at placere halvdelen med modstanderens farve. Foretages andet kliket sted hvor trækket bliver ugyldigt annulleres det og begge halvdele fjernesautomatisk igen. Et ugyldigt træk kan ogsa bruges til at annullere et træk, somman ikke ønskede at lave, hvis man kun har faet placeret den ene halvdel. Atklikke pa samme felt en gang til er en hurtigt made at annullere et halvt trækpa.Denne made at udføre trækkene pa er yderst hurtigt og nem at anvende, narman først er blev vandt til den. Og det at et enkelt fejlagtigt klik ikke afgør ettræks skæbne er ofte yderst velkomment.

2.2.3 Information pa displayet:

Pa displayet vises flere informationer forholdsvist diskret. Under brættet er deret felt med et tal. Tallet viser hvor mange træk, der er blevet foretaget. Desudenfortæller baggrundsfarven her om det er hvid eller sorts tur, da den har enmørkere nuance ved sort spillers træk end nar der er hvid der star for tur.Pa venstre side af brættet star et hvidt tal. Dette tal viser det nuværende antalpoint for den hvide spiller, mens det sorte tal pa højre side viser antal af pointfor den sorte. Hvid er placeret i venstre side, da vi læser fra venstre mod højreog det er hvid der under de officielle regler starter.

2.2 Design af eget Interface 29

Figur 2.6: Eksempel pa afsluttet spil med score vist pa figurerne.

2.2.4 Andre funktioner:

Der er i bunden af vinduet to knapper, hvor brugeren kan ga frem og tilbagei spillet blandt de træk der er blevet foretaget. Gar brugeren tilbage i spilletog ændrer et træk, fjernes de forrige træk fremad selvfølgelig da disse højstsandsynligt ikke længere er korrekte. Disse knapper giver mulighed for bedre atanalysere spillets gang og kan ogsa benyttes efter det har naet sin ende.

Under menupunktet ”Game”er der ogsa mulighed for at gemme spillet. Deter kun brættet og dets historie der gemmes, altsa den nyeste bræt og alle deforegaende som har ledt op til det. Indstillingerne for hvem, der spiller hvadgemmes ikke. Hentes spillet vil de spillere der var sat til at spille inden spilletblev hentet stadig være gældende. Dette er ikke sa heldigt set fra et normalt spilssynsvinkel, da dette giver brugeren mulighed for at snyde ved f.eks. at bytte ompa farverne for de to spiller. Men fra et testsynspunkt er dette ganske udmær-ket, da der kan undersøges hvordan forskellige AI’er takler den samme situation.

Bemærk ogsa at vinduet er større, det er for at det skal være muligt at an-vende større brætstørrelser, uden at brikkerne bliver alt for sma.

Det skal ogsa nævnes at AI’erne først begynder deres beregning, nar bruge-ren klikker en gang pa brættet efter placeringen af sin egen brik. Dette er lidt

30 Design og brugervenlighed

upraktisk, nar der spilles mellem et menneske og en AI. Nar det er to AI’erder sættes op mod hinanden, bliver det dog nemmere at følge med i spillet, dabrugeren selv kan bestemme, hvor hurtigt spillet skrider frem. Ønskes flere træktaget hurtigst muligt, er det blot at klikke det ønskede antal gange, og sa fort-sætter AI’erne op til dette antal træk. Dette sker selvom beregningen af førstetræk ikke er blevet gjort færdig inden bruger er færdig med sine klik.

Kapitel 3

Kunstig Intelligens

3.1 Programmet

Herunder er en kort oversigt over programmet og dets opbygning.

32 Kunstig Intelligens

Figur 3.1: Oversigtsdiagram for programmet.

3.1.1 TaijiDriver:

TaijiDriver er main-metoden, der konstruerer TaijiFrame og viser den.

3.1.2 TaijiFrame:

TaijiFrame er rammen, som indeholder de dele, der bliver vist pa skærmen. Deter ogsa her dimensionerne for brættet ligger gemt.

3.1.3 TaijiListeners:

TaijiListeners handtere opfangelsen af museklik indenfor vinduet.

3.1 Programmet 33

3.1.4 TaijiMenu

TaijiMenu handterer dropdown menuen for menupunktet ”Game”.

3.1.5 TaijiSettings:

TaijiSettings indeholder menuen for ”Change settings”ved start af nyt spil, hvordet er muligt at ændre opsætning for hvilken AI brugeren spiller mod.

3.1.6 TaijiPanels:

TaijiPanels tegner selve brættet og omraderne omkring, der f.eks. viser dennuværende score.

3.1.7 TaijiModel:

Hvor TaijiFrame star for at styre brugerfladen, at tegne brættet, vise menuerneog handtere brugerens kommunikation med programmet, tager TaijiModel sigaf selve spillet. TaijiModel handterer brættet, hvilke træk, der foretages pa det,og kalder de forskellige kunstige intelligenser.

3.1.8 TaijiHash:

TaijiHash indeholder hashfunktionerne, som de forskellige AI’er har adgang tilgennem TaijiModel.

3.1.9 TaijiPrint:

TaijiPrint inderholder flere forskellige funktioner til effektivt ud skrive forskelligdata, der kan være relevant nar forskellige dele af de kunstige intelligenser testes.

34 Kunstig Intelligens

3.1.10 FigureMap:

FigureMap bruges til at kortlægge de største figurer for begge farver saledes atdet bliver muligt at beregne scoren for hver spiller. Andre funktioner, der brugestil at konvertere almindelige taijibræt til figurbræt, som fortæller hvilke felter,der hænger sammen, findes ogsa her.

3.1.11 Board:

Board indeholder selve brættet og spilhistorien op til det nyeste træk og deru-dover funktioner, der har at gøre med handtering af brættet.

3.1.12 Node:

Node indeholder datastrukturen for Nodes, som anvendes i alle AI’erne.

3.1.13 Tree:

Tree indeholder datastrukturen for et spiltræ. Denne benyttes dog kun i denførst prototype AI, AITaijiMinimax.

3.1.14 AITaijiMinimax:

AITaijiMinimax er prototypen lavet for at komme i gang med at lave kunstigintelligens til Taiji, effektivitets niveauet for denne AI er langt under de senereAI’er. Den benytter sig som den eneste af en bredde-først minimax søgning.

3.1.15 AITaijiALphaBeta:

En kunstig intelligense, der anvender minimax algorithmen med alpha beta pru-ning til at søge ned i spilgrafen for at finde et træk.

3.2 Generelle datastrukturer og metoder 35

3.1.16 AITaijiPureAlphaBeta:

Fungere som AITaijiAlphaBeta uden at tage højde for rotationer og spejlinger.Denne AI er lavet til test formal, hvor dens resultat kan holdes op imod resultaterfor AlphaBeta AI’en.

3.1.17 AITaijiMinimax2:

Fungere som end dybde først minimax søgning, ved at deaktivere alpha betapruningen i AlphaBeta AI’en. Denne AI anvendes ligeledes til test formal, hvorden holdes op mod resultaterne fra AlphaBeta AI’en.

Da AITaijiPureAlphaBeta og AITaijiMinimax2 begge blot er versioner af AI-TaijiAlpha, med henholdvis alpha beta pruning og handteringen af rotationerneog spejlinger deaktiveret. Er disse to ikke taget med i kildekoden.

3.1.18 AITaijiLocalArea

Denne kunstige intelligens benytter sig af samme metoder som AlphaBeta AI’en,men begrænser sig selv til et lille søgeomrade omkring det seneste træk.

3.1.19 AITaijiGrowth

Growth AI’en benytter sig af en dybde-først minimax søgning. Men i stedet forat lade alle de mulige træk prøves af, lader den træk mulighederne vokser udfra de største figurer pa brættet.

3.2 Generelle datastrukturer og metoder

I dette afsnit beskrives nogle af de vigtigste datastrukturer og metoder, som garigen gennem mange af de kunstige intelligenser.

36 Kunstig Intelligens

3.2.1 Nodes:

Noderne bruges til at holde styr pa informationerne om hvert enkelt spilstadie.I en node gemmes spilbrættet med alle brikkerne. Der gemmes ingen informa-tion om grænserne for de enkelte brikker, der gemmes blot hvor der er sorte,hvide og frie felter. Det betyder at der ikke er nogen bestemt struktur gemt ibrættet om hvordan, spillet naede dette punkt. Denne anonymitet er en fordel,da det er mere end en rute til hver eneste brætsituation i spillet, og brættetsfortid derfor ikke ma være bundet til en bestemt forgænger. I noden kaldes detto-dimensionelle array hvor brættilstanden gemmes for nodeBoard.Pa trods af brættets pakrævede anonymitet er koordinatorerne til det træk, derskabte Noden, gemt i fire variabler. wc, wr, bc, br, kolonnen for det hvide felt,rækken for det hvide felt, kolonnen for det sorte felt og rækken for det sorte feltfor brikken, der blev lagt for at komme til dette stadie. Disse koordinatorer eret levn fra de første versioner, hvor der ikke blev taget højde for at flere for-gænger kunne lede til samme spilsituation. I de nyere versionerne bliver de dogstadig brugt til at gemme det træk, som den kunstige intelligens finder frem tilskal foretages. I Noden er der ogsa en variabel tilegnet at gemme værdien somheuristikken finder nar Noden evalueres. Denne variabel hedder a.Dybden gemmes ogsa i Noden, under navnet d. Dybden er ligesom scoren uaf-hængig af hvilken rute, der er blevet taget for at na Noden, da der skal væreblevet lagt lige mange brikker før to brætsituationer kan være ens.Til slut holder to arraylister af variable længde styr pa hvilke forgængere ogefterkommere Noden har. Den kaldes par for parents og den anden kaldes blotchildren.

3.2.2 Skabelsen af efterkommere:

Det vil i langt de fleste af de kunstige intelligenser før eller siden være nødvendigtat skabe alle efterkommere til en given node. Da denne proces i disse tilfælde erden samme, vil den blive beskrevet her. I de tilfælde hvor skabelsen af efterkom-mer foregar pa anden vis vil det være beskrevet i afsnittet om den pagældendeAI.For at skabe alle efterkommerne til en Node, er det nødvendigt at foretage allede træk som den pagældende spilleplade tillader. Dette gøres ved at gennemgabrættet fra enden til anden og lægge brikker alle de steder det er muligt. Detnemmeste er først at gennemga brættet med vandrette brikker og hver gang derfindes en vandret plads til en brik oprettes to Noder, en for hver led brikkenkan vender pa, sort-hvid og hvid-sort. Der samme gøres derefter for alle mulig-hederne for at lægge en brik lodret. Checkes der for bade lodrette og vandrettesamtidigt opstar der en masse specialtilfælde omkring to af kanterne af brættet,

3.3 Heuristik 37

og der ma checkes separat for lodrette pladser langs højre side og det sammegælder de vandrette pladser langs bunden.

3.3 Heuristik

En heuristik bruges til at vurdere spillets tilstand. Heuristikken skal altsa kunnelevere en værdi, som giver et indblik i hvor godt eller skidt det star til for de tospiller. I Taiji vil det være naturligt at anvende differencen mellem de to spilleresscore, som heuristik.I tilfælde, hvor det er muligt at undersøge alle trækkombinationer til ende, erdenne heuristik perfekt.

3.3.1 Mulige forbedringer af heuristikken:

Er det ikke muligt at beregne en fuldstændig løsningen, vil en heuristik, dertager højde for mere end blot den nuværende score, være mere anvendelig. Dennuværende score vil ikke nødvendigvis sige meget om hvad fremtiden vil bringe.F.eks er en fugl i handen bedre en ti pa taget. Et endeligt spilstadie med etpoints forspring inden for den mulige søgedybde, vil selvfølgelig være bedre enden et stadie, hvor spilleren er foran med flere points, men hvor søgedybden ernaet og spilleren derfor ikke ved hvad trækkene efter vil bringe. (Søgedybden erhvor mange generationer man har besluttet at ga ned i spiltræet). Er heuristik-ken kun baseret pa scoren vil de 10 fugle pa taget blive opfattet som den bedstemuglighed. Dette løsses ved at vinderstadier far tildelt værdien uendelig, uansethvor stor eller lille forskellen i scoren sa er. Dette kan selvfølgelig resultere i atAI’en vælger en løsning, hvor den vinder med en mindre point forskel end hvadder var mulighed for. Dette har dog først en betydning, hvis point forskellenlægges til en samlet score som strækker sig over flere spil. Er dette tilfældet kanheuristikken modificeres til at sætte værdien for vinderstadier til uendeligt plusdifferencen i scoren mellem de to spiller, sa det bedste af vinderstadierne inden-for søgedybden kan vælges. Dette kan selvfølgelig kun gøres fordi ”uendeligt”ipraksis blot er en værdi som er højere end noget der kan opnas i selve spillet.Det er ogsa muligt at forbedre heuristikken i tilfælde hvor et endeligt stadie ikkenas indenfor søgedybden. Den ene spiller kan f.eks. have en højere score, menvære blevet lukket af for at udvide sine to største figurer yderligere, mens denanden kan være lidt bagud pa point, men have gode muligheder for at udvidesine største figurer og dermed komme foran. I dette tilfælde kan heuristikkenudvides til ogsa at tage højde for hvor mange muligheder, der umiddelbart er for

38 Kunstig Intelligens

at udvide de større figurer i spillet. Det store spørgsmal er her hvordan vægt-ningen skal ligge mellem scoren og mulighederne for udvidelse. Her kunne detvære en mulighed at anvende et neuraltnetværk eller simuleret nedkøling til atfinpudse vægtningen basseret pa resultater og erfaringer gennem mange spil.

Det største problem med en heuristik, der kun tager højde for selve scoren,opstar nar den kunstige intelligens ikke har mulighed for at søge hele træetigennem, og der er blevet lavet to store figurer for begge spillere, som det ik-ke længere er muligt at udvide pa. Da det er de to største figurer der tællerpa scoren, er alle andre figurer ligegyldige indtil en indhenter den næststørstefigur. Dette betyder at den kunstige intelligens famler i blinde indtil en figursom minimum overgar den næststørste figurs størrelse. Har begge spiller f.eks.to figurer pa 8 point, som ikke længere kan udvides, og ellers kun figurer medstørrelsen 2 eller mindre, vil det være nødvendigt at bringe en af disse figurerop pa størrelsen 9 før det overhovedet kan ses pa heuristikken. Dette ville i defleste tilfælde kræve flere træk end den kunstige intelligens kan regne frem paet større bræt. Dette vil simpelthen resultere i at alle træk vil fa tildelt sammeværdi og derfor vil den kunstige intelligens vælge et fuldstændigt tilfældigt træk.Løsningen er selvfølgelig at ændre heuristikken sa den ikke kun ser pa de størstefigurer. Som nævnt tidligere kunne heuristikken ogsa se pa antallet af muligeudvidelser pa de største figurer. Men i stedet for at se pa muligheder omkring deto største figurer, sa sættes op til at se pa mulighederne omkring de to størstefigurer der endnu har muligheder for udvidelse. Den endelige udfordring landerigen pa vægtningen. Hvornar gar den mindre figur med gode muligheder forudvidelse hen og bliver mere fordelagtigt at spille pa end den store figur som erbegyndt at løbe tør for udvidelses muligheder.

3.3.2 Konklusion pa heuristik:

I den nuværende løsning anvendes den simple heuristikken, der kun ser pa selvespillets score til de forskellige AI’er. Men som det er blevet beskrevet er der enlang række steder hvor denne heuristik ikke er optimal. Dette gælder nar detikke er en praktisk mulighed at afdække hele spiltræet, hvilket er tilfældet vedet hvert spilbræt, der er støre end 4x4. Det forventes derfor at en forbedring afheuristikken, vil give en yderst mærkbar forbedring pa AI’ernes præstation.

Kapitel 4

Minimax

Minimax1 er en velkendt algoritme, der ofte anvendes til brætspil. Minimaxtager udgangspunkt i at begge spiller altid vil forsøge at maksimere sit egetudbytte og minimere modstanderens.Minimax fungerer ved at generere et træ med alle mulige træk gennem helespillet. De afsluttende spilstadier (bladene pa træet) bliver sa givet en heuri-stisk værdi, som fortæller om dette stadie er vundet, tabt eller uafgjort. I Taijistilfælde ogsa hvor meget, der er blevet vundet eller tabt med, da det er muligtat vinde med forskellige antal points. Disse værdier bliver ført videre op gen-nem træet. Dette sker ved at generationerne af forældre skiftevis patager sigden højeste af børnenes værdier eller den laveste, alt efter hvilken spiller gene-rationen repræsenterer. Her igennem opnas det at spillerne altid vil vælg dettræk med det minimale maksimum for sin modstander og derved det maksimaleminimum for sig selv. Deraf navnet Minimax. Med andre ord vælger spillerenden vej hvor modstanderens bedst mulige udbytte er det ringeste.

Da hele træet søges igennem under alle omstændigheder, er det bade muligt atlave en Minimax algoritme, hvor der anvendes en dybde-først fremgangsmade,og en hvor der anvendes en bredde-først fremgangsmade.Fordelen ved en bredde-først søgning, er at den er mere overskuelige at havemed at gøre. Derimod er mulighederne for videreudvikling bedre for dybde-

1Minimax-algoritmen star beskrevet i kapitel 6, afsnit 2 i ”Articial Intelligence - A ModernApproach”.

40 Minimax

først søgningen, da denne er nødvendig for at kunne lave Alpha-Beta pruning(se afsnit om dette). I brede-først søgningen evalueres størstedelen af slutstadi-erne først nar søgningen samlet har naet bunden af træstrukturen, og sa er detfor sent at begynde at skære grene af som ikke behøves søges igennem.

4.1 Beskrivelse af Minimax med brede-først søgning

Da bredde-først versionen af Minimax er blev skrevet som en øvelse og ikkeskulle anvendes til videreudvikling, er den kun blevet skrevet til at kunne spillesort.Bredde-først versionen fungere ved først at skabe hele træet, ved at sætte detnuværende spilstadie som roden og sa lade hver generation vokse ud fra denforrige. Undervejs bliver der holdt styr pa generationerne, ved at hver Node iden nye generation gemmes i et af to arrays. Et array for ulige generationer og etfor lige. Det lige array tømmes, nar en nye lige generation pabegyndes og tilsva-rende tømmes det ulige nar en nye ulige generation startes. Det gøres, fordi deter nødvendigt at holde styr pa medlemmerne af de to nyeste generationer naralting foregar per generation, i stedet for at fokusere pa en enkelt Node og densefterkommer eller forgænger. De endelige stadier, ogsa kaldet bladene, gemmesogsa i et array, da bladene ikke kun vil være at finde i den sidste generation.Nar træet er skabt pabegyndes beregning af værdierne op gennem træet.Beregningen startes i den endelige generation. Alle Noderne af denne generationevalueres og far tildelt en værdi. Nodernes forgænger tilføjes til det ulige ellerdet lige array afhængigt af generationen. For næste generation patager nodernessig alle den højeste værdi af sine børn, nar generationen er lige. Hvis genera-tionen er ulige patager noderne sig den laveste værdi af sine børn. Herudoverevalueres alle bladene af denne generation som befinder sig i arrayet for blade-ne, og tilføjes til det ulige eller det lige array efter generation. Alle forgængernetilføjes igen til enten det ulige eller det lige array, efter at arrayet er blevet tømtfor den gamle generation. Saledes fortsættes der indtil værdierne nar roden ogdet bedste træk kan vælges.

4.1.1 Pseudo-kode for Minimax med brede-først søgning:

Funktion : Minimax ( s t a d i e ) , r e t u r n e r e r et trækInput : s tad i e , s p i l l e t s nuværende s t a d i e .

rod = s t a d i eBeregnTræ (SkabTræ( rod ) )

4.2 Beskrivelse af Minimax med dybde-først søgning 41

RETURN rodens barn med den mindste værdi

4.2 Beskrivelse af Minimax med dybde-først søgning

I dybde-først søgningen, søger den først en gren til bunds og nar den nar bun-den, gar den blot et skridt tilbage for at tage et nyt skridt fremad.

4.2.1 Pseudo-kode for Minimax med dybde-først søgning:

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ækInput : 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 .

s tad i e , s p i l l e t s nuværende s t a d i e .

IF s p i l l e r = hvid THEN v = Max( s t a d i e )ELSE v = Min( s t a d i e )RETURN Trækket med værdien v

Funktion : Max(S ) , r e t u r n e r e en værdi f o r s t a d i e tInput : S , det a k t u e l l e s t a d i e i s p i l l e t .

IF S er et e n d e l i g t s t a d i eTHEN v = e va l ue r i n g a f S RETURN v

v = − i n fFOR a l l e efterkommere a f S ( s )

m = Min( s )IF v < m THEN v = m

RETURN v

Funktion : Min(S ) , r e t u r n e r e en værdi f o r s t a d i e tInput : S , det a k t u e l l e s t a d i e i s p i l l e t .

IF S er et e n d e l i g t s t a d i eTHEN v = e va l ue r i n g a f S RETURN v

v = i n fFOR a l l e efterkommere a f S ( s )

m = Max( s )IF v > m THEN v = m

RETURN v

42 Minimax

4.3 Spilgraf for 3x3 Taiji spil:

Forskellen mellem et spiltræ og en spilgraf, er at det i spilgrafen er muligt atflere foregaende stadier kan ende i samme stadie.Herunder ses spilgrafen for Taiji pa en 3 gange 3 spilplade. Alle rotationer ogspejlinger af et spilbræt, anses for at være et spilstadie. Var dette ikke tilfældetskulle grafen være betydeligt større, f.eks. ville der i stedet for 4 mulige starttrækvære 18.

4.3 Spilgraf for 3x3 Taiji spil: 43

Figur 4.1: Spilgrafen for Taiji pa et 3x3 bræt.

44 Minimax

Herunder ses spilgrafen efter de endelige spilstadier har faet tildelt deres vær-dier. Spilgrafen er blevet vendt om for at illustrere hvordan værdierne førstbliver tildelt de endelige stadier og derefter bliver givet videre op gennem træet.(Positiv score er til hvids fordel, negativ er til sorts.)

4.3 Spilgraf for 3x3 Taiji spil: 45

Figur 4.2: Spilgrafen for Taiji pa et 3x3 bræt med score pa slutstadierne. Positiveværdier er til hvids fordel, negative er til sorts.

46 Minimax

Herunder ses spilgrafen nar værdierne er blevet sendt op gennem træet efterminimax-princippet. Dette er grafen som den vil se ud, hvis det er den hvidespiller der har det første træk, ergo er det blevet kørt Max() pa roden.

4.3 Spilgraf for 3x3 Taiji spil: 47

Figur 4.3: Spilgrafen for Taiji pa et 3x3 efter Minimax genkørsel med Max somstarter.

48 Minimax

Som det kan ses ender spilgrafen i et nul ved roden. Dette betyder at der ikkeer nogen vinderstrategi, som kan lede til en sikker sejr. Dette betyder dog ogsa,at det er muligt at fa et uafgjort resultat uanset hvad modstanderen gør. Salænge begge parter spiller optimalt vil spillet ende uafgjort. Der vil først væreen sejrherre, nar den ene part begar en fejl som vil lede til modstanderens sejr.Det kan ogsa ses at det første træk ingen betydning har for resultatet, da alleanden generations spilstadierne har værdien nul. Spilles der mod en modstan-der der begar fejl er nogle af disse træk dog bedre end andre. Dette kan f.eks.bedømmes pa hvor stor en andel af de efterfølgende stadier der føre til en sejr.Jo større andel af træk, der føre til en sejr, jo større sandsynlighed for at en for-hastet modstander vil komme til at vælge et af disse. Placeres den sorte halvdelaf brikken i et hjørne, er der 6 efter følgende stadier der leder til en sejr ud afde i alt 15 forskellige muligheder.Herunder er en tabel over de fire mulige starttræk og hvor mange af modstan-derens træk, der efterfølgende vil lede til sejr for den første spiller:

Placering Træk, der leder til sejr Samlet antal træk ProcentdelSort i hjørnet 6 15 40%Hvid i hjørnet 3 15 20%Sort i midten 0 6 0%Hvid i midten 3 6 50%

Tages der ikke højde for spejlinger og rotationer ser tabellen saledes ud:

Placering Træk, der leder til sejr Samlet antal træk ProcentdelSort i hjørnet 7 16 43,75%Hvid i hjørnet 3 16 18,75%Sort i midten 0 12 0,00%Hvid i midten 6 12 50,00%

Ud fra dette kan det ses, at sandsynligheden for at modstanderen laver en fejl,der leder den første spiller til sejr, er størst ved at placere spillerens egen halvdelaf brikken i midten. Det kan ogsa forventes, at jo større antallet af mulige træker, jo større er sandsynligheden for at der laves en fejl. Er dette sandt, kan detvære bedre at placere den sorte halvdel af brikken i et hjørne, da dette øgerantallet af mulige træk pa bekostning af en relativt lille nedgang i procentdelenaf træk der vil lede til sejr.Det kan ogsa ses, at det at placere den sorte halvdel af brikken i midten ude-lukker muligheden for sejr, medmindre modstanderen laver fejl længere inde ispillet, hvor det vil være nemmere at overskue konsekvenserne af et træk ogderved er mindre sandsynligt at der laves en fejl. Det er maske endda tilfæl-det at sejren slet ikke er mulig efter dette træk. For at undersøge dette er herspilgrafen for trækket med sort i midten:

4.3 Spilgraf for 3x3 Taiji spil: 49

Figur 4.4: Spilgrafen for Taiji pa et 3x3 med fokus pa første træk med sort imidten.

50 Minimax

Det kan ses at alle de endelige stadier, som kan opnas fra dette træk, entenender i uafgjort eller i en sejr til sort.Gennemgas alle endelige stadier kan det ogsa ses, at intet stadie med sort imidten gar til den hvide spiller. Dette gælder selvfølgelige ogsa den anden vejrundt, intet stadie med hvid i midten gar til den sorte spillers sejr.Her af kan det konkluderes at den spiller, der først placeres sin farve i midten,vil være sikret minimum et uafgjort resultat.Desuden kan det ses at et hvert slutstadie med et frit felt i midten ender uafgjort.Med andre ord er midten nødvendig for at vinde spillet, nar brættet er pa 3 gange3 felter.

Kapitel 5

Optimering af Minimax

5.1 Spilgraf

En kraftig reducering kan opnas ved at skifte fra et spiltræ til en spilgraf. For-skellen mellem et spil træ og en spilgraf er, at hvor et spiltræs grene aldrig vil gasammen igen, er dette en mulighed for en spilgraf. I praksis er dette mulighedenfor at samme brættilstand kan nas ad mere end en vej.

52 Optimering af Minimax

Figur 5.1: Eksempel pa et lille spiltræ.

Figur 5.2: Eksempel pa en lille spilgraf for samme brættilstande.

5.2 Rotationer og spejlinger 53

5.2 Rotationer og spejlinger

At undga rotationer og spejlinger er en af de mest besparende faktorer i Taiji,især ved det helt første træk. Rotationer og spejlinger gar i sin enkelthed udpa at to brættilstande anses for at være samme tilstand, hvis den ene er enrotation eller spejling af den anden. Hvis to brættilstande er ens, behøves deefterfølgende beregninger kun laves en gang. Jo flere brættilstande, der kan sigesat være de samme, jo færre beregninger skal der til.

Figur 5.3: Eksempel pa tre 4x4 brættilstande, der kan betragtes som værendeens.

I praksis kommer reduceringen kraftigst til syne ved første træk, da de ef-terfølgende reducering bliver færre, fordi den første brik der sættes kommertil at danne et anker for efterfølgende rotationer og spejlinger. Herunder sesantal af brættilstande før reduceringen og efter reducering pga. rotationer ogspejlinger:

54 Optimering af Minimax

Figur 5.4: Alle trækmuligheder for et standardbræt. Hver streg repræsentereen brik og de to mader, som brikken kan vende pa.

Figur 5.5: Alle træk muligheder for først træk pa et standardbræt efter redu-cering pga. rotationer og spejlinger.

Første forgrening i spilgrafen reduceres her til omkring en 1/8. Langt de flestereduceringer sker i form af denne reducering og alle de brættilstande der aldrigkommer til at eksistere fordi deres forgænger blev fjernet her. Der opstar dogyderligere reduktioner ned gennem spilgrafen efter den store reducering, nar derundervejs dannes ny symmetri.

5.3 Hash funktioner 55

Figur 5.6: Eksempel pa reducering af brættilstande pga. rotationer og spejlingerlængere nede i spilgrafen.

Som tommelfingerregel er reduceringen pa en faktor 8, fire rotationer af brættetog fire rotationer af det spejlvendte bræt. Dette gælder dog kun kvadratiskebrætstørrelser, for rektangulære brætstørrelser er det ikke muligt at lave 90graders rotationer og reduceringen bliver derfor halveret til en faktor 4.

5.3 Hash funktioner

Efter at have sparet store dele af spiltræet væk ved at lade det være en graf istedet, hvor hvor flere vej kan lede til samme stadie, er det blevet nødvendigtved hvert enkelt spilstadie at checke om dette spilstadie allerede eksisterer. Forat gøre dette ma spilstadiet sammenlignes med alle andre spilstadier, der indtilvidere er blevet dannet i aktuelle spil, inden stadiet bliver oprettet i systemet

56 Optimering af Minimax

som et unikt stadie, eller om det blot skal bruges til at tilføje ny information tilet allerede eksisterende stadie.Denne søgning efter ens stadier kan, hvis den bare udføres blindt, potentielt øgetidsfaktoren sa meget at det ikke kan betale sig at ga fra spiltræ til spilgraf.Søgningen skal udføres for hvert stadie i spillet, og da der er tusinder af stadier,skal der for tusindvis af stadier søges igennem netop tusindvis af stadier. Dettevil selvfølgelig være et større problem i slutningen af et spil end i starten, hvorder endnu ikke er sa mange stadier at søge igennem. Desuden kan et matchendestadie findes tidligt i søgning, som sa kan afsluttes der. I gennemsnit kan det for-ventes at et stadie findes halvvejs inde i søgningen, men dette gælder selvfølgeligkun i tilfælde hvor der er et matchende stadie. Er der ikke et matchende stadie,vil det være nødvendigt at søge alle stadierne igennem for at konstatere at derikke er et.Dette vil give darlig svartid, hvis der søges blindt fra enden til anden. Mensøgningen kan optimeres ved at begrænse den til et mindre omrade hvori detkan afgøres at stadiet enten eksisterer eller ikke eksisterer.Det er her hashtabeller kommer ind i billedet. Hashtabeller1 bruges til at gøresøgninger hurtigere, ikke kun i spiltræer men i alle former data. Det gøres ved atopdele data i grupper, saledes at det kun er nødvendigt at søge en enkelt gruppeigennem for at konstatere om dataene eksistere eller ej. For at bestemme hvori hashtabellen et stykke data skal placeres, er det nødvendigt at en hashfunk-tion beregner en hashværdi for det stykke data der skal gemmes. Hashværdienfungerer lidt ligesom et postnummer og bestemmer hvor i hashtabellen dataeneskal gemmes, og derved ogsa hvor de kan findes og findes hurtigt igen. For atdette skal fungere, er det nødvendigt at hashværdierne overholder nogle regler.Flere stykker data ma godt fa tildelt samme hashværdi, dette betyder blot at dehavner i samme gruppe. Derimod ma to ens stykker data ikke kunne fa forskel-lige hashværdier, da system sa ikke længere vil være palideligt. Det vil fejlagtigtgive svaret at der ikke findes flere forekomster af et givne stykker data, selvomdette ikke er korrekt.

Da der for hvert træk lægges en brik, og da der pa intet tidspunkt hverkenfjernes eller flyttes brikker, vil to ens stadie kun kunne opsta i samme genera-tion, da to ens stadier altid vil have samme antal brikker. Af denne grund kandybden pa træet anvendes som en hash værdi.Ulempen ved at bruge dybden er at de forskellige generationer meget hurtigtkan komme til at indeholde rigtigt mange spilstadier. Især de midterste genera-tioner i spillet, hvor der er mange stadier i den tidligere generation at kommefra, og der stadig er mange fri muligheder for placering af nye brikker.Der er dog flere fordele ved at benytte dybden som en hashværdi. Den er nemat komme til, det er blot at holde styr pa turen eller tælle antallet af brikker,

1Der kan findes mere information om hash-tabeller og -funktioner i ”Introduction to Algo-rithms”, kapitel 11.

5.3 Hash funktioner 57

hvilket igen blot kan gøres ved at tælle antallet af enten sort eller hvide felter.I denne implementering er dybden endda gemt i hver eneste Node, sa den erhurtigere og lettere tilgængelige end som sa, da en hashfunktion faktisk slet ikkeer nødvendig. Udover tilgængeligheden vil fordelingen af spilstadierne ogsa væreganske udmærket. Pa trods af at der vil værre færre stadier gemt i de først gene-rationer, vil spilstadierne være godt fordelt ud over de forskellige generationerne.

Scoren er ogsa en mulig hash værdi, da scoren selvfølgelig altid ville være densamme for ens stadier. Differencen i scoren vil dog i et spil mellem jævnbyrdigemodstander ofte ligge tæt omkring værdien 0, hvilket vil betyde at store dele afstadierne vil havne i samme grupper. Derfor vil de oftest forekommende tilfældekræve de største søgninger. Dette er selvfølgelig ikke hensigtsmæssigt. Ved atanvende de to score i stedet for blot difference mellem dem, kan der skabes merevariation i hashværdierne. Dette kan f.eks. gøres ved at anvende hashfunktionen:

hashværdi = hvids score + (sorts score · (max score + 1))

Med denne hashfunktion vil kun de spilstadier, der har præcis samme score perspiller, fa samme hashværdi. For mange spilstadier vil scorerne ligge omkringde samme værdier, men slet ikke i sa høj grad, som nar kun differencen anvendes.

Selve hashtabellen er blevet lavet som et to-dimensionelt array. Spilstadiernebliver inddelt i denne tabel efter to hashværdier som bestemmer i henholdsvishvilken række og hvilken kolonne det enkelt spilstadie placeres. Den ene af disseværdier er dybden. Omkostningerne i form af regnekraft for at fremskaffe dener stort set ikke eksisterende, samtidigt med at den gør et glimmerende stykkearbejde, nar det kommer til at fordele stadierne ud nogenlunde ligeligt. Denanden værdi bliver overladt til en mere traditionel hashfunktion.

I første omgang fik hashfunktionen baseret pa scoren opgaven at fordele stadier-ne, og blev nanvgivet hashFunction. Kombinationen af hashFunction og dybdenfungere rimeligt godt pa sma brætter, hvor det er muligt at regne hele spiltræetigennem. Denne kombinationen har dog, uanset hvilken størrelse et bræt har,den ulempe at generationen og scoren ofte følges ad, jo længere inde i spillet,jo højere score. Men de største problemer opstar pa store brætter, hvor detkun er muligt at søge fa generationer frem. For de første par træk i spillet vilscoren altid være den samme. For første træk vil der blive lagt en brik, hvilketaltid vil give et point til sort og et point til hvid, og da det er er de to størstefigurer der tæller, vil andet træk resultere i scoren to-to uanset hvordan denanden brik placeres. Først ved spillets tredje træk fremkommer nogen form forvariation nemlig stillingerne to-to, to-tre, tre-to og tre-tre. Resultatet er altsaat hashFunction lige sa vel kunne have være undladt for de først to træk og kunopdeler spilstadierne i yderligere fire grupper for det tredje.

58 Optimering af Minimax

Det er derfor hensigtsmæssigt at finde en nye hashfunktion til at erstatte hash-Function. Dette alternativ kun baseres pa brikkernes placering pa bræt, da denenkelte briks placering er sa godt som uafhængig af dybden. Problemet er bareat en hashfunktion skal give samme hashværdi uanset om spilstadiets bræt erblevet spejlvendt, roteret eller en kombination af disse for at fungere. For atkomme uden om dette problem, kan et bræt med værdi bruges til finde en hash-værdi. Et sadant værdibræt skal have samme dimensioner som selve spilbrættetog skal forblive det samme uanset hvordan det vendes og drejes. Hvert felt skalhave en værdi, som sa kan tages i anvendelse, hvis en brik lægges oven pa det,og derved fa indflydelse pa den endelige hashværdi.I dette tilfælde er værdibrættet konstrueret saledes; det midterste felt har vær-dien 1, der kan være tale om flere felter, hvis antallet af kolonner eller rækker aflige generationer. Værdierne for fletterne lodret og vandret ud fra midten stigermed 1 hver gang de kommer et felt længere fra midten. Disse felter kan sessom to akser. De resterende felter far deres værdi ud fra disse. Er et felt ud forværdien 2 pa den lodret akse og ud for værdien 3 pa den vandret, bliver feltettildelt værdien 6 (2 x 3).Et eksempel pa dette kan se saledes ud:

12 9 6 3 3 6 9 128 6 4 2 2 4 6 84 3 2 1 1 2 3 48 6 4 2 2 4 6 812 9 6 3 3 6 9 12

Den oprindelige ide var at lægge alle værdierne sammen for alle de felter hvorder la en hvid halvdel, og trække summen fra af værdierne for alle de felter hvorder la en sort halvdel. Det kan dog hurtigt observeres at dette ikke er en optimalfremgangsmade, da en vandret brik vil tilføje den samme værdi sa længe denbevæger sig langs en række indtil den nar midten. Det samme gælder en lodretbriks bevægelse i en kolonne.

Eksembel for midterste række: 2 - 1 = 1, 3 - 2 = 1, 4 - 3 = 1.

Dette kan løses ved i stedet for at fratrække de sorte værdier, halveret vær-dien og sa lægge den til, for fortsat at bibeholde en vigtig afvigelse mellem deto farver. Til sidst benyttes modulus til at reducere resultatet til en passendestørrelse. Denne hashfunktion er navngivet hashFunction2.

Til slut forsøges med en tredje funktion som kombinerer hashFunction og has-hFunction2. Denne funktion lægger blot hashværdierne fra de to funktionernesamme og anvender igen modulus til at holde værdien inde for rammerne. Denfunktion har faet navnet hashFunction3.

5.3 Hash funktioner 59

5.3.1 Test af hashfunktioner

Køretiderne er efter at den menneskelige spiller har foretaget første træk, danogle af de kunstige intelligenser sætter en brik i midten uden at tænke sig om,hvis de har første træk, og derfor ikke kan bruges til sammenligning. Gældendetræk er altsa andet træk i spillet, dette er blevet taget ti gange for hver størrelseaf hver af kunstig intelligens og gennemsnittet af disse ti er hvad der ses i tabel-len her under:

4x4 Kun dybde hashFunction hashFunction2 hashFunction3AlphaBeta 5,040 1,127 1,555 1,178LocalArea 2,997 1,398 1,333 1,348

Growth 0,183 0,144 0,092 0,096

For et spillebræt pa fire gange fire ses det at de kunstige intelligenser kørerbetydeligt hurtigere nar de tre hash funktioner anvendes sammen med dybdenend nar dybden anvendes alene. Der er ikke blevet lavet forsøg uden dybden somhash værdi, da denne er dybere integreret i koden og derfor ikke lige sa nemat fjerne i test henseende som de andre hashfunktioner. Overraskende er dethashFunction, som kun er baseret pa scoren, der klare sig bedst for AlphaBetapa et fire gange fire bræt. Det kunne forventes at dette skyldes beregningsti-den for værdigrafs metoden i hashFunction2 var større end den score baseredemetode i hashFunction, men var dette tilfældet ville hashFunction3’s resultatvære darligere en bade hashFunction og hashFunction2, da denne anvender beg-ge metoder, hvilket ikke er tilfældet. HashFunction3 klarer sig stort set lige sagodt som hashFunction, hvilket ma betyde at problemet ligger i hashFunction2.HashFunction2 anvender som sagt værdigrafs metoden alene og heri opstar pro-blemet, da der ikke er meget variation i værdierne i en værdigraf af den størrelse:

4 2 2 42 1 1 22 1 1 24 2 2 4

Mange spilstadier vil derfor fa samme hash-værdi og der vil saledes være flerestadier, der skal søges igennem per søgning.

9x9 Kun dybde hashFunction hashFunction2 hashFunction3AlphaBeta 62,56 41,34 4,22 3,95LocalArea 2,997 1,398 1,333 1,348

Growth 20,12 1,82 1,34 0,82

Den oprindelige frygt for at en hashfunktion baseret pa score ville give megetlille variation i starten af spillet, viser sig her begrundet. HashFunction klarersig næsten lige sa darligt som dybden anvendt alene. Mens hashFunction2 og 3

60 Optimering af Minimax

klarer sig hele ti gange bedre end hashFunction. Der er unægtelig forskel pa omden menneskelige spiller skal vente fire sekunder pa at modstanderen foretagersit ryk eller om det tager næsten et helt minut.

LocalArea og Growth vil der blive set nærmere pa senere, men generelt er re-sultatet det samme for disse to.

5.3.2 Konklusion pa hashfunktioner:

Testen viser som forventet at hashFunction2 giver en betydeligt hurtigere be-regning end ved brug af den oprindelige hashFunction, nar det kommer til denalmindelige minimax algoritme med aplha beta pruning pa en stor plade, hvordet ikke er muligt at søg ret langt ned i spiltræet. Testen viser ogsa at selvomden kombinere hashfunktion hashFunction3 ikke altid er hurtigst, kommer denaltid nær den bedste tid, da den kombinere de to tidligere versioners styrker. Detkan ogsa ses at denne kombination ikke har de store tidsomkostninger, selvomden laver bade beregningen fra hashFunction og fra hashFunction2.Dette peger ogsa imod at selve beregningerne for hash-værdier ikke er den tun-ge del af svartiden. F.eks. er der en meget lille forskel i beregningstiden mellemhashFunction og hashFunction3 for AlphaBeta AI’en pa en fire gange fire plade,hvor hashFunction2 klare sig mindre godt og derfor ikke burde spille ind pa has-hFunction3s resultat i forhold til hashFunction. Men der opstar altsa ikke denstor forskel mellem hashFunction og hashFunction3, selvom hashFunction3 laverto beregninger, hvor hashFunction laver en. Den lille forskel i beregningstidenmellem hashFunction og hashFunction3, kan dog ogsa skyldes at hashværdienfor hashFunction3 er det bedre og derfor giver hurtigere søgetider, og at dettederfor opvejer den ekstra regnetid per hashværdi.Alt i alt vil hashFunction3 være det bedste generelle valg. Den klare sig altidbedst eller næstbedst i testene, og i de tilfælde hvor den kun er næstbedst liggerden meget tæt op ad den bedste. Det at den tager egenskaberne fra begge deforrige funktioner betyder at den aldrig vil klare sig specielt meget darligere endden bedste af disse to i et hvilket som helst tilfælde.

5.4 Alpha-beta pruning

Alpha-beta pruning2 er en teknik, der kan anvendes til at se bort fra store deleaf et spiltræ.

2Alpha-beta pruning er beskrevet i kapitel 6, afsnit 3 i ”Articial Intelligence - A ModernApproach”.

5.4 Alpha-beta pruning 61

Alpha-beta pruning kan anvendes sammen med minimax algorithmen til at be-grænse mængden af grene, der er skal søges i gennem i spiltræet. Ved hjælp afalpha beta pruning er det muligt at afgøre om det er værd at fortsætte søgningenned af en gren, eller om det allerede kan ses at et bedre resultat kan opnas andensteds. Dette gøres ved at de henholdsvis bedste værdier for max og min gemmessom alpha og beat-værdier. Nar en søgning nar enden af en gren, er det muligtat sammenligne værdien af denne med alpha eller beta-værdien, og afgøre omder er grund til at fortsætte søgningen eller ej. Disse afbrydelser kan forsættelængere op gennem træet, men minimum et blad skal være besøgt før en grenkan klippes fra i søgningen.Alpha anvendes til at gemme den hidtil bedste løsning for Max pa vejen til detpagældende stadie, mens beta anvendes ligeledes for min. Hvis Max-funktionenet sted inde i søgningen modtager en værdi fra et af børnene, som er større endeller lige sa stor som beta-værdien for Min en generation over den nuværendeMax, sa afbryder Max sin igangværende søgning og returnere den fundne vær-di til den igangværende Min-funktion generationen højere oppe. Max afbryderher fordi, det lige er blevet bekræftet, at denne gren kun er pa niveau medeller darligere end overstaende Min-funktions hidtil bedste løsning, og det atforstsætte søgningen vil kun vise hvor meget darligere grenen er. Hvilket er ir-relevant, da Min-funktionen under alle omstændigheder aldrig vil vælge dennegren, nar der allerede er fundet en bedre mulighed.

5.4.1 Pseudo-kode for Minimax med Alpha-Beta pruning:

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ækInput : 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 .

s tad i e , s p i l l e t s nuværende s t a d i e .

IF s p i l l e r = hvid THEN Max( s tad i e , −i n f , i n f )ELSE Min( s tad i e , −i n f , i n f )

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 tInput : S , det a k t u e l l e s t a d i e i s p i l l e t .

a , den a k t u e l l e Alpha værdi .ß , den a k t u e l l e Beta værdi .

IF S er et e n d e l i g t s t a d i eTHEN v = e va lu e r i n g a f S RETURN v

v = − i n fFOR a l l e efterkommere a f S ( s )

m = Min( s , a , ß )

62 Optimering af Minimax

IF v < m THEN v = mIF v = ß THEN RETURN vIF a < v THEN a = v

RETURN v

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 tInput : S , det a k t u e l l e s t a d i e i s p i l l e t .

a , den a k t u e l l e Alpha værdi .ß , den a k t u e l l e Beta værdi .

IF S er et e n d e l i g t s t a d i eTHEN v = e va lu e r i n g a f S RETURN v

v = i n fFOR a l l e efterkommere a f S ( s )

m = Max( s , a , ß )IF v > m THEN v = mIF v = a THEN RETURN vIF ß > v THEN ß = v

RETURN v

5.4.2 Gennemgang af et eksempel pa Alpha-Beta pruning:

Da det kan være svært umiddelbart at overskue præcist hvordan Alpha-Betapruning fungere er her en grundig gennemgang af et eksempel pa Alpha-Betapruning.

5.4 Alpha-beta pruning 63

Figur 5.7: Eksempel pa et spiltræ.

For at starte søgningen køres Max() pa noden rod-noden A, med alpha-værdien-8 og beta-værdien 8. Havde det været den modsatte spiller der startede, skullesøgningen i stedet startes med Min().

Start Max(A,−∞,∞):Da søge dybden ikke er naet og A ikke er et endeligt stadie, sættes værdien forA sættes til −∞ og der køres Min() pa As børn.

Min(B,−∞,∞):Da søge dybden ikke er naet og B ikke er et endeligt stadie, sættes værdien forB sættes til ∞ og der køres Max() pa Bs børn.

Max(D,−∞,∞):Da søge dybden ikke er naet og D ikke er et endeligt stadie, sættes værdien forD sættes til −∞ og der køres Min() pa Ds børn.

Min(H,−∞,∞):Da søge dybden er naet, evalueres H og far i dette tilfælde værdien 5. Værdienreturneres.

Max(D,−∞,∞):Modtager værdien 5 fra H.Værdien for D sættes til at være den højeste værdi af de to værdier, den nuvæ-rende værdi for D (−∞) eller værdien for H (5). Værdien for D sættes til 5.Der checkes om værdien for D (5) er større end/lig med Beta (∞). Hvilket ikke

64 Optimering af Minimax

er tilfældet.Alpha sættes til at være den største værdi af Alpha (−∞) og værdien for D (5).Alpha = 5.Max(D) forsætter med det næste barn. Kører Min(I,5,8).

Min(I,5,∞):Da søgedybden er naet, evalueres I og far i dette tilfælde værdien 2. Værdienreturneres.

Max(D,−∞,∞):Modtager værdien 2 fra I.Værdien for D sættes til at være den højeste af de to værdier, den nuværendeværdi for D (5) eller værdien for H (2). Værdien for D forbliver 5.Der checkes om værdien for D (5) er større end/lig med Beta (∞). Hvilket ikkeer tilfældet.Alpha sættes til at være den største værdi af Alpha (5) og værdien for D (5).Alpha = 5.Da D ikke har flere børn returneres værdien (5).

Figur 5.8: Spiltræet efter at Max(D,−∞,∞) er blevet kørt.

Min(B,−∞,∞):Modtager værdien 5 fra D.Værdien for B sættes til at være den mindeste af de to værdier, den nuværendeværdi for B (∞) eller værdien for D (5). Værdien for B sættes til 5.

5.4 Alpha-beta pruning 65

Der checkes om værdien for B (5) er mindre end Alpha (−∞). Hvilket ikke ertilfældet.Beta sættes til at være den mindste værdi af Beta (∞) og værdien for B (5).Beta = 5.Min(B) forsætter med det næste barn. Kører Max(E,−∞,5).

Max(E,−∞,5):Da søge dybden ikke er naet og E ikke er et endeligt stadie, sættes værdien forE sættes til −∞ og der køres Min() pa Ds børn.

Min(J,−∞,5):Da søge dybden er naet, evalueres J og far i dette tilfælde værdien 6. Værdienreturneres.

Max(E,−∞,5):Modtager værdien 6 fra J.Værdien for E sættes til at være den højeste af de to værdier, den nuværendeværdi for E (−∞) eller værdien for J (6). Værdien for E sættes til 6.Der checkes om værdien for E (6) er større end/lig med Beta (5). Hvilket ertilfældet.Søgningen afbrydes og værdien for E (6) returneres.

Min(B,−∞,∞):Modtager værdien 6 fra E.Værdien for B sættes til at være den mindeste af de to værdier, den nuværendeværdi for B (5) eller værdien for E (6). Værdien for B forbliver 5.Der checkes om værdien for B (5) er mindre end/lig med Alpha (−∞). Hvilketikke er tilfældet.Beta sættes til at være den mindste værdi af Beta (5) og værdien for B (5).Beta forbliver 5.Da B ikke har flere børn returneres værdien 5.

Max(A,−∞,∞):Modtager værdien 5 fra B.Værdien for A sættes til at være den højeste af de to værdier, den nuværendeværdi for A (−∞) eller værdien fra B (5). Værdien for A sættes til 5.Der checkes om værdien for A (5) er større end/lig med Beta (∞). Hvilket ikkeer tilfældet.Alpha sættes til at være den største værdi af Alpha (−∞) og værdien for A (5).Alpha = 5.Max(A) forsætter med det næste barn. Kører Min(C,5,∞).

66 Optimering af Minimax

Figur 5.9: Spiltræet, hvor Min(C,5,∞) kaldes.

Min(C,5,−∞):Da søge dybden ikke er naet og C ikke er et endeligt stadie, sættes værdien forC sættes til 8 og der køres Max() pa Cs børn.

Max(F,5,∞): Da F er et endeligt stadie, evalueres F og far i dette tilfældeværdien 3. Værdien returneres.

Min(C,5,∞): Modtager værdien 3 fra F.Værdien for C sættes til at være den mindeste af de to værdier, den nuværendeværdi for C (∞) eller værdien fra F (3). Værdien for C sættes til 3.Der checkes om værdien for C (3) er mindre end/lig med Alpha (5). Hvilket ertilfældet.Søgningen afbrydes og værdien for C (3) returneres.Max(A,−∞,∞):Modtager værdien 3 fra C.Værdien for A sættes til at være den højeste af de to værdier, den nuværendeværdi for A (5) eller værdien fra C (3). Værdien for A forbliver 5.Der checkes om værdien for A (5) er større end/lig med Beta (∞). Hvilket ikkeer tilfældet.Alpha sættes til at være den største værdi af Alpha (5) og værdien for A (5).Alpha forbliver 5.Da A ikke har flere børn er søgning slut.Resultatet er at B er det bedste træk, da dette træk har den højeste minimumsværdi pa 5.

5.4 Alpha-beta pruning 67

Figur 5.10: Det færdige spiltræet. De gra noder er ikke blevet undersøgt. Dentykke, sorte vej markere de endelige valg for Max og Min.

5.4.3 Alpha-Beta pruning pa spilgraf:

I et spiltræ er det relativt nemt at afslutte en undersøgelsen af en brættilstand,nar visse kriterier er opfyldt og sa ga videre uden at bekymre sig mere om den.Det samme er dog ikke tilfældet for en spilgraf. I en spilgraf er det nemlig muligtat komme tilbage til denne brættilstand, der tidligere er blevet besøgt, som kanvære blevet søgt helt igennem eller afbrudt undervejs af AlphaBeta pruning’en.Nar en sadan brættilstand mødes igen er det nødvendigvis ikke under sammekriterier som forrige gang. Alpha og beta-værdierne, som afgør om undersøgelsenaf brættilstanden skal afsluttes før tid, kan have ændret sig i mellemtiden og denværdi, som er gemt i brættilstanden fra forrige møde, kan være blevet forældet.Fortages søgningen pa ny under de nye kriterier for at undga at værdi ikkelængere er tidsvarende, forsvinder hele ideen med at benytte en spilgraf, nemligat den samme brættilstand ikke søges igennem flere gange. Anvendes den gemtværdi derimod uden at undersøge brættilstanden igen, risikeres der at det en-delige resultat bliver forkert.Løsningen er at finde en made at vurdere hvornar en ny undersøgelse er nødvendigog hvornar den gemte værdi kan anvendes uden videre.

For finde ud af om en ny undersøgelse af brættilstanden er nødvendig, er det

68 Optimering af Minimax

vigtigt at være opmærksom pa præcis hvilken information der er gemt i værdienfor brættilstanden. Uanset hvilke kriterier undersøgelsen af brættilstanden tid-ligere er blevet foretaget med, vil værdien være et minimum for hvor godt entenMin eller Max vil klare sig for denne brættilstand. Om det er Min eller Maxafhænger af brættilstandens generation. Er generationen over brættilstanden enMin-generation er brættilstanden selv af en Max-generation og omvendt.Værdien gemt i brættilstanden kommer altsa ikke til at blive bedre end den alle-rede er set fra Max eller Min’s syn generationen over brættilstanden. Sa hvis Mingenerationen over arbejder med en beta-værdi, der er lige sa stor eller større endden gemte værdi, behøver den ikke lave en nye undersøgelse af brættilstanden,da der allerede findes en lige sa god eller bedre løsning. Er det ikke tilfældet,bliver den nødt til at starte en ny undersøgelse af brættilstanden med de nyealpha og beta værdier, da det ikke kan garanteres at værdien for brættilstandenikke reelt er højere end hvad den forrige undersøgelse var kommet frem til, daden blev afsluttet.Er det Max, der er i gang generationen før brættilstanden, skal der i stedetcheckes om alpha-værdien er mindre end eller lige sa stor som den gemte værdi.Er den mindre end eller lige sa stor er der ingen grund til at undersøge brættil-standen igen.

Normalt checker Min- eller Max-funktionen om et træk resultere i en bræt-tilstand der allerede eksisterer, hvis den gør det tilføjer den brættilstand som etbarn og tilføjer sig selv som forældre pa brættilstanden, og sa gøres der ellersikke mere ved den. Men med alpha beta-pruning inde i billedet, stopper denikke længere. Ligesom hvis den ikke havde konstateret at der allerede fandtesen sadan brættilstand, kører den enten Max eller Min pa tilstanden, dog medden lille forskel, at udover at sende alpha og beta værdierne med, sender den enværdi der indikere om brættilstand fandtes i forvejen eller ej.Det første Min eller Max gør, i tilfælde af at brættilstanden allerede eksisterede,er at sammenligne henholdsvis alpha og beta med brættilstandens gemte værdi.Er værdien for Min’s vedkommende mindre end eller lig med alpha eller forMax’s vedkommende større end lig med beta, stoppes processen der og værdiengemt i brættilstanden returneres. Er det ikke tilfældet fortsætter Min og Maxpa sædvanligvis.

5.4.4 Fordele og ulemper:

Sammenlignet med en almindelige Minimax algoritme har Alpha-Beta versioneningen ulemper, da den altid vil kom frem til samme løsning, bare hurtigere. Deneneste forskel der kan komme til syne er, at der kan være mindre variation iAlpha-Beta versionens træk. Dette skyldes at den kunstige intelligens er sat

5.4 Alpha-beta pruning 69

til at vælge et tilfældigt træk, nar der er mere end et træk med den bedsteværdi. Her er det muligt at Alpha-Beta pruningen har frasorteret grene, somhvis de havde været søgt til bunds, havde vist sig at være lige sa gode somden fundne løsning men aldrig bedre. I det tilfælde ville mængden af lige godetræk, som den kunstige intelligens havde at vælge imellem, været mindre endmed en almindelige Minimax AI. Var dette dog en prioritet, kunne Alpha-Betaversionen hurtigt modificeres til ogsa at finde alle de bedste løsninger og stadigvære hurtigere end den almindelige Minimax AI. Dette kunne opnas blot ved atændre parametrene til ikke at stoppe en søgning ved en kun lige sa god løsning,men først at stoppe nar den viser sig decideret at være darligere end den hidtilbedst fundne. Det er dog svært at finde et scenarie, hvor det vil være sa vigtigtat være sikker pa at alle lige gode løsninger kommer med, at det er den ekstraregnetid værd.Desuden er der problemerne som er beskrevet i afsnit omkring heuristik.

5.4.5 Mulige forbedringer:

Jo tidligere en god løsning findes, jo flere darlige løsning kan sa udelukkes indender søges til bunds. Derfor kan kørslestiden af en Minimax AI som anvenderAlpha-Beta pruning forbedres ved at der sørges for, at de grene som forventesat have en god løsning søges igennem først, saledes at der formentligt vil være etgodt udgangspunkt for at stoppe de darligere løsninger pa et tidligere tidspunkt.

70 Optimering af Minimax

Kapitel 6

Begrænsning af antallet afundersøgte træk

6.1 Local Area

Ideen med Local Area AI’en et at fokusere søgningen omkring et lille omrade,der sa til gengæld søges helt til bunds. Omradet lægges omkring modstanderensseneste træk, med mindre det er Local Area AI’en der starter. I sa fald liggerden bare en brik pa midten af brættet. Denne AI vil formentligt spille meredefensivt end offensivt, da den fokusere pa modstanderens træk som udgangs-punkt. I praksis er det blot Minimax algoritmen med Alpha-Beta pruning, dersættes til at spille pa en lille plade midt i den store plade. Heuristikken vurde-re dog spillet pa hele pladen og ikke kun det lokale omrade. Dette betyder atfigurer, der ligger op ad det lokale omrade, far den indflydelse de skal have pascoren som AI’en vælger sit træk ud fra. Local Area AI’en kører med et lokaltomrade pa 4x4, da dette er den største plade, hvor pa Minimax algoritmen medAlpha-Beta pruning kan finde den fuldstændige løsning.Hvis modstanderen lægger sin brik tæt pa kanten af brættet flytter AI’en detlokale omrade længere ind mod midten for fortsat at udnytte hele regnearealet.

72 Begrænsning af antallet af undersøgte træk

Figur 6.1: Eksempel pa søge areal rundt om seneste brik.

6.1.1 Fordele og ulemper:

Fordelen ved denne AI er at den vil fungere ved en hver brætstørrelse, sa længebrættet bare er mindst fire gange fire.

6.1.2 Mulige forbedringer:

Det er muligt at denne AI kan forbedres ved at søgearealet udvides pa bekostningaf søgedybden.

6.2 Growth

Growth AI’en bygger pa, at det kun er de to største figurer for hver spiller, derer relevante for spillet og at disse kun er relevante sa længe der er mulighed forat udvide dem. Dermed er alt andet end de to største figurer, der stadig har

6.2 Growth 73

mulighed for udvidelse, irrelevant og ikke værd at bruge tid pa at undersøge.Forskellen pa denne kunstige intelligens og den sædvanlige Minimax algoritmeer, at hvor den almindelige AI lader en mulig efterkommer opsta, lader GrowthAI’en kun efterkommer opsta som ligger op ad de to største figurer med mulig-hed for udvidelse. Disse efterkommer vil gøre en af to ting, enten vil de udvideAI’ens egen figurer eller ogsa vil de fratage modstanderen nogle af mulighedernefor udvidelse pa sine største figurer. Denne AI kaldes netop Growth, fordi efter-kommerne sa at sige vokser ud fra de største figurer, hvor der er mulighed for det.

Figur 6.2: Eksempel pa hvor Growth forsøger at lægge brikker. Hver rød stregrepræsenterer en brik og den samme brik vendt 180 grader.

74 Begrænsning af antallet af undersøgte træk

Figur 6.3: Hvor Growth forsøger sig med at lægge brikker efter den nye brik erblevet lagt som forsøg.

6.2.1 Fordele:

Der vil blive set mere pa det i testafsnittet, men i praksis ser Growth ud tilat spille lige op med den almindelige Alpha-Beta Minimax algoritmen bade paresultat og afviklingstid, nar de spiller med samme søgedybde. Dette betyder athvis det lykkes ogsa at implementere Alpha-Beta pruning pa Growth AI’en, vildenne formentligt fa muligheden for at regne en generation dybder end Mini-max algortimen med Alpha-Beta pruning. Om ikke anden sa i hvert fald øgesøgedybden tidligere i spillet.

6.2.2 Ulemper:

Der vil opsta tilfælde, hvor det bedre kan betale sig at lægge en brik lidt væk frade største figurer og lade modstanderen forbinde figurerne. Dette vil dog aldrigske med denne AI, da der kun ses pa mulighederne lige opad de størstefigurer.Med den nuværende heuristik lider denne kunstige intelligens ogsa under atfamle i blinde, nar de største figurer ikke længere har muligheden for udvidelser,

6.2 Growth 75

og de næststørste figurer har lang vej igen for na op pa de største. Det ser dogikke ud som om den famler helt sa meget i blinde, da den altid placerer brikkerneop ad de næststørste figurer med mulighed for udvidelse. Men om de brikkerden lægger op ad disse figurer hjælper sig selv eller modstanderen, er den stadigkomplet blind over for.Et trejde problem

6.2.3 Mulige forbedringer:

Som det første er der at fa implementeringen af Alpha-Beta pruning til at fun-gere. Pa nuværende tidspunkt er aplha-beta pruningen slaet fra, da den ikkefungerer korrekt. Derudover er der muligheden for at forbedre heuristikken, saden ikke længere famler i blinde nar søgedybden ikke dækker over problemetmed store afsluttede figurer. Som alternativ til forbedring af heuristikken, kun-ne skabelsen af efterkommer ændres saledes, at den kun lægger brikker, sa deudvider egne figurer eller tager muligheder fra modstanderens, hvor den nu af-prøver f.eks. at lægge den sorte ende af en brik op mod sin egen hvide figureller lægge en sort ende op mod modstanderens sorte figur. Dette vil dog redu-cere mængden af træk, som bliver undersøgt med en faktor to pa godt og ondt.Afviklingstiden vil falde, og dette vil give mulighed for dybere søgninger, mensandsynligheden for at en bedre løsning ikke bliver undersøgt vil ogsa stige.

76 Begrænsning af antallet af undersøgte træk

Kapitel 7

Test og sammenligning af deimplementerede AI’er

I dette afsnit vil de forskellige kunstige intelligenser blive test og sammenlignet.Udover de komplementerende AI’er vil Taiji designeren Nestor Romeral Andres’egen AI ogsa indga i testen, sa det er muligt at sammenligne resultaterne. Deforskellige AI’er vil blive afprøvet mod en menneskelige modstander, mod hin-anden sa vidt muligt og der vil blive taget tid pa hvor hurtigt beregningernebliver udført.

7.1 Test af Nestor’s AI

Nestor’s egen AI spiller kun med standard brætstørrelsen pa ni gange ni felterog vil derfor kun blive testet for denne størrelse. Nestor’s AI har fire sværdhedsgrader, hvor 1 er den letteste og 4 er den sværeste, 4 kræver ogsa længst tidtil at beregne sit træk. De fire sværhedsgrader gar ogsa under navne Basic (1),Intermediate (2), Expert (3) og Master (4).

78 Test og sammenligning af de implementerede AI’er

7.1.1 Kørselstider for Nestor’s AI:

Her under ses gennemsnits kørsels tiderne for Nestor’s AI taget over de første10 træk:

Basic Intermediate Expert Master9x9 ca. 1 sek ca. 3 sek ca 15 sek ca. 50 sek

De to mest krævende sværhedsgrader Expert og Master bliver dog mærkbarthurtigere nar spillet nærmere sig enden, f.eks bruger Master omkring 25 sekun-der nar der er cirka 15 træk tilbage og ca. 10 sekunder nar der er cirka 8 træktilbage.Beregningstiderne for de to letteste sværhedsgrader er helt i orden. Intermedi-ate er lige i overkanten, da en menneskelig modstander vil na at blive en smuleutalmodig inden computeren foretager sit træk. Master er derimod helt uaccep-tabel med beregningstider der tager op i mod et minut. Et spil Taiji forventesat vare omkring 20 minutter mellem to menneskelige spiller 1 , hvor der brugeslængere tid pa at fysisk lægge brikkerne og der formentligt snakkes lidt, og derbliver tænkt lidt længere over trækkene end mod en computer, hvor ens æreikke star pa spil pa samme made. Et spil Taiji kan indeholde op til 40 trækog minimum 27, AI’en kommer til at sta for halvdelen af disse. Dette betyderat AI’en alene kommer til at sta for rundt regnet et kvartes betænkningstid iløbet af et enkelt spil. Til sammenligning kan et spil mod Intermediate sagtensafsluttes pa 3 minutter til den menneskelige spillers fordel.

7.1.2 Test af Nestor’s AI mod menneskelig modstander:

Her bliver Nestor’s AI stillet overfor en erfaren menneskelig modstander, hvilketjeg efterhanden godt kan tillade mig at kalde mig selv. Basic er ikke taget medi testen, da dennes eneste fordel er dens lave beregningstid, hvor Intermediateer storset lige sa hurtig, men er betydeligt smartere.

Intermediate (sort) mod erfaren menneskelig spiller (hvid):

1Tal fra boardgamegeek.com

7.1 Test af Nestor’s AI 79

9x9 Hvid score Sort score stilling for AI18 17 Tabt19 16 Tabt14 9 Tabt30 12 Tabt19 14 Tabt

I alt 100 68 0%

Intermediate (hvid) mod erfaren menneskelig spiller (sort):9x9 Hvid score Sort score stilling for AI

15 29 Tabt9 22 Tabt12 20 Tabt10 15 Tabt10 24 Tabt

I alt 56 110 0%

Intermediate vinder altsa ingen af sine 10 spil, hverken som sort eller hvid spiller.Gennemsnitligt taber den med 8,6 point og det nærmeste den kommer uafgjorter en forskel pa 3 point.

Expert (sort) mod erfaren menneskelig spiller (hvid):9x9 Hvid score Sort score stilling for AI

22 11 Tabt25 11 Tabt19 16 Tabt26 9 Tabt19 12 Tabt

I alt 111 59 0%

Expert (hvid) mod erfaren menneskelig spiller (sort):9x9 Hvid score Sort score stilling for AI

14 19 Tabt13 24 Tabt12 24 Tabt14 29 Tabt16 32 Tabt

I alt 69 128 0%

Expert vinder heller ikke nogen af sine 10 spil. Gennemsnitligt taber den med11,1 point, men til gengæld kommer den tæt pa at afslutte et enkelt spil med

80 Test og sammenligning af de implementerede AI’er

uafgjort med kun et points forskel.

Master (sort) mod erfaren menneskelig spiller (hvid):9x9 Hvid score Sort score stilling for AI

22 14 Tabt12 11 Tabt17 14 Tabt19 8 Tabt24 12 Tabt

I alt 94 59 0%

Master (hvid) mod erfaren menneskelig spiller (sort):9x9 Hvid score Sort score stilling for AI

9 17 Tabt11 19 Tabt15 29 Tabt11 18 Tabt12 17 Tabt

I alt 58 100 0%

Master taber ogsa alle sine 10 spil pa trods af sine lange beregningstider. Dentaber dog gennemsnitligt med point 7,7 points, hvilket har været det lavesteindtil videre. Samtidigt kommer den i et enkelt tilfælde lige sa tæt pa uafgjortsom Expert med et enkelt points forskel.

7.1.3 Sammenfatning af resultatet for Nestor’s AI:

Nestor’s AI beregner hurtigt et træk ved de to laveste sværhedsgrader, mensætter nærmeste brikkerne tilfældigt ved den laveste sværhedsgrad og yder ikkeden store modstand pa Intermediate.Expert sværhedsgraden bruger typisk en 15 sekunder pa at beregne sit træk,hvilket er fem gange sa meget som Intermediate, pa trods af dette klarede densig gennemsnitligt ikke meget bedre en denne, dog kom den i et enkelt tilfældetættere pa et uafgjort resultat.Master kan bruge næsten et helt minut pa at beregne sit træk, pa trods af detteopnaede den kun nederlag overfor den erfarende menneskelige spiller. Den kla-rere sig dog bedre end de alle de lavere sværhedsgrader, sa længe der ses bortfra beregningstiden.Det kunne forventes at Masters lange beregningstider ogsa har givet den men-neskelige spiller længere tid til at overveje sit næste træk, og at dette har været

7.2 Test af AlphaBeta AI (udviklet af Morten Rask) 81

med til at danne resultatet med en kun let fremgang fra forrige niveau. I praksishar de lange beregningstid dog betydet at jeg som testperson er gaet helt vækfra spillet og lavet noget andet indimellem i de lange ventetider.

7.2 Test af AlphaBeta AI (udviklet af MortenRask)

AlphaBeta bruger en minimax søgning med alpha beta pruning. Den eneste for-skel mellem den almindelige minimax AI og AlphaBeta versionen er beregning-stiden. Var det ikke for det tilfældige valg mellem lige gode træk ville AlphaBetaog minimax AI’en altid vælge samme træk.

7.2.1 Kørselstider for AlphaBeta AI’en:

For en fuld søgningen gennem spilgrafen for en fire gange fire plade, har delængste beregningstider altid været for det første træk, hvor der selvfølgelig ermest at regne igennem. Disse søgninger har taget lidt under 6 sekunder. Starterden anden spiller skal AlphaBeta AI’en beregne et træk mindre, beregningstidenher svinger mellem 1,7 og 3,3 sekunder afhængigt af hvilket træk modstanderenforetager. Alle beregningstider herefter er ubetydeligt sma.Pa en ni gange ni plade, hvor dybden bliver begrænset, har de længste bereg-ningstider gennem fem spil været pa lige under fire sekunder langt de fleste tiderhar dog ligget under to sekunder.

7.2.2 Test af AlphaBeta AI med fuld søgning

AlphaBeta AI’en kan højst kører pa en fire gange fire plade, hvis søgningen skalga helt til bunds i spilgrafen. Forventningerne er at det ikke vil være muligtat opna et bedre resultat end uafgjort mod AlphaBeta AI’en pa den størrelseplade. Lykkedes det at besejre denne AI vil det enten betyde at der er en vin-derstrategi for brætstørrelsen fire gange fire, eller at der er en fejl i AI’en.AI’en beregninger siger at der ikke er nogen vinderstrategier, da AI’en selv efteren fuld søgning giver alle de mulige start træk enten værdien 0, ufgjort, eller-1, tabt. Ergo vil AI’en altid kunne fa uafgjort uanset hvordan modstanderenspiller. -1-værdierne pa først træk betyder ogsa, at der er start træk, som altidvil lede til et nederlag, mod en modstander der ikke begar fejl.

82 Test og sammenligning af de implementerede AI’er

Da AI’en ikke mener, der er nogle vinderstrategier, vil et nederlag for AI’enbetyde at den ikke fungere korrekt, dette vil dog hverken bekræft eller udelukkeom der er en vinderstrategi eller ej.

AlphaBeta (hvid) mod erfaren menneskelig spiller (sort):

4x4 Hvid score Sort score stilling for AI6 6 Uafgjort3 3 Uafgjort6 6 Uafgjort5 5 Uafgjort7 7 Uafgjort7 7 Uafgjort5 5 Uafgjort7 6 Vundet6 6 Uafgjort7 7 Uafgjort

I alt 59 58 55%

Gennem ti spil med AlphaBeta spillende som hvid, har den som forventet aldrigtabt og derud over vundet et enkelt spil.

AlphaBeta (sort) mod erfaren menneskelig spiller (hvid):

4x4 Hvid score Sort score stilling for AI4 4 Uafgjort2 2 Uafgjort6 6 Uafgjort2 2 Uafgjort5 5 Uafgjort7 7 Uafgjort7 7 Uafgjort7 7 Uafgjort6 6 Uafgjort6 6 Uafgjort

I alt 52 52 50%

Heller ikke nar den menneskelige spiller starter far AlphaBeta AI’en et darligereresultat end uafgjort.

AI’ens værdier pa mulighederne for første træk viste at nogle disse ville føretil nederlag mod en modstander som ikke laver fejl. Det er disse to træk og allespejlinger og rotationerne af disse:

7.2 Test af AlphaBeta AI (udviklet af Morten Rask) 83

Figur 7.1: De to træk der leder til nederlag (for hvid spiller, nar hvid starter).

Herunder forsøger den menneskelige spiller at vinde eller fa uafgjort efter atvære startet med et af disse to træk.

AlphaBeta (sort) mod erfaren menneskelig spiller, som starter med nederlagstræk (hvid):

4x4 Hvid score Sort score stilling for AI4 5 Vundet3 5 Vundet3 5 Vundet5 7 Vundet7 8 Vundet3 4 Vundet4 5 Vundet3 5 Vundet4 6 Vundet3 4 Vundet

I alt 39 54 100%

Det kan ses at AI’en vinder alle spillene, na den menneskelige spiller startermed et af de to træk, som AI’en har vurderet ender i nederlag. Dette paviser atder er starttræk der leder direkte til nederlag mod en øvet modstander.Disse test viser ogsa at de konklusioner, der blev draget ud fra værdierne forde forskellige starttræk, som AlphaBeta AI’en beregnede, har vist sig at holdestik gennem alle forsøgene. Der kan udfra dette konkluderes at AlphaBeta AI’enfungere korrekt, det vil dog kræve en komplet spilgraf for en fire gange fire plade,lavet i handen at bevise dette, hvilket er en meget stor og uoverskuelige opgave,da der er godt og vel 30000 brættilstande for et spil pa fire gange fire og det eruden rotationer og spejlinger, hvor antallet for brætstørrelsen tre gange tre varpa lidt over 100.

84 Test og sammenligning af de implementerede AI’er

7.2.3 Test af AlphaBeta AI mod menneskelig modstander:

Her bliver AlphaBeta AI’en sat op imod en erfaren menneskelig modstander.AlphaBeta (sort) mod erfaren menneskelig spiller (hvid):

9x9 Hvid score Sort score stilling for AI17 18 Vundet10 11 Vundet20 12 Tabt24 14 Tabt17 18 Vundet

I alt 88 73 60%

AlphaBeta (hvid) mod erfaren menneskelig spiller (sort):9x9 Hvid score Sort score stilling for AI

15 18 Tabt16 15 Vundet20 22 Tabt16 20 Tabt14 14 Uafgjort

I alt 81 89 30%

Samlet set har AlphaBeta vundet 4 spil, tabt 5 og et endte i uafgjort. Dettegiver en vindings procent pa 45% . Nar det kommer til ren score har den gen-nemsnitligt tabt med 2,3 point. Dens sejre har alle været snævre, mens nogle afdens nederlag har være af større karakter.

Den menneskelige spiller har aldrig brugt mere end 5 sekunder pa sine træk.Dette har været tilstrækkeligt til udelukkende at sejr over Nestor’s AI, dettehar dog ikke været tilfældet her, hvor kun 55% har været sejre. Menneskeligespiller er svære at handtere, nar det kommer til holde præstationen konstant.Motivation, mental tilstand, humør og talmodighed spiller alle ind pa kvalitetenaf den menneskeliges spillers præstation, for ikke at nævne den konstant stigen-de erfaring med spillet. Det er derfor en god ide at opstille nogle rammer forden menneskelige modstand. F.eks. har den menneskelig modstander hidtil ikkebrugt mere end fem sekunder pa at tænke over sit træk. Dette kan bruges somen regel til at holde den menneskelige modstander niveau lidt nede. Alternativkun en regel, som at der minimum skal ga 15 sekunder før den menneskeligespiller foretager et træk, hjælper til at holde niveauet oppe.Det høje niveau har ikke været nødvendigt mod Nestor’s AI, men det kunnevæ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

indflydelse pa resultatet.

AlphaBeta (sort) mod erfaren menneskelig spiller min 15 sek (hvid):

9x9 Hvid score Sort score stilling for AI25 13 Tabt10 12 Vundet15 12 Tabt17 12 Tabt18 11 Tabt

I alt 85 60 20%

AlphaBeta (hvid) mod erfaren menneskelig spiller min 15 sek (sort):

9x9 Hvid score Sort score stilling for AI11 14 Tabt14 26 Tabt11 21 Tabt9 9 Uafgjort13 14 Tabt

I alt 58 84 10%

Det ekstra betænkningstid, som er blevet patvunget den menneskelige spiller,har givet resultat. AlphaBeta AI’ens sejrs procent er gaet ned fra 45% til kun15% . Dette er uden tvivl et resultat af færre fejl pa grund bedre overvejedebeslutninger fra den menneskelige side.

7.3 Test af LocalArea AI (designet og udvikletaf Morten Rask)

LocalArea AI’en benytter en minimax søgning med alpha beta pruning til atsøge et omrade pa fire gange fire helt til bunds, uanset brættets størrelse. Detteomrade placeres omkring modstanderens sidst lagte brik, er der ingen frie pladserinden for dette omrade flyttets det til et sted hvor der er.

86 Test og sammenligning af de implementerede AI’er

7.3.1 Test af LocalArea AI pa en 4x4 plade:

Denne test er i sig selv ikke sa interessant, da resultatet skulle være præcistdet samme som for AlphaBeta AI’en, da disse fungere ens pa en fire gange fireplade. Det er dog vigtigt at konstatere at LocalArea AI’en fungere korrekt in-den den slippes løs pa de større brætter, hvor det vil være svært at gennemskueforskellen mellem deciderede fejl og generelle problemer med netop den metode.Her gør rammerne det tydeligt hvorvidt AI’en fungere, da en lokal fuld dybdesøgning pa fire gange fire anvendt pa et fire gange fire bræt, ikke ma kunne tabe.

LocalArea (sort) mod AlphaBeta (hvid):

4x4 Hvid score Sort score stilling for LocalArea6 6 Uafgjort2 2 Uafgjort6 6 Uafgjort5 5 Uafgjort6 6 Uafgjort5 5 Uafgjort6 6 Uafgjort8 8 Uafgjort4 4 Uafgjort5 5 Uafgjort

I alt 53 53 50%

LocalArea (hvid) mod AlphaBeta (sort):

4x4 Hvid score Sort score stilling for LocalArea4 4 Uafgjort6 6 Uafgjort5 5 Uafgjort5 5 Uafgjort2 2 Uafgjort4 4 Uafgjort5 5 Uafgjort4 4 Uafgjort4 4 Uafgjort6 6 Uafgjort

I alt 45 45 50%

Alle spil endte i uafgjort mellem AlphaBeta og LocalArea, hvilket tyder paat LocalArea udfører sin søgning pa sit fire gange fire areal korrekt.

7.4 Test af Growth AI (designet og udviklet af Morten Rask) 87

7.3.2 Test af LocalArea AI pa en 9x9 plade:

Pa en plade større end fire gange fire tildeler LocalArea trækmulighederne for-kert værdier, i form af enten ∞ eller −∞ . De mulige træk placeres dog korrektindenfor det pagældende fire gange fire omrade.

Det interessante ved fejlen for LocalArea AI’en er, udover at den virker fintfor et 4x4 bræt, at der er bade negative og positive ”uendelige”værdier, ofte vilder kun være et fortegn, hvis der f.eks. er blevet lavet en fortegnes fejl sa enværdi, der skulle være meget lille, er sa stor at den overtrumfer alt.Jeg er overbevidst om at forklaring skal findes i, at undersøgelsen af hvorvidten brættilstand har naet bunden eller ej ikke længere fungerer korrekt, da derstadig kan findes lovlige træk uden for arealet som LocalAera koncentrer sigom. Derfor ender alle værdier med at blive pa det minimum eller maksimum defik tildelt fra start af. De endelige brættilstande bliver ikke vurderet til at væreendelige brættilstande, men de far heller ikke nogle børn, da alle pladser indenfor arealet er optaget. Grund til der bade opstar positive og negative værdi erfordi det vil være forskelligt om de endelige brættilstande er af lige eller uligegeneration, derfor bliver nogle handteret af Min-funktionen og far værdien ∞,mens andre af Max-funktionen og far −∞.

En løsning ville være at lave en nye funktion til at vurdere, hvorvidt en bræt-tilstand er endelige ud fra det lokal areal i stedet for hele brættet.

7.4 Test af Growth AI (designet og udviklet afMorten Rask)

7.4.1 Test af Growth AI’en pa en 4x4 plade:

Det er interessant at se hvordan Growth klare sig mod AlphaBeta, da Growthnetop ser bort fra træk der anses som uinteressante, mens AlphaBeta forsøgersig med alle træk. Denne test vil visse om de træk Growth ser bort fra virkeligter uinteressante eller om det lykkedes AlphaBeta at vinde netop pa grund afdisse træk.

Growth (sort) mod AlphaBeta (hvid):

88 Test og sammenligning af de implementerede AI’er

4x4 Hvid score Sort score stilling for Growth4 4 Uafgjort6 6 Uafgjort5 5 Uafgjort4 4 Uafgjort7 7 Uafgjort4 4 Uafgjort4 4 Uafgjort4 4 Uafgjort5 5 Uafgjort5 5 Uafgjort

I alt 48 48 50%

Growth (hvid) mod AlphaBeta (sort):

4x4 Hvid score Sort score stilling for Growth4 4 Uafgjort4 4 Uafgjort6 6 Uafgjort4 4 Uafgjort4 4 Uafgjort6 6 Uafgjort5 5 Uafgjort4 4 Uafgjort4 4 Uafgjort4 4 Uafgjort

I alt 45 45 50%

Testen viser at Growth pa en fire gange fire plade ikke er AlphaBeta under-legen pa trods af at den undersøger færre træk.Pa en lille plade som fire gange fire er det dog rimeligt begrænset hvor man-ge træk Growth ser bort fra. Jo større pladen bliver jo større bliver forskellenmellem antallet af undersøgte træk for Growth og AlphaBeta. Om resultatet vilvære et andet for større plader er svært at sige, da det ikke er muligt at lave enfuld søgning pa plader større end fire gange fire.

7.4.2 Test af Growth AI’en pa en 9x9 plade:

Growth (sort) mod erfaren menneskelig spiller (hvid):

7.4 Test af Growth AI (designet og udviklet af Morten Rask) 89

9x9 Hvid score Sort score stilling for AI11 12 Vundet15 12 Tabt18 17 Tabt14 12 Tabt11 11 Uafgjort

I alt 69 64 30%

Growth (hvid) mod erfaren menneskelig spiller (sort):

9x9 Hvid score Sort score stilling for AI17 19 Tabt14 18 Tabt13 13 Uafgjort19 12 Vundet15 10 Vundet

I alt 64 82 50%

Resultatet for Growth mod den erfaren menneskelige modstander, som maxi-mum bruger 5 sekunder pa hvert træk, er lige sa godt som resultatet for Alpha-Beta ved samme test med 45% vundende spil. Lige som for AlphaBeta forsøgesder ogsa mod den menneskelige spiller, hvor der bruges minimum 15 sekunderper træk.

Growth (sort) mod erfaren menneskelig spiller min 15 sek(hvid):

9x9 Hvid score Sort score stilling for AI21 16 Tabt20 14 Tabt13 12 Tabt10 13 Vundet12 15 vundet

I alt 76 70 40%

Growth (hvid) mod erfaren menneskelig spiller min 15 sek(sort):

9x9 Hvid score Sort score stilling for AI10 10 Uafgjort11 12 Tabt14 15 Tabt12 11 Vundet11 14 Tabt

I alt 58 62 30%

90 Test og sammenligning af de implementerede AI’er

7.5 Sammenligning af AI’erne

Der er foretaget færre spil med Nestor’s AI, da disse spil er langt mere tidskræ-vende end de andre, bade fordi Nestor’s bedste af AI har lange beregningstiderog fordi Nestor’s AI ikke kan spille direkte mod de andre AI’er eller mod sigselv. Det her derfor været nødvendigt manuelt at kopier træk frem og tilbagemellem AI’erne i hvert deres vindue. Skal en hvid Nestor AI f.eks spille mod ensort AlphaBeta, bliver det til en hvid Nestor AI mod en sort menneskelig spillerog en hvid menneskelig spiller mod en sort AlphaBeta, hvor den menneskeligspiller blot kopier Nestor AI’ens træk mod AlphaBeta i det andet vindue ogomvendt.

Resultatet i parentes er for de Officielle Regler, hvor uafgjort tæller som ensejr til sort.

9x9:

Hvid spiller Sort spiller antal spil hvid score sort score hvid% (OR)Nestor4 Nestor4 5 66 67 50% (40%)Nestor4 AlphaBeta 5 73 71 70% (60%)Nestor4 Growth 5 57 73 0% (0%)

AlphaBeta AlphaBeta 10 171 165 65% (50%)AlphaBeta Nestor4 5 81 62 80% (80%)AlphaBeta Growth 10 147 162 30% (20%)

Growth Growth 10 157 164 50% (40%)Growth Nestor4 5 90 75 90% (80%)Growth AlphaBeta 10 182 141 100% (100%)

Mens AlphaBeta og Nestor4 har en vis tendens til at vinde over hinanden, narde spiller hvid, sa slar Growth dem begge overbevisende uanset hvilken farveden spiller som.

Nar det kommer til beregningstiderne pa de tre er det mest sigende at ladedem kører et helt spil igennem mod sig selv:

9x9 spil mod sig selv AlphaBeta Growth Nestor4tiden (gennemsnit af flere spil) ca. 30 sekunder ca. 1 minut ca. 19 minutter

Kapitel 8

Konklusion

Jeg matte konstatere under testen af den AI, som Nestor Romeral Andres harkonstrueret til at spille Taiji, at den ikke er særlig anvendelig i praksis. Den erfor langsom, nar den skal yde sit ypperste for at vinde spillet. Desuden mattejeg konkludere, at den ikke pa nogen af sine fire niveauer kan vinde over enkvalificeret menneskelig modstander.

Derfor satte jeg for at teste, om det kunne lade sig gøre at na et højere ni-veau med anvendelse af flere metoder indenfor AI.Hvis man ikke har ubegrænsede ressourcer som i IBM’s Deep Blue skakcompu-terprojekt, er det afgørende at kombinere forskellige metoder og kunne benyttedem i velovervejet omfang, saledes at man udnytter de tilgængelige computer-kræfter smart og opnar et anvendeligt resultat.

I opbygningen af mine AI’er har jeg undersøgt forskellige teorier for kunsti-ge intelligencer (AI’er) og gennemprøvet disse. Derefter har jeg kombineret demsom gav de bedste resultater og gav mest mening for den foreliggende opgave, atspille Taiji. Mit hovedformal har netop været at opna en AI som netop opførersig intelligent og samtidig en AI der er tilstrækkelig hurtig til at den kan anven-des i praksis. Desuden forlangte jeg at den skulle kunne vinde over en rimeliggod menneskelig modstander.

Min Growth AI er bade hurtigt og smart. Growth AI’en kan i spil mod sig

92 Konklusion

selv na igennem et helt spil pa omkring et minut. Den samme opgave tagerfor Nestor Romeral Andres’ kraftigste AI næsten 20 minutter. Men pa trodsaf at Nestor Romeral Andres’ AI anvender godt 20 gange sa lang tid til sineberegninger som Growth, lykkedes det kun at vinde et ud 10 spil, og dette varud fra de officielle regler, hvor et uafgjort resultat tæller som en sejr for sort.Growth vinder ni ud af ti gange, hvor den sidste en ud af ti endte uafgjort ellertabt afhængigt af reglerne. Og dette gjorde den pa kun ca. 5% af den tid NestorRomeral Andres’ AI anvendte.Desværre er resultatet ikke lige sa overbevisende mod en erfaren menneskeligspiller, hvor den vinder en tre-fire gange ud af ti spil, hvilket dog ogsa er etganske glimmerende resultat sammenlignes med de andre AI’ers resultater.

Min overordnede konklusion er derfor, at ved at benytte flere AI-teorier ogkombinere disse pa gennemtænkt og gennemtestet made, kan man opna væ-sentlige forbedringer vedr. afviklingshastighed uden at sætte ’intelligensen’ overstyr. Dette er netop bevist med min AI. Derfor mener jeg ogsa det er rimeligtat konkludere at AI vil kunne anvendes med fordel i flere gennemanalyseredesituationer. Disse situationer kan netop handteres med AI uden at der behøvesat anvendes overvældende computerkraft.Men ligesom det kan konkluderes at den kunstig intelligens kan bruges med for-del pa gennemanalyserede situationer, kan det tilsvarende konkluderes at: Forsituationer, hvor der ikke ligger en grundig analyse, der har afdækket alle ud-faldsrum for en given situation, vil de typer AI som er anvendt i denne opgaveikke fungere. I situationer hvor ’spilbrættet’ ikke er kendt vil der være behov forandre metoder, der kan simulere en anden type intelligens, den type vi i dagligtale kalder intuition.

8.0.1 Fremtidige udviklingsmuligheder:

I fremtidsperspektivet for AlphaBeta AI’en er der mulighed at lave yderligereforbedringer, disse kun komme pa flere fronter, men det bedste resultat villeformentligt komme af kombinationer mellem nye tiltag og gamle fungerendemetoder.Et omrade hvor der kan indføres nogle nye tiltag er heuristikken. Nye heuri-stikker kunne laves, som i stedet for blot at se pa scoren, kan ga ind og se paudvidelsesmulighederne for de største figurer eller ser pa hvor store de tredjestørste figurer er. Det bedste resultat vil nok ikke komme ved at udskifte dennuværende heuristik med en ny, men netop ved at kombinere den nuværendeheuristik med nye, og finde en passende vægtning mellem dem.Vægtningen kunne f.eks. tilpasses ved hjælp af mere avancerede metoder indenfor AI, som simuleret nedkøling eller neurale netværk. Vægtningen vil med dissemetoder kunne tilpasses ud fra erfaringer med at spille spillet, og hvordan disse

93

spil med forskellige vægtninger er endt.

Ses der pa den lidt nærmere fremtid kunne AlphaBeta AI’en forbedres vedhjælp af metoden, der bestemmer hvilke træk der undersøges i Growth AI’en.Dette skulle ske ved at trækkene, som growth nøjes med at undersøge, skulleundersøges først i AlphaBeta AI’en, mens de resterende træk kommer i andenrække. Det er nemlig ret sandsynligt, at de bedste træk befinder sig inden-for de træk growth undersøger. Jo hurtigere AlphaBeta AI’en finder et godttræk jo bedre fungerer alpha-beta pruning, da den derved kan stoppe en langrække undersøgelser pa et tidligere tidspunkt. I praksis vil denne forbedringkunne betyde, at AlphaBeta AI’en kommer til at kunne klare en dybere søgningned i spiltræet. Skulle det hermed lykkedes AlphaBeta AI’en at na den sammesøgedybde, som Growth AI’en leverer, vil AlphaBeta AI’en sandsynligvis ga henog blive et bedre valg, fordi Growth AI’ens begrænsede søgning i vise tilfældeskader kvaliteten af dens resultat.

Forbedringer for Growth AI’en kunne besta i at lade dens træk ga ud fra detre største figurer for hver farve i stedet for blot de to største, som det harværet hidtil. En forbedring af justeringen af søgedybden kunne ogsa hjælpe, danogle træk bliver beregnet sa hurtigt, at det formentligt ville være muligt attage en generation mere med i beregningen i disse tilfælde. Dette vil dog kræveen grundigere analyse af brættilstanden, da det ikke umiddelbart er til at gen-nemskue, i hvilke tilfælde beregningerne er hurtigt overstaet og hvornar de ikkeer.

94 Konklusion

Bilag A

Kildekode

To be added

A.1 AITaijiAlphaBeta.java

1 import java . u t i l . Random ;2 import java . u t i l . ArrayList ;34 pub l i c c l a s s AITaij iAlphaBeta {56 pub l i c Tai j iModel tModel ;7 pub l i c Node tNode ;8 pub 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 .9 pub l i c i n t maxDepth ;

10 p r i v a t e ArrayList<Node > [ ] [ ] nodes ; // indeho lde r a l l e noderne ia r r a y l i s t s e f t e r gene ra t i on og hash vaerd i .

11 p r i v a t e i n t maxD; // den maximale dybde f o r t r a e e t .12 p r i v a t e i n t maxH; // den maximale Hash vaerd i13 p r i v a t e Node Root ; // Traeets rod .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

en maximal soege dybde1516 pub l i c AITaij iAlphaBeta ( Tai j iModel m) {17 t h i s . tModel = m;18 }

96 Bilag A

1920 // i n i t i a l i s e r e r AlphaBeta21 pub l i c void AlphaBeta ( ) {22 tNode = new Node ( ) ;23 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;24 count = 1 ;25 maxD = tModel . maxTurnsLeft ( ) ;26 searchD = maxD;27 maxH = tModel . tHash . getMaxH3 ( ) ;28 nodes = new ArrayList [maxD ] [ maxH+1] ;29 f o r ( i n t i =0; i<maxD; i++){30 f o r ( i n t j =0; j<=maxH; j++)31 nodes [ i ] [ j ] = new ArrayList<Node>() ;32 }33 setMaxDepth (1 ) ; // 0 f o r komplet soegning , 1 f o r dybde

begraense t soegning3435 }36373839 // s a e t t e r soegedybden .40 pub l i c void setSearchDepth ( i n t d) {41 searchD = d ;42 }4344 // s a e t t e r maxDepth e f t e r hvor mange ture der max er t i l b a g e45 p r i v a t e void setMaxDepth ( i n t mode) {46 // i ”Mode 0” f o r s o e g e r den at regne he l e t r a e e t igennem47 i f (mode == 0) {48 maxDepth = ( tModel . noCols∗ tModel . noRows/2) ;49 System . out . p r i n t l n (” AlphaBeta Mode 0 max Depth = ”+

searchD ) ;50 }51 // i ”Mode 1” s a e t t e s max fremregningen e f t e r hvor mange

t raek der er t i l b a g e .52 i f (mode == 1) {53 i n t maxT = tModel . maxTurnsLeft ( ) ;54 i f (maxT >= 10)55 setSearchDepth (2 ) ;56 i f (maxT >= 8 && maxT < 10)57 setSearchDepth (3 ) ;58 i f (maxT > 6 && maxT < 8)59 setSearchDepth (4 ) ;60 i f (maxT <= 6)61 setSearchDepth (maxT) ;62 System . out . p r i n t l n (” AlphaBeta Mode 1 max Depth = ”+

searchD ) ;63 }64 }6566 // checker om der a l l e r e d e er et saadant braet . Returnerer

koord inate rne f o r den Node , hv i s den a l l e r e d e f i n d e s .67 p r i v a t e i n t [ ] checkBoardInd iv idua l i ty ( i n t [ ] [ ] b , i n t d) {68 i n t [ ] p = new i n t [ 3 ] ;

A.1 AITaijiAlphaBeta.java 97

69 i n t h = tModel . tHash . hashFunction3 (b) ;70 p [0 ]= d ;// d ;71 p [1 ]=h ;72 p[2]=−1;73 f o r ( i n t i = 0 ; i<nodes [ d ] [ h ] . s i z e ( ) ; i++){74 i f ( tModel . tBoard . compareBoardsBool (b , nodes [ d ] [ h ] . get (

i ) . nodeBoard ) ) {75 p [2 ]= i ;76 re turn (p) ;77 }78 }79 re turn (p) ;80 }8182 // Max−funkt ionen i minimax−soegningen83 p r i v a t e i n t max(Node n , i n t alpha , i n t beta , i n t ex ) {84 i f (n . d >= searchD | | ! tModel . movesLeftN (n) ) {85 n . a = tModel . fMap . c a l D i f (n . nodeBoard , tModel . noCols ,

tModel . noRows) ;86 re turn (n . a ) ;87 }88 e l s e {89 i f ( ex == 1) {90 i f (n . a >= beta )91 re turn (n . a ) ;92 }93 n . a = −tModel . maxScore ;94 i n t [ ] [ ] b = n . nodeBoard ;95 i n t d = n . d ;96 f o r ( i n t c =0; c < tModel . noCols ; c++){97 f o r ( i n t r =0; r < tModel . noRows−1; r++){98 i f (b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {99 b [ c ] [ r ] = 1 ;

100 b [ c ] [ r +1] = 0 ;101 i n t [ ] p = new i n t [ 3 ] ;102 p = checkBoardInd iv idua l i ty (b , d) ;103 i f (p [ 2 ] >= 0) {104 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;105 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;106 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;107 i f (n . a < v )108 n . a = v ;109 i f (n . a > beta ) {110 b [ c ] [ r ] = 2 ;111 b [ c ] [ r +1] = 2 ;112 re turn (n . a ) ;113 }114 i f ( alpha < n . a )115 alpha = n . a ;116117 }118 i f (p [ 2 ] == −1){119 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;

98 Bilag A

120 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .createChi ldNode ( c , r , c , r +1, n) ) ) ;

121 count++;122 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;123 i f (n . a < v )124 n . a = v ;125 i f (n . a > beta ) {126 b [ c ] [ r ] = 2 ;127 b [ c ] [ r +1] = 2 ;128 re turn (n . a ) ;129 }130 i f ( alpha < n . a )131 alpha = n . a ;132133 }134 b [ c ] [ r ] = 0 ;135 b [ c ] [ r +1] = 1 ;136 p = checkBoardInd iv idua l i ty (b , d) ;137 i f (p [ 2 ] >= 0) {138 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;139 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;140 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;141 i f (n . a < v )142 n . a = v ;143 i f (n . a > beta ) {144 b [ c ] [ r ] = 2 ;145 b [ c ] [ r +1] = 2 ;146 re turn (n . a ) ;147 }148 i f ( alpha < n . a )149 alpha = n . a ;150 }151 i f (p [ 2 ] == −1){152 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;153 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , n ) ) ) ;154 count++;155 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;156 i f (n . a < v )157 n . a = v ;158 i f (n . a > beta ) {159 b [ c ] [ r ] = 2 ;160 b [ c ] [ r +1] = 2 ;161 re turn (n . a ) ;162 }163 i f ( alpha < n . a )164 alpha = n . a ;165 }166167 b [ c ] [ r ] = 2 ;168 b [ c ] [ r +1] = 2 ;

A.1 AITaijiAlphaBeta.java 99

169 }170 }171 }172173 f o r ( i n t c=0; c < tModel . noCols−1; c++){174 f o r ( i n t r =0; r < tModel . noRows ; r++){175 i f (b [ c ] [ r ] == 2 && b [ c +1] [ r ] == 2 ) {176 b [ c ] [ r ] = 1 ;177 b [ c +1] [ r ] = 0 ;178 i n t [ ] p = new i n t [ 3 ] ;179 p = checkBoardInd iv idua l i ty (b , d) ;180 i f (p [ 2 ] >= 0) {181 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;182 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;183 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;184 i f (n . a < v )185 n . a = v ;186 i f (n . a > beta ) {187 b [ c ] [ r ] = 2 ;188 b [ c +1] [ r ] = 2 ;189 re turn (n . a ) ;190 }191 i f ( alpha < n . a )192 alpha = n . a ;193 }194 i f (p [ 2 ] == −1){195 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;196 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c+1, r , n ) ) ) ;197 count++;198 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;199 i f (n . a < v )200 n . a = v ;201 i f (n . a > beta ) {202 b [ c ] [ r ] = 2 ;203 b [ c +1] [ r ] = 2 ;204 re turn (n . a ) ;205 }206 i f ( alpha < n . a )207 alpha = n . a ;208 }209 b [ c ] [ r ] = 0 ;210 b [ c +1] [ r ] = 1 ;211 p = checkBoardInd iv idua l i ty (b , d) ;212 i f (p [ 2 ] >= 0) {213 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;214 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;215 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;216 i f (n . a < v )217 n . a = v ;

100 Bilag A

218 i f (n . a > beta ) {219 b [ c ] [ r ] = 2 ;220 b [ c +1] [ r ] = 2 ;221 re turn (n . a ) ;222 }223 i f ( alpha < n . a )224 alpha = n . a ;225 }226 i f (p [ 2 ] == −1){227 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;228 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , n ) ) ) ;229 count++;230 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;231 i f (n . a < v )232 n . a = v ;233 i f (n . a > beta ) {234 b [ c ] [ r ] = 2 ;235 b [ c +1] [ r ] = 2 ;236 re turn (n . a ) ;237 }238 i f ( alpha < n . a )239 alpha = n . a ;240 }241 b [ c ] [ r ] = 2 ;242 b [ c +1] [ r ] = 2 ;243 }244 }245 }246 re turn (n . a ) ;247 }248 }249250 // Min−funkt ionen i minimax−soegningen251 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 ) {252 i f (n . d >= searchD | | ! tModel . movesLeftN (n) ) {253 n . a = tModel . fMap . c a l D i f (n . nodeBoard , tModel . noCols ,

tModel . noRows) ;254 re turn (n . a ) ;255 }256 e l s e {257 i f ( ex == 1) {258 i f (n . a <= alpha )259 re turn (n . a ) ;260 }261 n . a = tModel . maxScore ;262 i n t [ ] [ ] b = n . nodeBoard ;263 i n t d = n . d ;264 f o r ( i n t c=0; c < tModel . noCols ; c++){265 f o r ( i n t r =0; r < tModel . noRows−1; r++){266 i f (b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {267 b [ c ] [ r ] = 1 ;268 b [ c ] [ r +1] = 0 ;269 i n t [ ] p = new i n t [ 3 ] ;

A.1 AITaijiAlphaBeta.java 101

270 p = checkBoardInd iv idua l i ty (b , d) ;271 i f (p [ 2 ] >= 0) {272 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;273 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;274 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;275 i f (n . a > v )276 n . a = v ;277 i f (n . a < alpha ) {278 b [ c ] [ r ] = 2 ;279 b [ c ] [ r +1] = 2 ;280 re turn (n . a ) ;281 }282 i f ( beta > n . a )283 beta = n . a ;284 }285 i f (p [ 2 ] == −1){286 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;287 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c , r +1, n) ) ) ;288 count++;289 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;290 i f (n . a > v )291 n . a = v ;292 i f (n . a < alpha ) {293 b [ c ] [ r ] = 2 ;294 b [ c ] [ r +1] = 2 ;295 re turn (n . a ) ;296 }297 i f ( beta > n . a )298 beta = n . a ;299 }300 b [ c ] [ r ] = 0 ;301 b [ c ] [ r +1] = 1 ;302303 p = checkBoardInd iv idua l i ty (b , d) ;304 i f (p [ 2 ] >= 0) {305 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;306 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;307 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;308 i f (n . a > v )309 n . a = v ;310 i f (n . a < alpha ) {311 b [ c ] [ r ] = 2 ;312 b [ c ] [ r +1] = 2 ;313 re turn (n . a ) ;314 }315 i f ( beta > n . a )316 beta = n . a ;317 }318 i f (p [ 2 ] == −1){

102 Bilag A

319 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;320 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , n ) ) ) ;321 count++;322 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;323 i f (n . a > v )324 n . a = v ;325 i f (n . a < alpha ) {326 b [ c ] [ r ] = 2 ;327 b [ c ] [ r +1] = 2 ;328 re turn (n . a ) ;329 }330 i f ( beta > n . a )331 beta = n . a ;332 }333 b [ c ] [ r ] = 2 ;334 b [ c ] [ r +1] = 2 ;335336337 }338 }339 }340341342 f o r ( i n t c=0; c < tModel . noCols−1; c++){343 f o r ( i n t r =0; r < tModel . noRows ; r++){344 i f (b [ c ] [ r ] == 2 && b [ c +1] [ r ] == 2 ) {345 b [ c ] [ r ] = 1 ;346 b [ c +1] [ r ] = 0 ;347 i n t [ ] p = new i n t [ 3 ] ;348 p = checkBoardInd iv idua l i ty (b , d) ;349 i f (p [ 2 ] >= 0) {350 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;351 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;352 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;353 i f (n . a > v )354 n . a = v ;355 i f (n . a < alpha ) {356 b [ c ] [ r ] = 2 ;357 b [ c +1] [ r ] = 2 ;358 re turn (n . a ) ;359 }360 i f ( beta > n . a )361 beta = n . a ;362 }363 i f (p [ 2 ] == −1){364 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;365 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c+1, r , n ) ) ) ;366 count++;367 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;

A.1 AITaijiAlphaBeta.java 103

368 i f (n . a > v )369 n . a = v ;370 i f (n . a < alpha ) {371 b [ c ] [ r ] = 2 ;372 b [ c +1] [ r ] = 2 ;373 re turn (n . a ) ;374 }375 i f ( beta > n . a )376 beta = n . a ;377 }378 b [ c ] [ r ] = 0 ;379 b [ c +1] [ r ] = 1 ;380381 p = checkBoardInd iv idua l i ty (b , d) ;382 i f (p [ 2 ] >= 0) {383 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;384 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;385 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;386 i f (n . a > v )387 n . a = v ;388 i f (n . a < alpha ) {389 b [ c ] [ r ] = 2 ;390 b [ c +1] [ r ] = 2 ;391 re turn (n . a ) ;392 }393 i f ( beta > n . a )394 beta = n . a ;395 }396 i f (p [ 2 ] == −1){397 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;398 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , n ) ) ) ;399 count++;400 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;401 i f (n . a > v )402 n . a = v ;403 i f (n . a < alpha ) {404 b [ c ] [ r ] = 2 ;405 b [ c +1] [ r ] = 2 ;406 re turn (n . a ) ;407 }408 i f ( beta > n . a )409 beta = n . a ;410 }411 b [ c ] [ r ] = 2 ;412 b [ c +1] [ r ] = 2 ;413 }414 }415 }416 re turn (n . a ) ;417 }418 }

104 Bilag A

419420421422423424425 // s a e t t e r scoren f o r en node t i l −’ uende l ig ’426 p r i v a t e Node setScoreMin (Node n) {427 n . a = −tModel . maxScore ;428 re turn (n) ;429 }430 // s a e t t e r scoren f o r en node t i l ” uende l i g ”431 p r i v a t e Node setScoreMax (Node n) {432 n . a = tModel . maxScore ;433 re turn (n) ;434 }435436 // udsk r i v e r vae rd i e rne paa f o r a e l d r e n e t i l en Node437 p r i v a t e void pr intParScore (Node n) {438 System . out . p r i n t (”AB pr intParScore d=”+n . d+” n . par s c o r e s :

”) ;439 f o r ( i n t i =0; i<n . par . s i z e ( ) ; i++){440 System . out . p r i n t (n . par . get ( i ) . a+” ”) ;441 }442 System . out . p r i n t l n (” end n . a=”+n . a ) ;443 }444445446 // s t a r t e s f r a Tai j iModel . S tyre r AlphaBeta AI ’ en og r e tu rne r

det fundne t raekke t447 pub l i c Node returnMove ( boolean b) {448 AlphaBeta ( ) ;449450 i f (b)451 min ( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;452 i f ( ! b )453 max( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;454455 Random randomVal = new Random( ) ;456 Node n ;457 ArrayList<Node> move = new ArrayList<Node>() ;458 i n t wC,wR, bC,bR, ran ;459 n = Root . c h i l d r e n . get (0 ) ;460 // tModel . tPr in t . printNode ( Root ) ;461 // tModel . tPr in t . p r in tCh i ld r en ( Root ) ;462 System . out . p r i n t l n (”AB anta l noder i a l t = ”+count ) ; //

udsk r i v e r hvor mange Node der b lev l a v e t i a l t undersoegningen

463 //System . out . p r i n t l n (”AB − r e turn move Root . s i z e=”+Root .c h i l d r e n . s i z e ( ) ) ;

464 i f ( Root . c h i l d r e n . s i z e ( ) > 1) {465 i f (b) {466 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ //

Finder bedste vae rd i467 i f (n . a>Root . c h i l d r e n . get ( i ) . a ) {

A.1 AITaijiAlphaBeta.java 105

468 n=Root . c h i l d r e n . get ( i ) ;469 }470 }471 }472 i f ( ! b ) {473 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ //

Finder bedste vae rd i474 i f (n . a<Root . c h i l d r e n . get ( i ) . a ) {475 n=Root . c h i l d r e n . get ( i ) ;476 }477 }478 }479 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ // Finder

a l l e t raek med bedste vae rd i480 i f (n . a==Root . c h i l d r e n . get ( i ) . a ) {481 move . add ( Root . c h i l d r e n . get ( i ) ) ;482 }483 }484 ran = randomVal . next Int (move . s i z e ( ) ) ; // v a e l g e r

t i l f a e l d i g t mellem de l i g e gode t raek .485 n = move . get ( ran ) ;486 }487488 System . out . p r i n t l n (”AB Move coord”+n . wc+” ”+n . wr+” ”+n . bc+”

”+n . br ) ;489 wC = n . wc ;490 wR = n . wr ;491 bC = n . bc ;492 bR = n . br ;493 n . nodeBoard [wC] [wR]=2;494 n . nodeBoard [bC ] [ bR]=2;495 // tModel . tPr in t . printNode (n) ;496497 // vender det va l g t e t raek saa det matcher s p i l l e t s

igangvaerende braet .498 i n t mr = tModel . tBoard . compareBoardsInt (n . nodeBoard , tModel

. tBoard . board [ tModel . currentTurn ] ) ;499 System . out . p r i n t l n (”AB − Return move mr=”+mr) ;500 i f (mr == 1) {501 re turn (n) ;502 }503 i f (mr == 2) {504 n . br = tModel . noRows−1 − bR;505 n . wr = tModel . noRows−1 − wR;506 re turn (n) ;507 }508 i f (mr == 3) {509 n . bc = tModel . noCols−1 − bC;510 n . wc = tModel . noCols−1 − wC;511 re turn (n) ;512 }513 i f (mr == 4) {514 n . bc = tModel . noCols−1 − bC;515 n . wc = tModel . noCols−1 − wC;516 n . br = tModel . noRows−1 − bR;

106 Bilag A

517 n . wr = tModel . noRows−1 − wR;518 re turn (n) ;519 }520 i f (mr == 5) {521 n . bc = bR;522 n . wc = wR;523 n . br = bC;524 n . wr = wC;525 re turn (n) ;526 }527 i f (mr == 6) {528 n . bc = tModel . noRows−1 − bR;529 n . wc = tModel . noRows−1 − wR;530 n . br = bC;531 n . wr = wC;532 re turn (n) ;533 }534 i f (mr == 7) {535 n . bc = bR;536 n . wc = wR;537 n . br = tModel . noCols−1 − bC;538 n . wr = tModel . noCols−1 − wC;539 re turn (n) ;540 }541 i f (mr == 8) {542 n . bc = tModel . noRows−1 − bR;543 n . wc = tModel . noRows−1 − wR;544 n . br = tModel . noCols−1 − bC;545 n . wr = tModel . noCols−1 − wC;546 re turn (n) ;547 }548 re turn (n) ;549 }550551552 }

A.2 AITaijiGrowth.java

1 import java . u t i l . Random ;2 import java . u t i l . ArrayList ;34 pub l i c c l a s s AITaijiGrowth {56 pub l i c Tai j iModel tModel ;7 pub l i c Node tNode ;8 pub 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 .9 pub l i c i n t maxDepth ;

10 p r i v a t e ArrayList<Node > [ ] [ ] nodes ; // indeho lde r a l l e noderne ia r r a y l i s t s e f t e r gene ra t i on og hash vaerd i .

11 p r i v a t e i n t maxD; // den maximale dybde f o r t r a e e t .12 p r i v a t e i n t maxH; // den maximale Hash vaerd i13 p r i v a t e Node Root ; // Traeets rod .

A.2 AITaijiGrowth.java 107

14 p r i v a t e i n t searchD ; // Search depth , muligheden f o r at s a e t t een maximal soege dybde

1516 pub l i c AITaijiGrowth ( Tai j iModel m) {17 t h i s . tModel = m;18 }1920 pub l i c void Growth ( ) {21 tNode = new Node ( ) ;22 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;23 count = 1 ;24 maxD = tModel . maxTurnsLeft ( ) ; // max dybden s p i l g r a f e n kan

opnaa f i n d e s25 searchD = maxD; // soegedybden s a e t t e s som udgangspunkt t i l

at gaa h e l t i bund26 maxH = tModel . tHash . getMaxH3 ( ) ; //maxH s a e t t e s udfra

hv i lken hashfunkt ion der anvendes27 nodes = new ArrayList [maxD ] [ maxH+1] ;28 f o r ( i n t i =0; i<maxD; i++){29 f o r ( i n t j =0; j<=maxH; j++)30 nodes [ i ] [ j ] = new ArrayList<Node>() ;31 }32 setMaxDepth (1 ) ;33 }343536 // s a e t t e r soege dybden37 pub l i c void setSearchDepth ( i n t d) {38 searchD = d ;39 }4041 // her bestemmes og s a e a e t e s soegedybden udfra anta l a f

t i l bagevae r ende t raek42 p r i v a t e void setMaxDepth ( i n t mode) {43 // i ”Mode 0” f o r s o e g e r den at regne he l e t r a e e t igennem44 i f (mode == 0) {45 maxDepth = ( tModel . noCols∗ tModel . noRows/2) ;46 System . out . p r i n t l n (” Growth Depth Mode 0 max Depth =

”+searchD ) ;47 }48 // i ”Mode 1” s a e t t e s max fremregningen t i l 2 , hv i s der er

mere en 5 traek t i l b a g e ,49 // e l l e r s regner den h e l t igennem .50 i f (mode == 1) {51 i n t maxT = tModel . maxTurnsLeft ( ) ;52 i f (maxT > 10)53 setSearchDepth (3 ) ;54 i f (maxT > 7 && maxT <= 10)55 setSearchDepth (4 ) ;56 i f (maxT > 6 && maxT <= 7)57 setSearchDepth (5 ) ;58 i f (maxT <= 6)59 setSearchDepth (maxT) ;60 System . out . p r i n t l n (” Growth Depth Mode 1 max Depth =

”+searchD ) ;

108 Bilag A

61 }62 }6364 // checker om der a l l e r e d e er et saadant braet . Returnerer

co rd ina t e rne f o r den node , hv i s der er .65 p r i v a t e i n t [ ] checkBoardInd iv idua l i ty ( i n t [ ] [ ] b , i n t d) {66 i n t [ ] p = new i n t [ 3 ] ;67 i n t h = tModel . tHash . hashFunction3 (b) ;68 p [0 ]=d ;69 p [1 ]=h ;70 p[2]=−1;71 f o r ( i n t i = 0 ; i<nodes [ d ] [ h ] . s i z e ( ) ; i++){72 i f ( tModel . tBoard . compareBoardsBool (b , nodes [ d ] [ h ] . get (

i ) . nodeBoard ) ) {73 p [2 ]= i ;74 re turn (p) ;75 }76 }77 re turn (p) ;78 }7980 // Max−funkt ionen81 p r i v a t e i n t max(Node n , i n t alpha , i n t beta , i n t ex ) {82 i f (n . d >= searchD | | ! tModel . movesLeftN (n) ) {83 n . a = tModel . fMap . c a l D i f (n . nodeBoard , tModel . noCols ,

tModel . noRows) ;84 re turn (n . a ) ;85 }86 e l s e {87 i f ( ex == 1) {88 i f (n . a >= beta )89 re turn (n . a ) ;90 }91 n . a = −tModel . maxScore ;92 i n t [ ] [ ] b = n . nodeBoard ;93 i n t [ ] [ ] fb = new i n t [ tModel . noCols ] [ tModel . noRows ] ;94 i n t d = n . d ;95 i n t [ ] [ ] [ ] f i g s ;969798 fb = tModel . fMap . getFigBoard (n . nodeBoard , tModel . noCols

, tModel . noRows) ;99 f i g s = tModel . fMap . ge tF ig s ( fb ) ;

100101 i f ( f a l s e ) { // s a e t t e s t i l t rue f o r at p r i n t e f igBoard

og h v i l k e f i g u r e , der er s t o e r s t med f r i e p l ad s e romkring s i g . T i l t e s t brug

102 System . out . p r i n t l n (” growth f i g s W: ”+ f i g s[ 1 ] [ 0 ] [ 0 ] + ” & ”+ f i g s [ 1 ] [ 1 ] [ 0 ] + ” B: ”+ f i g s[ 0 ] [ 0 ] [ 0 ] + ” & ”+ f i g s [ 0 ] [ 1 ] [ 0 ] ) ;

103 printFB ( fb ) ;104 }105106107

A.2 AITaijiGrowth.java 109

108 f o r ( i n t c=0; c < tModel . noCols ; c++){109 f o r ( i n t r =0; r < tModel . noRows ; r++){110 i f ( fb [ c ] [ r ] == f i g s [ 1 ] [ 0 ] [ 0 ] | | fb [ c ] [ r ] ==

f i g s [ 1 ] [ 1 ] [ 0 ] | | fb [ c ] [ r ] == f i g s [ 0 ] [ 0 ] [ 0 ]| | fb [ c ] [ r ] == f i g s [ 0 ] [ 1 ] [ 0 ] ) {

111 // oe s t112 i f ( c < tModel . noCols−1){113 i f ( fb [ c +1] [ r ] == 0) {114 i f ( r < tModel . noRows−1){115 i f ( fb [ c +1] [ r +1] == 0) {116 i n t [ ] r e ;117 b [ c +1] [ r ] = 1 ;118 b [ c +1] [ r +1] = 0 ;119 re = placePieceMax (b , d , n ,

c+1, r , c+1, r +1,alpha , beta ) ;

120 alpha = re [ 1 ] ;121 beta = re [ 2 ] ;122 i f ( re [ 0 ] == 1) {123 b [ c +1] [ r ] = 2 ;124 b [ c +1] [ r +1] = 2 ;125 re turn ( re [ 3 ] ) ;126 }127 b [ c +1] [ r ] = 0 ;128 b [ c +1] [ r +1] = 1 ;129 re = placePieceMax (b , d , n ,

c+1, r +1, c+1, r ,alpha , beta ) ;

130 alpha = re [ 1 ] ;131 beta = re [ 2 ] ;132 i f ( re [ 0 ] == 1) {133 b [ c +1] [ r ] = 2 ;134 b [ c +1] [ r +1] = 2 ;135 re turn ( re [ 3 ] ) ;136 }137 b [ c +1] [ r ] = 2 ;138 b [ c +1] [ r +1] = 2 ;139 }140 }141 i f ( r > 0) {142 i f ( fb [ c +1] [ r−1] == 0) {143 i n t [ ] r e ;144 b [ c +1] [ r ] = 1 ;145 b [ c +1] [ r−1] = 0 ;146 re = placePieceMax (b , d , n ,

c+1, r , c+1, r−1,alpha , beta ) ;

147 alpha = re [ 1 ] ;148 beta = re [ 2 ] ;149 i f ( re [ 0 ] == 1) {150 b [ c +1] [ r ] = 2 ;151 b [ c +1] [ r−1] = 2 ;152 re turn ( re [ 3 ] ) ;153 }154 b [ c +1] [ r ] = 0 ;

110 Bilag A

155 b [ c +1] [ r−1] = 1 ;156 re = placePieceMax (b , d , n ,

c+1, r−1, c+1, r ,alpha , beta ) ;

157 alpha = re [ 1 ] ;158 beta = re [ 2 ] ;159 i f ( re [ 0 ] == 1) {160 b [ c +1] [ r ] = 2 ;161 b [ c +1] [ r−1] = 2 ;162 re turn ( re [ 3 ] ) ;163 }164 b [ c +1] [ r ] = 2 ;165 b [ c +1] [ r−1] = 2 ;166 }167 }168 i f ( c < tModel . noCols−2){169 i f ( fb [ c +2] [ r ] == 0) {170 i n t [ ] r e ;171 b [ c +1] [ r ] = 1 ;172 b [ c +2] [ r ] = 0 ;173 re = placePieceMax (b , d , n ,

c+1, r , c+2, r , alpha ,beta ) ;

174 alpha = re [ 1 ] ;175 beta = re [ 2 ] ;176 i f ( re [ 0 ] == 1) {177 b [ c +1] [ r ] = 2 ;178 b [ c +2] [ r ] = 2 ;179 re turn ( re [ 3 ] ) ;180 }181 b [ c +1] [ r ] = 0 ;182 b [ c +2] [ r ] = 1 ;183 re = placePieceMax (b , d , n ,

c+2, r , c+1, r , alpha ,beta ) ;

184 alpha = re [ 1 ] ;185 beta = re [ 2 ] ;186 i f ( re [ 0 ] == 1) {187 b [ c +1] [ r ] = 2 ;188 b [ c +2] [ r ] = 2 ;189 re turn ( re [ 3 ] ) ;190 }191 b [ c +1] [ r ] = 2 ;192 b [ c +2] [ r ] = 2 ;193 }194 }195 }196 }197 // ves t198 i f ( c > 0) {199 i f ( fb [ c−1] [ r ] == 0) {200 i f ( r < tModel . noRows−1){201 i f ( fb [ c−1] [ r +1] == 0) {202 i n t [ ] r e ;203 b [ c−1] [ r ] = 1 ;

A.2 AITaijiGrowth.java 111

204 b [ c−1] [ r +1] = 0 ;205 re = placePieceMax (b , d , n ,

c−1, r , c−1, r +1,alpha , beta ) ;

206 alpha = re [ 1 ] ;207 beta = re [ 2 ] ;208 i f ( re [ 0 ] == 1) {209 b [ c−1] [ r ] = 2 ;210 b [ c−1] [ r +1] = 2 ;211 re turn ( re [ 3 ] ) ;212 }213 b [ c−1] [ r ] = 0 ;214 b [ c−1] [ r +1] = 1 ;215 re = placePieceMax (b , d , n ,

c−1, r +1, c−1, r ,alpha , beta ) ;

216 alpha = re [ 1 ] ;217 beta = re [ 2 ] ;218 i f ( re [ 0 ] == 1) {219 b [ c−1] [ r ] = 2 ;220 b [ c−1] [ r +1] = 2 ;221 re turn ( re [ 3 ] ) ;222 }223 b [ c−1] [ r ] = 2 ;224 b [ c−1] [ r +1] = 2 ;225 }226 }227 i f ( r > 0) {228 i f ( fb [ c−1] [ r−1] == 0) {229 i n t [ ] r e ;230 b [ c−1] [ r ] = 1 ;231 b [ c−1] [ r−1] = 0 ;232 re = placePieceMax (b , d , n ,

c−1, r , c−1, r−1,alpha , beta ) ;

233 alpha = re [ 1 ] ;234 beta = re [ 2 ] ;235 i f ( re [ 0 ] == 1) {236 b [ c−1] [ r ] = 2 ;237 b [ c−1] [ r−1] = 2 ;238 re turn ( re [ 3 ] ) ;239 }240 b [ c−1] [ r ] = 0 ;241 b [ c−1] [ r−1] = 1 ;242 re = placePieceMax (b , d , n ,

c−1, r−1, c−1, r ,alpha , beta ) ;

243 alpha = re [ 1 ] ;244 beta = re [ 2 ] ;245 i f ( re [ 0 ] == 1) {246 b [ c−1] [ r ] = 2 ;247 b [ c−1] [ r−1] = 2 ;248 re turn ( re [ 3 ] ) ;249 }250 b [ c−1] [ r ] = 2 ;

112 Bilag A

251 b [ c−1] [ r−1] = 2 ;252 }253 }254 i f ( c > 1) {255 i f ( fb [ c−2] [ r ] == 0) {256 i n t [ ] r e ;257 b [ c−1] [ r ] = 1 ;258 b [ c−2] [ r ] = 0 ;259 re = placePieceMax (b , d , n ,

c−1, r , c−2, r , alpha ,beta ) ;

260 alpha = re [ 1 ] ;261 beta = re [ 2 ] ;262 i f ( re [ 0 ] == 1) {263 b [ c−1] [ r ] = 2 ;264 b [ c−2] [ r ] = 2 ;265 re turn ( re [ 3 ] ) ;266 }267 b [ c−1] [ r ] = 0 ;268 b [ c−2] [ r ] = 1 ;269 re = placePieceMax (b , d , n ,

c−2, r , c−1, r , alpha ,beta ) ;

270 alpha = re [ 1 ] ;271 beta = re [ 2 ] ;272 i f ( re [ 0 ] == 1) {273 b [ c−1] [ r ] = 2 ;274 b [ c−2] [ r ] = 2 ;275 re turn ( re [ 3 ] ) ;276 }277 b [ c−1] [ r ] = 2 ;278 b [ c−2] [ r ] = 2 ;279 }280 }281 }282 }283 //System . out . p r i n t l n (” Growth count so f a r

”+count+” d=”+n . d) ;284 // printFB ( fb ) ;285 // syd286 i f ( r < tModel . noRows−1){287 i f ( fb [ c ] [ r +1] == 0) {288 i f ( c < tModel . noCols−1){289 i f ( fb [ c +1] [ r +1] == 0) {290 i n t [ ] r e ;291 b [ c ] [ r +1] = 1 ;292 b [ c +1] [ r +1] = 0 ;293 re = placePieceMax (b , d , n ,

c , r +1, c+1, r +1,alpha , beta ) ;

294 alpha = re [ 1 ] ;295 beta = re [ 2 ] ;296 i f ( re [ 0 ] == 1) {297 b [ c ] [ r +1] = 2 ;298 b [ c +1] [ r +1] = 2 ;

A.2 AITaijiGrowth.java 113

299 re turn ( re [ 3 ] ) ;300 }301 b [ c ] [ r +1] = 0 ;302 b [ c +1] [ r +1] = 1 ;303 re = placePieceMax (b , d , n ,

c+1, r +1, c , r +1,alpha , beta ) ;

304 alpha = re [ 1 ] ;305 beta = re [ 2 ] ;306 i f ( re [ 0 ] == 1) {307 b [ c ] [ r +1] = 2 ;308 b [ c +1] [ r +1] = 2 ;309 re turn ( re [ 3 ] ) ;310 }311 b [ c ] [ r +1] = 2 ;312 b [ c +1] [ r +1] = 2 ;313 }314 }315 i f ( c > 0) {316 i f ( fb [ c−1] [ r +1] == 0) {317 i n t [ ] r e ;318 b [ c ] [ r +1] = 1 ;319 b [ c−1] [ r +1] = 0 ;320 re = placePieceMax (b , d , n ,

c , r +1, c−1, r +1,alpha , beta ) ;

321 alpha = re [ 1 ] ;322 beta = re [ 2 ] ;323 i f ( re [ 0 ] == 1) {324 b [ c ] [ r +1] = 2 ;325 b [ c−1] [ r +1] = 2 ;326 re turn ( re [ 3 ] ) ;327 }328 b [ c ] [ r +1] = 0 ;329 b [ c−1] [ r +1] = 1 ;330 re = placePieceMax (b , d , n ,

c−1, r +1, c , r +1,alpha , beta ) ;

331 alpha = re [ 1 ] ;332 beta = re [ 2 ] ;333 i f ( re [ 0 ] == 1) {334 b [ c ] [ r +1] = 2 ;335 b [ c−1] [ r +1] = 2 ;336 re turn ( re [ 3 ] ) ;337 }338 b [ c ] [ r +1] = 2 ;339 b [ c−1] [ r +1] = 2 ;340 }341 }342 i f ( r < tModel . noRows−2){343 i f ( fb [ c ] [ r +2] == 0) {344 i n t [ ] r e ;345 b [ c ] [ r +1] = 1 ;346 b [ c ] [ r +2] = 0 ;

114 Bilag A

347 re = placePieceMax (b , d , n ,c , r +1, c , r +2, alpha ,beta ) ;

348 alpha = re [ 1 ] ;349 beta = re [ 2 ] ;350 i f ( re [ 0 ] == 1) {351 b [ c ] [ r +1] = 2 ;352 b [ c ] [ r +2] = 2 ;353 re turn ( re [ 3 ] ) ;354 }355 b [ c ] [ r +1] = 0 ;356 b [ c ] [ r +2] = 1 ;357 re = placePieceMax (b , d , n ,

c , r +2, c , r +1, alpha ,beta ) ;

358 alpha = re [ 1 ] ;359 beta = re [ 2 ] ;360 i f ( re [ 0 ] == 1) {361 b [ c ] [ r +1] = 2 ;362 b [ c ] [ r +2] = 2 ;363 re turn ( re [ 3 ] ) ;364 }365 b [ c ] [ r +1] = 2 ;366 b [ c ] [ r +2] = 2 ;367 }368 }369 }370 }371 // Nord372 i f ( r > 0) {373 i f ( fb [ c ] [ r−1] == 0) {374 i f ( c > 0) {375 i f ( fb [ c−1] [ r−1] == 0) {376 i n t [ ] r e ;377 b [ c ] [ r−1] = 1 ;378 b [ c−1] [ r−1] = 0 ;379 re = placePieceMax (b , d , n ,

c , r−1, c−1, r−1,alpha , beta ) ;

380 alpha = re [ 1 ] ;381 beta = re [ 2 ] ;382 i f ( re [ 0 ] == 1) {383 b [ c ] [ r−1] = 2 ;384 b [ c−1] [ r−1] = 2 ;385 re turn ( re [ 3 ] ) ;386 }387 b [ c ] [ r−1] = 0 ;388 b [ c−1] [ r−1] = 1 ;389 re = placePieceMax (b , d , n ,

c−1, r−1, c , r−1,alpha , beta ) ;

390 alpha = re [ 1 ] ;391 beta = re [ 2 ] ;392 i f ( re [ 0 ] == 1) {393 b [ c ] [ r−1] = 2 ;

A.2 AITaijiGrowth.java 115

394 b [ c−1] [ r−1] = 2 ;395 re turn ( re [ 3 ] ) ;396 }397 b [ c ] [ r−1] = 2 ;398 b [ c−1] [ r−1] = 2 ;399 }400 }401 i f ( c < tModel . noCols−1){402 i f ( fb [ c +1] [ r−1] == 0) {403 i n t [ ] r e ;404 b [ c ] [ r−1] = 1 ;405 b [ c +1] [ r−1] = 0 ;406 re = placePieceMax (b , d , n ,

c , r−1, c+1, r−1,alpha , beta ) ;

407 alpha = re [ 1 ] ;408 beta = re [ 2 ] ;409 i f ( re [ 0 ] == 1) {410 b [ c ] [ r−1] = 2 ;411 b [ c +1] [ r−1] = 2 ;412 re turn ( re [ 3 ] ) ;413 }414 b [ c ] [ r−1] = 0 ;415 b [ c +1] [ r−1] = 1 ;416 re = placePieceMax (b , d , n ,

c+1, r−1, c , r−1,alpha , beta ) ;

417 alpha = re [ 1 ] ;418 beta = re [ 2 ] ;419 i f ( re [ 0 ] == 1) {420 b [ c ] [ r−1] = 2 ;421 b [ c +1] [ r−1] = 2 ;422 re turn ( re [ 3 ] ) ;423 }424 b [ c ] [ r−1] = 2 ;425 b [ c +1] [ r−1] = 2 ;426 }427 }428 i f ( r > 1) {429 i f ( fb [ c ] [ r−2] == 0) {430 i n t [ ] r e ;431 b [ c ] [ r−1] = 1 ;432 b [ c ] [ r−2] = 0 ;433 re = placePieceMax (b , d , n ,

c , r−1, c , r−2, alpha ,beta ) ;

434 alpha = re [ 1 ] ;435 beta = re [ 2 ] ;436 i f ( re [ 0 ] == 1) {437 b [ c ] [ r−1] = 2 ;438 b [ c ] [ r−2] = 2 ;439 re turn ( re [ 3 ] ) ;440 }441 b [ c ] [ r−1] = 0 ;442 b [ c ] [ r−2] = 1 ;

116 Bilag A

443 re = placePieceMax (b , d , n ,c , r−2, c , r−1, alpha ,beta ) ;

444 alpha = re [ 1 ] ;445 beta = re [ 2 ] ;446 i f ( re [ 0 ] == 1) {447 b [ c ] [ r−1] = 2 ;448 b [ c ] [ r−2] = 2 ;449 re turn ( re [ 3 ] ) ;450 }451 b [ c ] [ r−1] = 2 ;452 b [ c ] [ r−2] = 2 ;453 }454 }455 }456 }457 }458 }459 }460 re turn (n . a ) ;461 }462 }463464 //Min−funkt ionen465 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 ) {466 //System . out . p r i n t l n (” Growth − Min”) ;467 i f (n . d >= searchD | | ! tModel . movesLeftN (n) ) {468 n . a = tModel . fMap . c a l D i f (n . nodeBoard , tModel . noCols ,

tModel . noRows) ;469 re turn (n . a ) ;470 }471 e l s e {472 i f ( ex == 1) {473 i f (n . a <= alpha )474 re turn (n . a ) ;475 }476 n . a = tModel . maxScore ;477 i n t [ ] [ ] b = n . nodeBoard ;478 i n t d = n . d ;479 i n t [ ] [ ] fb = new i n t [ tModel . noCols ] [ tModel . noRows ] ;480 i n t [ ] [ ] [ ] f i g s ;481482 fb = tModel . fMap . getFigBoard (n . nodeBoard , tModel . noCols

, tModel . noRows) ;483 f i g s = tModel . fMap . ge tF ig s ( fb ) ;484 i f ( f a l s e ) { // s a e t t e s t i l t rue f o r at p r i n t e f igBoard

og h v i l k e f i g u r e , der er s t o e r s t med f r i e p l ad s e romkring s i g . T i l t e s t brug

485 System . out . p r i n t l n (” growth f i g s W: ”+ f i g s[ 1 ] [ 0 ] [ 0 ] + ” & ”+ f i g s [ 1 ] [ 1 ] [ 0 ] + ” B: ”+ f i g s[ 0 ] [ 0 ] [ 0 ] + ” & ”+ f i g s [ 0 ] [ 1 ] [ 0 ] ) ;

486 printFB ( fb ) ;487 }488489 f o r ( i n t c =0; c < tModel . noCols ; c++){

A.2 AITaijiGrowth.java 117

490 f o r ( i n t r =0; r < tModel . noRows ; r++){491 i f ( fb [ c ] [ r ] == f i g s [ 1 ] [ 0 ] [ 0 ] | | fb [ c ] [ r ] ==

f i g s [ 1 ] [ 1 ] [ 0 ] | | fb [ c ] [ r ] == f i g s [ 0 ] [ 0 ] [ 0 ]| | fb [ c ] [ r ] == f i g s [ 0 ] [ 1 ] [ 0 ] ) {

492 // oe s t493 i f ( c < tModel . noCols−1){494 i f ( fb [ c +1] [ r ] == 0) {495 i f ( r < tModel . noRows−1){496 i f ( fb [ c +1] [ r +1] == 0) {497 i f (n . a==0) ;498 i n t [ ] r e ;499 b [ c +1] [ r ] = 1 ;500 b [ c +1] [ r +1] = 0 ;501 re = placePieceMin (b , d , n ,

c+1, r , c+1, r +1,alpha , beta ) ;

502 alpha = re [ 1 ] ;503 beta = re [ 2 ] ;504 i f ( re [ 0 ] == 1) {505 b [ c +1] [ r ] = 2 ;506 b [ c +1] [ r +1] = 2 ;507 re turn (n . a ) ;508 }509 b [ c +1] [ r ] = 0 ;510 b [ c +1] [ r +1] = 1 ;511 re = placePieceMin (b , d , n ,

c+1, r +1, c+1, r ,alpha , beta ) ;

512 alpha = re [ 1 ] ;513 beta = re [ 2 ] ;514 i f ( re [ 0 ] == 1) {515 b [ c +1] [ r ] = 2 ;516 b [ c +1] [ r +1] = 2 ;517 re turn ( re [ 3 ] ) ;518 }519 b [ c +1] [ r ] = 2 ;520 b [ c +1] [ r +1] = 2 ;521 }522 }523 i f ( r > 0) {524 i f ( fb [ c +1] [ r−1] == 0) {525 i n t [ ] r e ;526 b [ c +1] [ r ] = 1 ;527 b [ c +1] [ r−1] = 0 ;528 re = placePieceMin (b , d , n ,

c+1, r , c+1, r−1,alpha , beta ) ;

529 alpha = re [ 1 ] ;530 beta = re [ 2 ] ;531 i f ( re [ 0 ] == 1) {532 b [ c +1] [ r ] = 2 ;533 b [ c +1] [ r−1] = 2 ;534 re turn ( re [ 3 ] ) ;535 }536 b [ c +1] [ r ] = 0 ;

118 Bilag A

537 b [ c +1] [ r−1] = 1 ;538 re = placePieceMin (b , d , n ,

c+1, r−1, c+1, r ,alpha , beta ) ;

539 alpha = re [ 1 ] ;540 beta = re [ 2 ] ;541 i f ( re [ 0 ] == 1) {542 b [ c +1] [ r ] = 2 ;543 b [ c +1] [ r−1] = 2 ;544 re turn ( re [ 3 ] ) ;545 }546 b [ c +1] [ r ] = 2 ;547 b [ c +1] [ r−1] = 2 ;548 }549 }550 i f ( c < tModel . noCols−2){551 i f ( fb [ c +2] [ r ] == 0) {552 i n t [ ] r e ;553 b [ c +1] [ r ] = 1 ;554 b [ c +2] [ r ] = 0 ;555 re = placePieceMin (b , d , n ,

c+1, r , c+2, r , alpha ,beta ) ;

556 alpha = re [ 1 ] ;557 beta = re [ 2 ] ;558 i f ( re [ 0 ] == 1) {559 b [ c +1] [ r ] = 2 ;560 b [ c +2] [ r ] = 2 ;561 re turn ( re [ 3 ] ) ;562 }563 b [ c +1] [ r ] = 0 ;564 b [ c +2] [ r ] = 1 ;565 re = placePieceMin (b , d , n ,

c+2, r , c+1, r , alpha ,beta ) ;

566 alpha = re [ 1 ] ;567 beta = re [ 2 ] ;568 i f ( re [ 0 ] == 1) {569 b [ c +1] [ r ] = 2 ;570 b [ c +2] [ r ] = 2 ;571 re turn ( re [ 3 ] ) ;572 }573 b [ c +1] [ r ] = 2 ;574 b [ c +2] [ r ] = 2 ;575 }576 }577 }578 }579 // ves t580 i f ( c > 0) {581 i f ( fb [ c−1] [ r ] == 0) {582 i f ( r < tModel . noRows−1){583 i f ( fb [ c−1] [ r +1] == 0) {584 i n t [ ] r e ;585 b [ c−1] [ r ] = 1 ;

A.2 AITaijiGrowth.java 119

586 b [ c−1] [ r +1] = 0 ;587 re = placePieceMin (b , d , n ,

c−1, r , c−1, r +1,alpha , beta ) ;

588 alpha = re [ 1 ] ;589 beta = re [ 2 ] ;590 i f ( re [ 0 ] == 1) {591 b [ c−1] [ r ] = 2 ;592 b [ c−1] [ r +1] = 2 ;593 re turn ( re [ 3 ] ) ;594 }595 b [ c−1] [ r ] = 0 ;596 b [ c−1] [ r +1] = 1 ;597 re = placePieceMin (b , d , n ,

c−1, r +1, c−1, r ,alpha , beta ) ;

598 alpha = re [ 1 ] ;599 beta = re [ 2 ] ;600 i f ( re [ 0 ] == 1) {601 b [ c−1] [ r ] = 2 ;602 b [ c−1] [ r +1] = 2 ;603 re turn ( re [ 3 ] ) ;604 }605 b [ c−1] [ r ] = 2 ;606 b [ c−1] [ r +1] = 2 ;607 }608 }609 i f ( r > 0) {610 i f ( fb [ c−1] [ r−1] == 0) {611 i n t [ ] r e ;612 b [ c−1] [ r ] = 1 ;613 b [ c−1] [ r−1] = 0 ;614 re = placePieceMin (b , d , n ,

c−1, r , c−1, r−1,alpha , beta ) ;

615 alpha = re [ 1 ] ;616 beta = re [ 2 ] ;617 i f ( re [ 0 ] == 1) {618 b [ c−1] [ r ] = 2 ;619 b [ c−1] [ r−1] = 2 ;620 re turn ( re [ 3 ] ) ;621 }622 b [ c−1] [ r ] = 0 ;623 b [ c−1] [ r−1] = 1 ;624 re = placePieceMin (b , d , n ,

c−1, r−1, c−1, r ,alpha , beta ) ;

625 alpha = re [ 1 ] ;626 beta = re [ 2 ] ;627 i f ( re [ 0 ] == 1) {628 b [ c−1] [ r ] = 2 ;629 b [ c−1] [ r−1] = 2 ;630 re turn ( re [ 3 ] ) ;631 }632 b [ c−1] [ r ] = 2 ;

120 Bilag A

633 b [ c−1] [ r−1] = 2 ;634 }635 }636 i f ( c > 1) {637 i f ( fb [ c−2] [ r ] == 0) {638 i n t [ ] r e ;639 b [ c−1] [ r ] = 1 ;640 b [ c−2] [ r ] = 0 ;641 re = placePieceMin (b , d , n ,

c−1, r , c−2, r , alpha ,beta ) ;

642 alpha = re [ 1 ] ;643 beta = re [ 2 ] ;644 i f ( re [ 0 ] == 1) {645 b [ c−1] [ r ] = 2 ;646 b [ c−2] [ r ] = 2 ;647 re turn ( re [ 3 ] ) ;648 }649 b [ c−1] [ r ] = 0 ;650 b [ c−2] [ r ] = 1 ;651 re = placePieceMin (b , d , n ,

c−2, r , c−1, r , alpha ,beta ) ;

652 alpha = re [ 1 ] ;653 beta = re [ 2 ] ;654 i f ( re [ 0 ] == 1) {655 b [ c−1] [ r ] = 2 ;656 b [ c−2] [ r ] = 2 ;657 re turn ( re [ 3 ] ) ;658 }659 b [ c−1] [ r ] = 2 ;660 b [ c−2] [ r ] = 2 ;661 }662 }663 }664 }665 // syd666 i f ( r < tModel . noRows−1){667 i f ( fb [ c ] [ r +1] == 0) {668 i f ( c < tModel . noCols−1){669 i f ( fb [ c +1] [ r +1] == 0) {670 i n t [ ] r e ;671 b [ c ] [ r +1] = 1 ;672 b [ c +1] [ r +1] = 0 ;673 re = placePieceMin (b , d , n ,

c , r +1, c+1, r +1,alpha , beta ) ;

674 alpha = re [ 1 ] ;675 beta = re [ 2 ] ;676 i f ( re [ 0 ] == 1) {677 b [ c ] [ r +1] = 2 ;678 b [ c +1] [ r +1] = 2 ;679 re turn ( re [ 3 ] ) ;680 }681 b [ c ] [ r +1] = 0 ;

A.2 AITaijiGrowth.java 121

682 b [ c +1] [ r +1] = 1 ;683 re = placePieceMin (b , d , n ,

c+1, r +1, c , r +1,alpha , beta ) ;

684 alpha = re [ 1 ] ;685 beta = re [ 2 ] ;686 i f ( re [ 0 ] == 1) {687 b [ c ] [ r +1] = 2 ;688 b [ c +1] [ r +1] = 2 ;689 re turn ( re [ 3 ] ) ;690 }691 b [ c ] [ r +1] = 2 ;692 b [ c +1] [ r +1] = 2 ;693 }694 }695 i f ( c > 0) {696 i f ( fb [ c−1] [ r +1] == 0) {697 i n t [ ] r e ;698 b [ c ] [ r +1] = 1 ;699 b [ c−1] [ r +1] = 0 ;700 re = placePieceMin (b , d , n ,

c , r +1, c−1, r +1,alpha , beta ) ;

701 alpha = re [ 1 ] ;702 beta = re [ 2 ] ;703 i f ( re [ 0 ] == 1) {704 b [ c ] [ r +1] = 2 ;705 b [ c−1] [ r +1] = 2 ;706 re turn ( re [ 3 ] ) ;707 }708 b [ c ] [ r +1] = 0 ;709 b [ c−1] [ r +1] = 1 ;710 re = placePieceMin (b , d , n ,

c−1, r +1, c , r +1,alpha , beta ) ;

711 alpha = re [ 1 ] ;712 beta = re [ 2 ] ;713 i f ( re [ 0 ] == 1) {714 b [ c ] [ r +1] = 2 ;715 b [ c−1] [ r +1] = 2 ;716 re turn ( re [ 3 ] ) ;717 }718 b [ c ] [ r +1] = 2 ;719 b [ c−1] [ r +1] = 2 ;720 }721 }722 i f ( r < tModel . noRows−2){723 i f ( fb [ c ] [ r +2] == 0) {724 i n t [ ] r e ;725 b [ c ] [ r +1] = 1 ;726 b [ c ] [ r +2] = 0 ;727 re = placePieceMin (b , d , n ,

c , r +1, c , r +2, alpha ,beta ) ;

728 alpha = re [ 1 ] ;

122 Bilag A

729 beta = re [ 2 ] ;730 i f ( re [ 0 ] == 1) {731 b [ c ] [ r +1] = 2 ;732 b [ c ] [ r +2] = 2 ;733 re turn ( re [ 3 ] ) ;734 }735 b [ c ] [ r +1] = 0 ;736 b [ c ] [ r +2] = 1 ;737 re = placePieceMin (b , d , n ,

c , r +2, c , r +1, alpha ,beta ) ;

738 alpha = re [ 1 ] ;739 beta = re [ 2 ] ;740 i f ( re [ 0 ] == 1) {741 b [ c ] [ r +1] = 2 ;742 b [ c ] [ r +2] = 2 ;743 re turn ( re [ 3 ] ) ;744 }745 b [ c ] [ r +1] = 2 ;746 b [ c ] [ r +2] = 2 ;747 }748 }749 }750 }751 // Nord752 i f ( r > 0) {753 i f ( fb [ c ] [ r−1] == 0) {754 i f ( c > 0) {755 i f ( fb [ c−1] [ r−1] == 0) {756 i n t [ ] r e ;757 b [ c ] [ r−1] = 1 ;758 b [ c−1] [ r−1] = 0 ;759 re = placePieceMin (b , d , n ,

c , r−1, c−1, r−1,alpha , beta ) ;

760 alpha = re [ 1 ] ;761 beta = re [ 2 ] ;762 i f ( re [ 0 ] == 1) {763 b [ c ] [ r−1] = 2 ;764 b [ c−1] [ r−1] = 2 ;765 re turn ( re [ 3 ] ) ;766 }767 b [ c ] [ r−1] = 0 ;768 b [ c−1] [ r−1] = 1 ;769 re = placePieceMin (b , d , n ,

c−1, r−1, c , r−1,alpha , beta ) ;

770 alpha = re [ 1 ] ;771 beta = re [ 2 ] ;772 i f ( re [ 0 ] == 1) {773 b [ c ] [ r−1] = 2 ;774 b [ c−1] [ r−1] = 2 ;775 re turn ( re [ 3 ] ) ;776 }777 b [ c ] [ r−1] = 2 ;

A.2 AITaijiGrowth.java 123

778 b [ c−1] [ r−1] = 2 ;779 }780 }781 i f ( c < tModel . noCols−1){782 i f ( fb [ c +1] [ r−1] == 0) {783 i n t [ ] r e ;784 b [ c ] [ r−1] = 1 ;785 b [ c +1] [ r−1] = 0 ;786 re = placePieceMin (b , d , n ,

c , r−1, c+1, r−1,alpha , beta ) ;

787 alpha = re [ 1 ] ;788 beta = re [ 2 ] ;789 i f ( re [ 0 ] == 1) {790 b [ c ] [ r−1] = 2 ;791 b [ c +1] [ r−1] = 2 ;792 re turn ( re [ 3 ] ) ;793 }794 b [ c ] [ r−1] = 0 ;795 b [ c +1] [ r−1] = 1 ;796 re = placePieceMin (b , d , n ,

c+1, r−1, c , r−1,alpha , beta ) ;

797 alpha = re [ 1 ] ;798 beta = re [ 2 ] ;799 i f ( re [ 0 ] == 1) {800 b [ c ] [ r−1] = 2 ;801 b [ c +1] [ r−1] = 2 ;802 re turn ( re [ 3 ] ) ;803 }804 b [ c ] [ r−1] = 2 ;805 b [ c +1] [ r−1] = 2 ;806 }807 }808 i f ( r > 1) {809 i f ( fb [ c ] [ r−2] == 0) {810 i n t [ ] r e ;811 b [ c ] [ r−1] = 1 ;812 b [ c ] [ r−2] = 0 ;813 re = placePieceMin (b , d , n ,

c , r−1, c , r−2, alpha ,beta ) ;

814 alpha = re [ 1 ] ;815 beta = re [ 2 ] ;816 i f ( re [ 0 ] == 1) {817 b [ c ] [ r−1] = 2 ;818 b [ c ] [ r−2] = 2 ;819 re turn ( re [ 3 ] ) ;820 }821 b [ c ] [ r−1] = 0 ;822 b [ c ] [ r−2] = 1 ;823 re = placePieceMin (b , d , n ,

c , r−2, c , r−1, alpha ,beta ) ;

824 alpha = re [ 1 ] ;

124 Bilag A

825 beta = re [ 2 ] ;826 i f ( re [ 0 ] == 1) {827 b [ c ] [ r−1] = 2 ;828 b [ c ] [ r−2] = 2 ;829 re turn ( re [ 3 ] ) ;830 }831 b [ c ] [ r−1] = 2 ;832 b [ c ] [ r−2] = 2 ;833 }834 }835 }836 }837 }838 }839 }840 re turn (n . a ) ;841 }842 }843844845 // haandtere p l a c e r i ngen a f b r i kke r f o r max( ) , checker om de

a l l e r e d e e k s i s t e r e r , haandtere alpha beta pruning846 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,

i n t wR, i n t bC, i n t bR, i n t alpha , i n t beta ) {847 i n t [ ] p = new i n t [ 3 ] ;848 p = checkBoardInd iv idua l i ty (b , d) ;849 i n t [ ] r e = new i n t [ 4 ] ; // re [0 ]= 1 break , re [1 ]= alpha , re

[2 ]= beta , re [3 ]= n . a850851 i f (p [ 2 ] >= 0) {852 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;853 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;854 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;855 i f (n . a < v )856 n . a = v ;857 i f (n . a > beta ) {858 re [ 0 ] = 0 ; // 1 = alpha beta pruning

s l a a e t t i l , 0 = s l a a e t f r a (s l a a e t f r a da den g i v e rproblemer )

859 re [1 ]= alpha ;860 re [2 ]= beta ;861 re [3 ]=n . a ;862 re turn ( re ) ;863 }864 i f ( alpha < n . a )865 alpha = n . a ;866867 }868 i f (p [ 2 ] == −1){869 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;870 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode (wC, wR, bC, bR, n) )

A.2 AITaijiGrowth.java 125

) ;871 count++;872 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;873 i f (n . a < v )874 n . a = v ;875 i f (n . a > beta ) {876 re [ 0 ] = 0 ; // 1 = alpha beta pruning

s l a a e t t i l , 0 = s l a a e t f r a (s l a a e t f r a da den g i v e rproblemer )

877 re [1 ]= alpha ;878 re [2 ]= beta ;879 re [3 ]=n . a ;880 re turn ( re ) ;881 }882 i f ( alpha < n . a )883 alpha = n . a ;884885 }886 re turn ( re ) ;887 }888889 // haandtere p l a c e r i ngen a f b r i kke r f o r min ( ) , checker om de

a l l e r e d e e k s i s t e r e r , haandtere alpha beta pruning890 p r i v a t e i n t [ ] p lacePieceMin ( i n t [ ] [ ] b , i n t d , Node n , i n t wC,

i n t wR, i n t bC, i n t bR, i n t alpha , i n t beta ) {891 i n t [ ] p = new i n t [ 3 ] ;892 p = checkBoardInd iv idua l i ty (b , d) ;893 i n t [ ] r e = new i n t [ 4 ] ; // re [0 ]= 1 break , re [1 ]= alpha , re

[2 ]= beta , re [3 ]= n . a894895 i f (p [ 2 ] >= 0) {896 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;897 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) ) ;898 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) , alpha , beta , 1 ) ;899 i f (n . a > v )900 n . a = v ;901 i f (n . a < alpha ) {902 re [ 0 ] = 0 ; // 1 = alpha beta pruning s l a a e t t i l , 0 =

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 )903 re [1 ]= alpha ;904 re [2 ]= beta ;905 re [3 ]=n . a ;906 re turn ( re ) ;907 }908 i f ( beta > n . a )909 beta = n . a ;910 }911 i f (p [ 2 ] == −1){912 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;913 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode . createChi ldNode (

wC, wR, bC, bR, n) ) ) ;914 count++;915 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) , alpha , beta , 0 ) ;

126 Bilag A

916 i f (n . a > v )917 n . a = v ; // 1 = alpha beta pruning s l a a e t t i l , 0 =

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)

918 i f (n . a < alpha ) {919 re [ 0 ] = 0 ;920 re [1 ]= alpha ;921 re [2 ]= beta ;922 re [3 ]=n . a ;923 re turn ( re ) ;924 }925 i f ( beta > n . a )926 beta = n . a ;927 }928 re turn ( re ) ;929 }930931932933934935936 // s a e t t e r scoren f o r en node t i l lower bound937 p r i v a t e Node setScoreMin (Node n) {938 n . a = −tModel . maxScore ;939 re turn (n) ;940 }941 // s a e t t e r scoren f o r en node t i l e t upper bound942 p r i v a t e Node setScoreMax (Node n) {943 n . a = tModel . maxScore ;944 re turn (n) ;945 }946947948949 // udsk r i v e r f i gBoarde t f o r 4x4 e l l e r 9x9 p lader950 p r i v a t e void printFB ( i n t [ ] [ ] fb ) {951 i f ( tModel . noCols > 8 && tModel . noRows > 8)952 printFB9x9 ( fb ) ;953 e l s e954 printFB4x4 ( fb ) ;955 }956957 // udsk r i v e r f i gBoarde t f o r 4x4 p lader958 p r i v a t e void printFB4x4 ( i n t [ ] [ ] fb ) {959 System . out . p r i n t l n (” Pr int FB ”+fb ) ;960 System . out . p r i n t l n ( fb [ 0 ] [ 0 ] + ” ”+fb [ 1 ] [ 0 ] + ” ”+fb

[ 2 ] [ 0 ] + ” ”+fb [ 3 ] [ 0 ] ) ;961 System . out . p r i n t l n ( fb [ 0 ] [ 1 ] + ” ”+fb [ 1 ] [ 1 ] + ” ”+fb

[ 2 ] [ 1 ] + ” ”+fb [ 3 ] [ 1 ] ) ;962 System . out . p r i n t l n ( fb [ 0 ] [ 2 ] + ” ”+fb [ 1 ] [ 2 ] + ” ”+fb

[ 2 ] [ 2 ] + ” ”+fb [ 3 ] [ 2 ] ) ;963 System . out . p r i n t l n ( fb [ 0 ] [ 3 ] + ” ”+fb [ 1 ] [ 3 ] + ” ”+fb

[ 2 ] [ 3 ] + ” ”+fb [ 3 ] [ 3 ] ) ;964 System . out . p r i n t l n ( ) ;

A.2 AITaijiGrowth.java 127

965 }966967 // udsk r i v e r f i gBoarde t f o r 9x9 p lader968 p r i v a t e void printFB9x9 ( i n t [ ] [ ] fb ) {969 System . out . p r i n t l n (” Pr int FB ”+fb ) ;970 System . out . p r i n t l n ( fb [ 0 ] [ 0 ] + ” ”+fb [ 1 ] [ 0 ] + ” ”+fb

[ 2 ] [ 0 ] + ” ”+fb [ 3 ] [ 0 ] + ” ”+fb [ 4 ] [ 0 ] + ” ”+fb [ 5 ] [ 0 ] + ””+fb [ 6 ] [ 0 ] + ” ”+fb [ 7 ] [ 0 ] + ” ”+fb [ 8 ] [ 0 ] ) ;

971 System . out . p r i n t l n ( fb [ 0 ] [ 1 ] + ” ”+fb [ 1 ] [ 1 ] + ” ”+fb[ 2 ] [ 1 ] + ” ”+fb [ 3 ] [ 1 ] + ” ”+fb [ 4 ] [ 1 ] + ” ”+fb [ 5 ] [ 1 ] + ””+fb [ 6 ] [ 1 ] + ” ”+fb [ 7 ] [ 1 ] + ” ”+fb [ 8 ] [ 1 ] ) ;

972 System . out . p r i n t l n ( fb [ 0 ] [ 2 ] + ” ”+fb [ 1 ] [ 2 ] + ” ”+fb[ 2 ] [ 2 ] + ” ”+fb [ 3 ] [ 2 ] + ” ”+fb [ 4 ] [ 2 ] + ” ”+fb [ 5 ] [ 2 ] + ””+fb [ 6 ] [ 2 ] + ” ”+fb [ 7 ] [ 2 ] + ” ”+fb [ 8 ] [ 2 ] ) ;

973 System . out . p r i n t l n ( fb [ 0 ] [ 3 ] + ” ”+fb [ 1 ] [ 3 ] + ” ”+fb[ 2 ] [ 3 ] + ” ”+fb [ 3 ] [ 3 ] + ” ”+fb [ 4 ] [ 3 ] + ” ”+fb [ 5 ] [ 3 ] + ””+fb [ 6 ] [ 3 ] + ” ”+fb [ 7 ] [ 3 ] + ” ”+fb [ 8 ] [ 3 ] ) ;

974 System . out . p r i n t l n ( fb [ 0 ] [ 4 ] + ” ”+fb [ 1 ] [ 4 ] + ” ”+fb[ 2 ] [ 4 ] + ” ”+fb [ 3 ] [ 4 ] + ” ”+fb [ 4 ] [ 4 ] + ” ”+fb [ 5 ] [ 4 ] + ””+fb [ 6 ] [ 4 ] + ” ”+fb [ 7 ] [ 4 ] + ” ”+fb [ 8 ] [ 4 ] ) ;

975 System . out . p r i n t l n ( fb [ 0 ] [ 5 ] + ” ”+fb [ 1 ] [ 5 ] + ” ”+fb[ 2 ] [ 5 ] + ” ”+fb [ 3 ] [ 5 ] + ” ”+fb [ 4 ] [ 5 ] + ” ”+fb [ 5 ] [ 5 ] + ””+fb [ 6 ] [ 5 ] + ” ”+fb [ 7 ] [ 5 ] + ” ”+fb [ 8 ] [ 5 ] ) ;

976 System . out . p r i n t l n ( fb [ 0 ] [ 6 ] + ” ”+fb [ 1 ] [ 6 ] + ” ”+fb[ 2 ] [ 6 ] + ” ”+fb [ 3 ] [ 6 ] + ” ”+fb [ 4 ] [ 6 ] + ” ”+fb [ 5 ] [ 6 ] + ””+fb [ 6 ] [ 6 ] + ” ”+fb [ 7 ] [ 6 ] + ” ”+fb [ 8 ] [ 6 ] ) ;

977 System . out . p r i n t l n ( fb [ 0 ] [ 7 ] + ” ”+fb [ 1 ] [ 7 ] + ” ”+fb[ 2 ] [ 7 ] + ” ”+fb [ 3 ] [ 7 ] + ” ”+fb [ 4 ] [ 7 ] + ” ”+fb [ 5 ] [ 7 ] + ””+fb [ 6 ] [ 7 ] + ” ”+fb [ 7 ] [ 7 ] + ” ”+fb [ 8 ] [ 7 ] ) ;

978 System . out . p r i n t l n ( fb [ 0 ] [ 8 ] + ” ”+fb [ 1 ] [ 8 ] + ” ”+fb[ 2 ] [ 8 ] + ” ”+fb [ 3 ] [ 8 ] + ” ”+fb [ 4 ] [ 8 ] + ” ”+fb [ 5 ] [ 8 ] + ””+fb [ 6 ] [ 8 ] + ” ”+fb [ 7 ] [ 8 ] + ” ”+fb [ 8 ] [ 8 ] ) ;

979 System . out . p r i n t l n ( ) ;980 }981982 // haandtere Growth AI ’ ens k o e r s e l og r e t u r n e r e det fundne

t raek983 pub l i c Node returnMove ( boolean b) {984 i f ( tModel . currentTurn == 1) {985 i f (b == f a l s e ) {986 tNode = new Node ( ) ;987 Root = tNode . createNode ( tModel . currentTurn , tModel )

;988 Root . wc=0; // tModel . noCols /2 ; // f o r at s a e t t e

f o e r s t e br ik i midten i s t e d e t f o r i h j o e rne t989 Root . wr=1; // tModel . noCols /2 ; // f o r at s a e t t e

f o e r s t e br ik i midten i s t e d e t f o r i h j o e rne t990 Root . bc=Root . wc ;991 Root . br=Root . wr−1;992 re turn ( Root ) ;993 }994 i f (b == true ) {995 tNode = new Node ( ) ;996 Root = tNode . createNode ( tModel . currentTurn , tModel )

;

128 Bilag A

997 Root . wc=0; // tModel . noCols /2 ; // f o r at s a e t t ef o e r s t e br ik i midten i s t e d e t f o r i h j o e rne t

998 Root . wr=0; // tModel . noCols /2 ; // f o r at s a e t t ef o e r s t e br ik i midten i s t e d e t f o r i h j o e rne t

999 Root . bc=Root . wc ;1000 Root . br=Root . wr+1;1001 re turn ( Root ) ;1002 }1003 }1004 Growth ( ) ;10051006 i f (b)1007 min ( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;1008 i f ( ! b )1009 max( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;10101011 Random randomVal = new Random( ) ;1012 Node n ;1013 ArrayList<Node> move = new ArrayList<Node>() ;1014 i n t wC,wR, bC,bR, ran ;1015 n = Root . c h i l d r e n . get (0 ) ;1016 // tModel . tPr in t . printNode ( Root ) ;1017 // tModel . tPr in t . p r in tCh i ld r en ( Root ) ;1018 //System . out . p r i n t l n (” Growth − r e turn move Root . s i z e=”+Root

. c h i l d r e n . s i z e ( ) ) ;1019 i f ( Root . c h i l d r e n . s i z e ( ) > 1) {1020 i f (b) {1021 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ //

Finder bedste vae rd i1022 i f (n . a>Root . c h i l d r e n . get ( i ) . a ) {1023 n=Root . c h i l d r e n . get ( i ) ;1024 }1025 }1026 }1027 i f ( ! b ) {1028 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ //

Finder bedste vae rd i1029 i f (n . a<Root . c h i l d r e n . get ( i ) . a ) {1030 n=Root . c h i l d r e n . get ( i ) ;1031 }1032 }1033 }1034 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ // Finder

a l l e t raek med bedste vae rd i1035 i f (n . a==Root . c h i l d r e n . get ( i ) . a ) {1036 move . add ( Root . c h i l d r e n . get ( i ) ) ;1037 }1038 }1039 ran = randomVal . next Int (move . s i z e ( ) ) ; // v a e l g e r

t i l f a e l d i g t mellem de l i g e gode t raek .1040 n = move . get ( ran ) ;1041 }10421043 System . out . p r i n t l n (” Growth Move coord”+n . wc+” ”+n . wr+” ”+n .

bc+” ”+n . br ) ;

A.2 AITaijiGrowth.java 129

1044 wC = n . wc ;1045 wR = n . wr ;1046 bC = n . bc ;1047 bR = n . br ;1048 n . nodeBoard [wC] [wR]=2;1049 n . nodeBoard [bC ] [ bR]=2;1050 // tModel . tPr in t . printNode (n) ;10511052 // vender det va l g t e t raek saa det matcher s p i l l e t s

igangvaerende t raek .1053 i n t mr = tModel . tBoard . compareBoardsInt (n . nodeBoard , tModel

. tBoard . board [ tModel . currentTurn ] ) ;1054 System . out . p r i n t l n (” Growth − Return move mr=”+mr) ;1055 i f (mr == 1) {1056 re turn (n) ;1057 }1058 i f (mr == 2) {1059 n . br = tModel . noRows−1 − bR;1060 n . wr = tModel . noRows−1 − wR;1061 re turn (n) ;1062 }1063 i f (mr == 3) {1064 n . bc = tModel . noCols−1 − bC;1065 n . wc = tModel . noCols−1 − wC;1066 re turn (n) ;1067 }1068 i f (mr == 4) {1069 n . bc = tModel . noCols−1 − bC;1070 n . wc = tModel . noCols−1 − wC;1071 n . br = tModel . noRows−1 − bR;1072 n . wr = tModel . noRows−1 − wR;1073 re turn (n) ;1074 }1075 i f (mr == 5) {1076 n . bc = bR;1077 n . wc = wR;1078 n . br = bC;1079 n . wr = wC;1080 re turn (n) ;1081 }1082 i f (mr == 6) {1083 n . bc = tModel . noRows−1 − bR;1084 n . wc = tModel . noRows−1 − wR;1085 n . br = bC;1086 n . wr = wC;1087 re turn (n) ;1088 }1089 i f (mr == 7) {1090 n . bc = bR;1091 n . wc = wR;1092 n . br = tModel . noCols−1 − bC;1093 n . wr = tModel . noCols−1 − wC;1094 re turn (n) ;1095 }1096 i f (mr == 8) {

130 Bilag A

1097 n . bc = tModel . noRows−1 − bR;1098 n . wc = tModel . noRows−1 − wR;1099 n . br = tModel . noCols−1 − bC;1100 n . wr = tModel . noCols−1 − wC;1101 re turn (n) ;1102 }1103 re turn (n) ;1104 }11051106 }

A.3 AITaijiLocalAreaAB.java

1 import java . u t i l . Random ;2 import java . u t i l . ArrayList ;34 pub l i c c l a s s AITaijiLocalAreaAB {56 pub l i c Tai j iModel tModel ;7 pub l i c Node tNode ;8 pub 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 .9 pub l i c i n t maxDepth ;

10 p r i v a t e ArrayList<Node > [ ] [ ] nodes ; // indeho lde r a l l e noderne ia r r a y l i s t s e f t e r gene ra t i on og hash vaerd i .

11 p r i v a t e i n t maxD; // den maximale dybde f o r t r a e e t .12 p r i v a t e i n t maxH; // den maximale Hash vaerd i13 p r i v a t e Node Root ; // Traeets rod .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

en maximal soege dybde15 p r i v a t e i n t co lS ta r t , colEnd , rowStart , rowEnd ;161718 pub l i c AITaijiLocalAreaAB ( Tai j iModel m) {19 t h i s . tModel = m;20 }2122 pub l i c void LocalAreaAB ( ) {23 tNode = new Node ( ) ;24 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;25 count = 1 ;26 maxD = tModel . maxTurnsLeft ( ) ;27 searchD = maxD;28 maxH = tModel . tHash . getMaxH3 ( ) ;29 nodes = new ArrayList [maxD ] [ maxH+1] ;30 f o r ( i n t i =0; i<maxD; i++){31 f o r ( i n t j =0; j<=maxH; j++)32 nodes [ i ] [ j ] = new ArrayList<Node>() ;33 }34 i n t [ ] t = new i n t [ 4 ] ;35 t = tModel . getLatestMove ( ) ;3637 setAround ( t ) ;38

A.3 AITaijiLocalAreaAB.java 131

39 }4041 // s a e t t e r co lS ta r t , colEnd , rowStart og rowEnd s a a l e d e s at der

kan koere s minimax paa et 4x4 omraade a f b r a e t t e t .42 p r i v a t e void setAround ( i n t [ ] t ) {43 i f ( t [ 0 ] < t [ 2 ] ) {44 c o l S t a r t = t [0 ] −1 ;45 colEnd = t [ 2 ] + 1 ;46 }47 i f ( t [ 0 ] > t [ 2 ] ) {48 c o l S t a r t = t [2 ] −1 ;49 colEnd = t [ 0 ] + 1 ;50 }51 i f ( t [ 0 ] == t [ 2 ] ) {52 c o l S t a r t = t [0 ] −1 ;53 colEnd = t [ 0 ] + 2 ; // +2 f o r 4x4 , +1 f o r 3x454 }55 // f l y t t e r omraadet hv i s f o r r i g e t raek l i g g e r opad kanten56 i f ( c o l S t a r t < 0) {57 i f ( colEnd − c o l S t a r t == 2 && t [0]== t [ 2 ] )58 colEnd = 2 ; // 3x459 e l s e60 colEnd = 3 ; // 4x461 c o l S t a r t = 0 ;62 }6364 // f l y t t e r omraadet hv i s f o r r i g e t raek l i g g e r opad kanten65 i f ( colEnd >= tModel . noCols ) {66 i f ( colEnd − c o l S t a r t == 2 && t [0]== t [ 2 ] )67 c o l S t a r t = tModel . noCols−3; // 3x468 e l s e69 c o l S t a r t = tModel . noCols−4; // 4x470 colEnd = tModel . noCols−1;7172 }7374 i f ( t [ 1 ] < t [ 3 ] ) {75 rowStart = t [1 ] −1 ;76 rowEnd = t [ 3 ] + 1 ;77 }78 i f ( t [ 1 ] > t [ 3 ] ) {79 rowStart = t [3 ] −1 ;80 rowEnd = t [ 1 ] + 1 ;81 }82 i f ( t [ 1 ] == t [ 3 ] ) {83 rowStart = t [1 ] −1 ;84 rowEnd = t [ 1 ] + 2 ; // +2 f o r 4x4 , +1 f o r 4x385 }86 i f ( rowStart < 0) {87 i f ( rowEnd − rowStart == 2 && t [1]== t [ 3 ] )88 rowEnd = 2 ; // 4x389 e l s e90 rowEnd = 3 ; // 4x491 rowStart = 0 ;92 }

132 Bilag A

93 i f ( rowEnd >= tModel . noRows) {94 i f ( rowEnd − rowStart == 2 && t [1]== t [ 3 ] )95 rowStart = tModel . noRows−3; // 4x396 e l s e97 rowStart = tModel . noRows−4; // 4x498 rowEnd = tModel . noRows−1;99 }

100 }101102 // s a e t t e r soegedybden103 pub l i c void setSearchDepth ( i n t d) {104 searchD = d ;105 }106107 // checker om der a l l e r e d e er et saadant braet . Returnerer

co rd ina t e rne f o r den node , hv i s der er .108 p r i v a t e i n t [ ] checkBoardInd iv idua l i ty ( i n t [ ] [ ] b , i n t d) {109 i n t [ ] p = new i n t [ 3 ] ;110 i n t h = tModel . tHash . hashFunction3 (b) ;111 p [0 ]=d ;112 p [1 ]=h ;113 p[2]=−1;114 f o r ( i n t i = 0 ; i<nodes [ d ] [ h ] . s i z e ( ) ; i++){115 i f ( tModel . tBoard . compareBoards (b , nodes [ d ] [ h ] . get ( i ) .

nodeBoard ) ) { // Sammenligner to braet , men ikker o t t e r i n g e r e l l e r s p e j l i n g e r

116 p [2 ]= i ;117 re turn (p) ;118 }119 }120 re turn (p) ;121122123 }124125 // Max−funkt ionen , l a v e t t i l holde s i g inden f o r et 4x4 a r e a l

paa b r a e t t e t126 p r i v a t e i n t max(Node n , i n t alpha , i n t beta , i n t ex ) {127 i f (n . d >= searchD | | ! tModel . movesLeftN (n) ) {128 n . a = tModel . fMap . c a l D i f (n . nodeBoard , tModel . noCols ,

tModel . noRows) ;129 re turn (n . a ) ;130 }131 e l s e {132 i f ( ex == 1) {133 i f (n . a >= beta )134 re turn (n . a ) ;135 }136 n . a = −tModel . maxScore ;137 i n t [ ] [ ] b = n . nodeBoard ;138 i n t d = n . d ;139 f o r ( i n t c=c o l S t a r t ; c <= colEnd ; c++){140 f o r ( i n t r=rowStart ; r <= rowEnd−1; r++){141 i f (b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {142 b [ c ] [ r ] = 1 ;

A.3 AITaijiLocalAreaAB.java 133

143 b [ c ] [ r +1] = 0 ;144 i n t [ ] p = new i n t [ 3 ] ;145 p = checkBoardInd iv idua l i ty (b , d) ;146 i f (p [ 2 ] >= 0) {147 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;148 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;149 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;150 i f (n . a < v )151 n . a = v ;152 i f (n . a > beta ) {153 b [ c ] [ r ] = 2 ;154 b [ c ] [ r +1] = 2 ;155 re turn (n . a ) ;156 }157 i f ( alpha < n . a )158 alpha = n . a ;159160 }161 i f (p [ 2 ] == −1){162 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;163 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c , r +1, n) ) ) ;164 count++;165 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;166 i f (n . a < v )167 n . a = v ;168 i f (n . a > beta ) {169 b [ c ] [ r ] = 2 ;170 b [ c ] [ r +1] = 2 ;171 re turn (n . a ) ;172 }173 i f ( alpha < n . a )174 alpha = n . a ;175176 }177 b [ c ] [ r ] = 0 ;178 b [ c ] [ r +1] = 1 ;179 p = checkBoardInd iv idua l i ty (b , d) ;180 i f (p [ 2 ] >= 0) {181 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;182 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;183 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;184 i f (n . a < v )185 n . a = v ;186 i f (n . a > beta ) {187 b [ c ] [ r ] = 2 ;188 b [ c ] [ r +1] = 2 ;189 re turn (n . a ) ;190 }191 i f ( alpha < n . a )

134 Bilag A

192 alpha = n . a ;193 }194 i f (p [ 2 ] == −1){195 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;196 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , n ) ) ) ;197 count++;198 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;199 i f (n . a < v )200 n . a = v ;201 i f (n . a > beta ) {202 b [ c ] [ r ] = 2 ;203 b [ c ] [ r +1] = 2 ;204 re turn (n . a ) ;205 }206 i f ( alpha < n . a )207 alpha = n . a ;208 }209210 b [ c ] [ r ] = 2 ;211 b [ c ] [ r +1] = 2 ;212 }213 }214 }215216 f o r ( i n t c=c o l S t a r t ; c <= colEnd−1; c++){217 f o r ( i n t r=rowStart ; r <= rowEnd ; r++){218 i f (b [ c ] [ r ] == 2 && b [ c +1] [ r ] == 2 ) {219 b [ c ] [ r ] = 1 ;220 b [ c +1] [ r ] = 0 ;221 i n t [ ] p = new i n t [ 3 ] ;222 p = checkBoardInd iv idua l i ty (b , d) ;223 i f (p [ 2 ] >= 0) {224 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;225 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;226 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;227 i f (n . a < v )228 n . a = v ;229 i f (n . a > beta ) {230 b [ c ] [ r ] = 2 ;231 b [ c +1] [ r ] = 2 ;232 re turn (n . a ) ;233 }234 i f ( alpha < n . a )235 alpha = n . a ;236 }237 i f (p [ 2 ] == −1){238 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;239 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c+1, r , n ) ) ) ;240 count++;

A.3 AITaijiLocalAreaAB.java 135

241 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ), alpha , beta , 0 ) ;

242 i f (n . a < v )243 n . a = v ;244 i f (n . a > beta ) {245 b [ c ] [ r ] = 2 ;246 b [ c +1] [ r ] = 2 ;247 re turn (n . a ) ;248 }249 i f ( alpha < n . a )250 alpha = n . a ;251 }252 b [ c ] [ r ] = 0 ;253 b [ c +1] [ r ] = 1 ;254 p = checkBoardInd iv idua l i ty (b , d) ;255 i f (p [ 2 ] >= 0) {256 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;257 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;258 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;259 i f (n . a < v )260 n . a = v ;261 i f (n . a > beta ) {262 b [ c ] [ r ] = 2 ;263 b [ c +1] [ r ] = 2 ;264 re turn (n . a ) ;265 }266 i f ( alpha < n . a )267 alpha = n . a ;268 }269 i f (p [ 2 ] == −1){270 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;271 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , n ) ) ) ;272 count++;273 i n t v = min ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;274 i f (n . a < v )275 n . a = v ;276 i f (n . a > beta ) {277 b [ c ] [ r ] = 2 ;278 b [ c +1] [ r ] = 2 ;279 re turn (n . a ) ;280 }281 i f ( alpha < n . a )282 alpha = n . a ;283 }284 b [ c ] [ r ] = 2 ;285 b [ c +1] [ r ] = 2 ;286 }287 }288 }289 re turn (n . a ) ;290 }

136 Bilag A

291 }292293 // Min−funkt ionen , l a v e t t i l holde s i g inden f o r et 4x4 a r e a l

paa b r a e t t e t294 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 ) {295 i f (n . d >= searchD | | ! tModel . movesLeftN (n) ) {296 n . a = tModel . fMap . c a l D i f (n . nodeBoard , tModel . noCols ,

tModel . noRows) ;297 re turn (n . a ) ;298 }299 e l s e {300 n . a = tModel . maxScore ;301 i n t [ ] [ ] b = n . nodeBoard ;302 i n t d = n . d ;303 // boolean Break = f a l s e ;304 f o r ( i n t c=c o l S t a r t ; c <= colEnd ; c++){305 f o r ( i n t r=rowStart ; r <= rowEnd−1; r++){306 i f (b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {307 b [ c ] [ r ] = 1 ;308 b [ c ] [ r +1] = 0 ;309 i n t [ ] p = new i n t [ 3 ] ;310 p = checkBoardInd iv idua l i ty (b , d) ;311 i f (p [ 2 ] >= 0) {312 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;313 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;314 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;315 i f (n . a > v )316 n . a = v ;317 i f (n . a < alpha ) {318 b [ c ] [ r ] = 2 ;319 b [ c ] [ r +1] = 2 ;320 re turn (n . a ) ;321 }322 i f ( beta > n . a )323 beta = n . a ;324 }325 i f (p [ 2 ] == −1){326 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;327 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c , r +1, n) ) ) ;328 count++;329 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;330 i f (n . a > v )331 n . a = v ;332 i f (n . a < alpha ) {333 b [ c ] [ r ] = 2 ;334 b [ c ] [ r +1] = 2 ;335 re turn (n . a ) ;336 }337 i f ( beta > n . a )338 beta = n . a ;339 }

A.3 AITaijiLocalAreaAB.java 137

340 b [ c ] [ r ] = 0 ;341 b [ c ] [ r +1] = 1 ;342343 p = checkBoardInd iv idua l i ty (b , d) ;344 i f (p [ 2 ] >= 0) {345 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;346 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;347 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;348 i f (n . a > v )349 n . a = v ;350 i f (n . a < alpha ) {351 b [ c ] [ r ] = 2 ;352 b [ c ] [ r +1] = 2 ;353 re turn (n . a ) ;354 }355 i f ( beta > n . a )356 beta = n . a ;357 }358 i f (p [ 2 ] == −1){359 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;360 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , n ) ) ) ;361 count++;362 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;363 i f (n . a > v )364 n . a = v ;365 i f (n . a < alpha ) {366 b [ c ] [ r ] = 2 ;367 b [ c ] [ r +1] = 2 ;368 re turn (n . a ) ;369 }370 i f ( beta > n . a )371 beta = n . a ;372 }373 b [ c ] [ r ] = 2 ;374 b [ c ] [ r +1] = 2 ;375376377 }378 }379 }380381382 f o r ( i n t c=c o l S t a r t ; c <= colEnd−1; c++){383 f o r ( i n t r=rowStart ; r <= rowEnd ; r++){384 i f (b [ c ] [ r ] == 2 && b [ c +1] [ r ] == 2 ) {385 b [ c ] [ r ] = 1 ;386 b [ c +1] [ r ] = 0 ;387 i n t [ ] p = new i n t [ 3 ] ;388 p = checkBoardInd iv idua l i ty (b , d) ;389 i f (p [ 2 ] >= 0) {390 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;

138 Bilag A

391 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p[ 2 ] ) ) ;

392 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ), alpha , beta , 1 ) ;

393 i f (n . a > v )394 n . a = v ;395 i f (n . a < alpha ) {396 b [ c ] [ r ] = 2 ;397 b [ c +1] [ r ] = 2 ;398 re turn (n . a ) ;399 }400 i f ( beta > n . a )401 beta = n . a ;402 }403 i f (p [ 2 ] == −1){404 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;405 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c , r , c+1, r , n ) ) ) ;406 count++;407 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;408 i f (n . a > v )409 n . a = v ;410 i f (n . a < alpha ) {411 b [ c ] [ r ] = 2 ;412 b [ c +1] [ r ] = 2 ;413 re turn (n . a ) ;414 }415 i f ( beta > n . a )416 beta = n . a ;417 }418 b [ c ] [ r ] = 0 ;419 b [ c +1] [ r ] = 1 ;420421 p = checkBoardInd iv idua l i ty (b , d) ;422 i f (p [ 2 ] >= 0) {423 nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] ) . par . add (n) ;424 n . c h i l d r e n . add ( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p

[ 2 ] ) ) ;425 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 1 ) ;426 i f (n . a > v )427 n . a = v ;428 i f (n . a < alpha ) {429 b [ c ] [ r ] = 2 ;430 b [ c +1] [ r ] = 2 ;431 re turn (n . a ) ;432 }433 i f ( beta > n . a )434 beta = n . a ;435 }436 i f (p [ 2 ] == −1){437 p [2 ]= nodes [ p [ 0 ] ] [ p [ 1 ] ] . s i z e ( ) ;438 nodes [ p [ 0 ] ] [ p [ 1 ] ] . add (n . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , n ) ) ) ;

A.3 AITaijiLocalAreaAB.java 139

439 count++;440 i n t v = max( nodes [ p [ 0 ] ] [ p [ 1 ] ] . get (p [ 2 ] )

, alpha , beta , 0 ) ;441 i f (n . a > v )442 n . a = v ;443 i f (n . a < alpha ) {444 b [ c ] [ r ] = 2 ;445 b [ c +1] [ r ] = 2 ;446 re turn (n . a ) ;447 }448 i f ( beta > n . a )449 beta = n . a ;450 }451 b [ c ] [ r ] = 2 ;452 b [ c +1] [ r ] = 2 ;453 }454 }455 }456 re turn (n . a ) ;457 }458 }459460461462463 // s a e t t e r scoren f o r en node t i l −”uende l i g ”464 p r i v a t e Node setScoreMin (Node n) {465 n . a = −tModel . maxScore ;466 re turn (n) ;467 }468 // s a e t t e r scoren f o r en node t i l ” uende l i g ”469 p r i v a t e Node setScoreMax (Node n) {470 n . a = tModel . maxScore ;471 re turn (n) ;472 }473474475476 pub l i c Node returnMove ( boolean b) {477 i f ( tModel . currentTurn == 1) {478 tNode = new Node ( ) ;479 Root = tNode . createNode ( tModel . currentTurn , tModel ) ;480 Root . wc=tModel . noCols /2 ;481 Root . wr=tModel . noCols /2 ;482 Root . bc=Root . wc ;483 Root . br=Root . wr+1;484 re turn ( Root ) ;485 }486 LocalAreaAB ( ) ;487488 whi l e ( Root . c h i l d r e n . s i z e ( ) == 0 && tModel . movesLeft ( ) ) {489 i f (b)490 min ( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;491 i f ( ! b )492 max( Root ,−tModel . maxScore , tModel . maxScore , 0 ) ;

140 Bilag A

493 i f ( Root . c h i l d r e n . s i z e ( ) == 0) {494 i n t [ ] s = new i n t [ 4 ] ;495 s = tModel . getAMove ( Root ) ;496 setAround ( s ) ;497 }498 //System . out . p r i n t l n (”LA − End o f While ”) ;499 }500501 Random randomVal = new Random( ) ;502 Node n ;503 ArrayList<Node> move = new ArrayList<Node>() ;504 i n t wC,wR, bC,bR, ran ;505 n = Root . c h i l d r e n . get (0 ) ;506 // tModel . tPr in t . printNode ( Root ) ; // udsk r i v e r roden507 // tModel . tPr in t . p r in tCh i ld r en ( Root ) ; // udsk r i v e r rodens

boern saa r e s u l t a t e t a f soegningen bedre kanundersoeges

508 System . out . p r i n t l n (”LA − r e turn move Root . s i z e=”+Root .c h i l d r e n . s i z e ( ) ) ;

509 i f ( Root . c h i l d r e n . s i z e ( ) > 1) {510 i f (b) {511 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ //

Finder bedste vae rd i512 i f (n . a>Root . c h i l d r e n . get ( i ) . a ) {513 n=Root . c h i l d r e n . get ( i ) ;514 }515 }516 }517 i f ( ! b ) {518 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ //

Finder bedste vae rd i519 i f (n . a<Root . c h i l d r e n . get ( i ) . a ) {520 n=Root . c h i l d r e n . get ( i ) ;521 }522 }523 }524 f o r ( i n t i =0; i<Root . c h i l d r e n . s i z e ( ) ; i++){ // Finder

a l l e t raek med bedste vae rd i525 i f (n . a==Root . c h i l d r e n . get ( i ) . a ) {526 move . add ( Root . c h i l d r e n . get ( i ) ) ;527 }528 }529 ran = randomVal . next Int (move . s i z e ( ) ) ; // v a e l g e r

t i l f a e l d i g t mellem de l i g e gode t raek .530 n = move . get ( ran ) ;531 }532533 System . out . p r i n t l n (”LA Move coord”+n . wc+” ”+n . wr+” ”+n . bc+”

”+n . br ) ;534 wC = n . wc ;535 wR = n . wr ;536 bC = n . bc ;537 bR = n . br ;538 n . nodeBoard [wC] [wR]=2;539 n . nodeBoard [bC ] [ bR]=2;

A.3 AITaijiLocalAreaAB.java 141

540 // tModel . tPr in t . printNode (n) ;541542 // vender det va l g t e t raek saa det matcher s p i l l e t s

igangvaerende t raek .543 i n t mr = tModel . tBoard . compareBoardsInt (n . nodeBoard , tModel

. tBoard . board [ tModel . currentTurn ] ) ;544 System . out . p r i n t l n (”LA − Return move mr=”+mr) ;545 i f (mr == 1) {546 re turn (n) ;547 }548 i f (mr == 2) {549 n . br = tModel . noRows−1 − bR;550 n . wr = tModel . noRows−1 − wR;551 re turn (n) ;552 }553 i f (mr == 3) {554 n . bc = tModel . noCols−1 − bC;555 n . wc = tModel . noCols−1 − wC;556 re turn (n) ;557 }558 i f (mr == 4) {559 n . bc = tModel . noCols−1 − bC;560 n . wc = tModel . noCols−1 − wC;561 n . br = tModel . noRows−1 − bR;562 n . wr = tModel . noRows−1 − wR;563 re turn (n) ;564 }565 i f (mr == 5) {566 n . bc = bR;567 n . wc = wR;568 n . br = bC;569 n . wr = wC;570 re turn (n) ;571 }572 i f (mr == 6) {573 n . bc = tModel . noRows−1 − bR;574 n . wc = tModel . noRows−1 − wR;575 n . br = bC;576 n . wr = wC;577 re turn (n) ;578 }579 i f (mr == 7) {580 n . bc = bR;581 n . wc = wR;582 n . br = tModel . noCols−1 − bC;583 n . wr = tModel . noCols−1 − wC;584 re turn (n) ;585 }586 i f (mr == 8) {587 n . bc = tModel . noRows−1 − bR;588 n . wc = tModel . noRows−1 − wR;589 n . br = tModel . noCols−1 − bC;590 n . wr = tModel . noCols−1 − wC;591 re turn (n) ;592 }

142 Bilag A

593 re turn (n) ;594 }595596597 }

A.4 AITaijiMinimax.java

1 import java . u t i l . Random ;2 import java . u t i l . ArrayList ;34 pub l i c c l a s s AITaijiMinimax {5 pub l i c Tai j iModel tModel ;6 pub l i c Node tNode ;7 pub l i c Tree tTree ;8 pub 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 .9 pub l i c i n t maxDepth ; // f o r at kunne s a e t t e en max dybde paa

soegningen1011 pub l i c AITaijiMinimax ( Tai j iModel m) {12 t h i s . tModel = m;13 }1415 // F r e m s t i l l e r t r a e e t med udgangs punkt i det nuvaerende braet .16 pub l i c void createTree ( )17 {18 tNode = new Node ( ) ;19 Node i n i t = tNode . createNode ( tModel . currentTurn ,

tModel ) ;20 count = 1 ;21 // i n t b [ ] [ ] = tModel . getOneBoard ( tModel . currentTurn ) ;22 //Node t e s t = tNode . createCloneNode ( i n i t ) ;23 //System . out . p r i n t l n (” t e s t . par ”+t e s t . par ) ;24 tTree = new Tree ( ) ;25 tTree . setRoot ( i n i t ) ;2627 i n t maxTurns = tModel . maxTurnsLeft ( ) ;28 System . out . p r i n t l n (” minimax max turns l e f t ”+maxTurns )

;29 setMaxDepth (1 ) ;30 //System . out . p r i n t l n (” i n i t ”) ;31 //System . out . p r i n t l n (” ”+ i n i t +” ”+ i n i t . par+” ”+ i n i t . a+”

”+ i n i t . bc+” ”+ i n i t . br+” ”+ i n i t . wc+” ”+ i n i t . wr+” ”+i n i t . c h i l d r e n+” ”+ i n i t . nodeBoard+” ”+ i n i t . d ) ;

32 //System . out . p r i n t l n ( i n i t . nodeBoard [ 0 ] [ 0 ] + ” ”+ i n i t .nodeBoard [ 1 ] [ 0 ] + ” ”+ i n i t . nodeBoard [ 2 ] [ 0 ] ) ;

33 //System . out . p r i n t l n ( i n i t . nodeBoard [ 0 ] [ 1 ] + ” ”+ i n i t .nodeBoard [ 1 ] [ 1 ] + ” ”+ i n i t . nodeBoard [ 2 ] [ 1 ] ) ;

34 //System . out . p r i n t l n ( i n i t . nodeBoard [ 0 ] [ 2 ] + ” ”+ i n i t .nodeBoard [ 1 ] [ 2 ] + ” ”+ i n i t . nodeBoard [ 2 ] [ 2 ] ) ;

3536 //System . out . p r i n t l n (” minimax createChi ldren ”) ;37 c r ea t eCh i ld r en ( i n i t , 0) ;

A.4 AITaijiMinimax.java 143

38 //printOddGen ( ) ;39 //System . out . p r i n t l n (” ”) ;40 c r ea t eCh i ld r en ( tTree . oddGen . get (1 ) , 1) ;41 // printEvenGen ( ) ;42 //System . out . p r i n t l n (” minimax createLeaves ”) ;43 c reateLeaves ( ) ;44 calcScoreOnLeaves ( ) ;45 // pr in tF ina lLeave s ( ) ;46 //System . out . p r i n t l n (” ca l cTree ”) ;47 // pr intLeaves ( ) ;48 // System . out . p r i n t l n (” minimax calcTree ”) ;49 ca l cTree ( ) ;50 System . out . p r i n t l n (”Number o f nodes c rea ted : ”+count ) ;51 count =0;52 //addLeavesToGen (4) ;53 // calcGen (4) ;54 // printMax ( ) ;55 //printOddGen ( ) ;5657 }58596061 // Laver en node/barn f o r hvert mul igt t raek f r a f o r a e l d r e noden

. Laver a l t s a a en gene ra t i on a f boern .62 p r i v a t e void c r ea t eCh i ld r en (Node p , i n t d)63 {64 i n t [ ] [ ] b = p . nodeBoard ;65 f o r ( i n t c=0; c < tModel . noCols ; c++){66 f o r ( i n t r =0; r < tModel . noRows−1; r++){67 i f (b [ c ] [ r ] == 2 && b [ c ] [ r +1] == 2 ) {68 b [ c ] [ r ] = 1 ;69 b [ c ] [ r +1] = 0 ;70 i n t i ;71 i = checkBoardInd iv idua l i ty (b , d) ;72 //System . out . p r i n t l n (” minimax checkBI i= ”+i ) ;73 i f ( i >= 0) {74 i f (d % 2 == 1)75 tTree . evenGen . get ( i ) . par . add (p) ;76 i f (d % 2 == 0)77 tTree . oddGen . get ( i ) . par . add (p) ;78 }79 i f ( i == −1){80 i f (d % 2 == 1) {81 tTree . evenGen . add (p . addChild ( tNode .

createChi ldNode ( c , r , c , r +1, p) ) ) ;82 count++;83 }84 i f (d % 2 == 0) {85 tTree . oddGen . add (p . addChild ( tNode .

createChi ldNode ( c , r , c , r +1, p) ) ) ;86 count++;87 }88 }89

144 Bilag A

90 b [ c ] [ r ] = 0 ;91 b [ c ] [ r +1] = 1 ;92 i = checkBoardInd iv idua l i ty (b , d) ;93 //System . out . p r i n t l n (” minimax checkBI2 i= ”+i ) ;94 i f ( i >= 0) {95 i f (d % 2 == 1)96 tTree . evenGen . get ( i ) . par . add (p) ;97 i f (d % 2 == 0)98 tTree . oddGen . get ( i ) . par . add (p) ;99 }

100 i f ( i == −1){101 i f (d % 2 == 1) {102 tTree . evenGen . add (p . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , p ) ) ) ;103 count++;104 }105 i f (d % 2 == 0) {106 tTree . oddGen . add (p . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , p ) ) ) ;107 count++;108 }109 }110 b [ c ] [ r ] = 2 ;111 b [ c ] [ r +1] = 2 ;112113 // tTree . addLeave (p . addChild ( tNode .

createChi ldNode ( c , r , c , r +1, p) ) ) ;114 // tTree . addLeave (p . addChild ( tNode .

createChi ldNode ( c , r +1, c , r , p ) ) ) ;115 }116117 }118 }119 f o r ( i n t c=0; c < tModel . noCols−1; c++){120 f o r ( i n t r =0; r < tModel . noRows ; r++){121 i f (b [ c ] [ r ] == 2 && b [ c +1] [ r ] == 2 ) {122 b [ c ] [ r ] = 1 ;123 b [ c +1] [ r ] = 0 ;124 i n t i ;125 i = checkBoardInd iv idua l i ty (b , d) ;126 //System . out . p r i n t l n (” minimax checkBoardIndi i

= ”+i ) ;127 i f ( i >= 0) {128 i f (d % 2 == 1)129 tTree . evenGen . get ( i ) . par . add (p) ;130 i f (d % 2 == 0)131 tTree . oddGen . get ( i ) . par . add (p) ;132 }133 i f ( i == −1){134 i f (d % 2 == 1) {135 tTree . evenGen . add (p . addChild ( tNode .

createChi ldNode ( c , r , c+1, r , p ) ) ) ;136 count++;137 }138 i f (d % 2 == 0) {

A.4 AITaijiMinimax.java 145

139 tTree . oddGen . add (p . addChild ( tNode .createChi ldNode ( c , r , c+1, r , p ) ) ) ;

140 count++;141 }142 }143144 b [ c ] [ r ] = 0 ;145 b [ c +1] [ r ] = 1 ;146 i = checkBoardInd iv idua l i ty (b , d) ;147 i f ( i >= 0) {148 i f (d % 2 == 1)149 tTree . evenGen . get ( i ) . par . add (p) ;150 i f (d % 2 == 0)151 tTree . oddGen . get ( i ) . par . add (p) ;152 }153 i f ( i == −1){154 i f (d % 2 == 1) {155 tTree . evenGen . add (p . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , p ) ) ) ;156 count++;}157 i f (d % 2 == 0) {158 tTree . oddGen . add (p . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , p ) ) ) ;159 count++;160 }161 }162 b [ c ] [ r ] = 2 ;163 b [ c +1] [ r ] = 2 ;164 // tTree . addLeave (p . addChild ( tNode .

createChi ldNode ( c , r , c+1, r , p ) ) ) ;165 // tTree . addLeave (p . addChild ( tNode .

createChi ldNode ( c+1, r , c , r , p ) ) ) ;166 }167 }168 }169 }170171 // Checker om et braet a l l e r e d e e k s i s t e r e i en node ,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 braet e l l e r −1,

hv i s der ikke f i n d e s en173 p r i v a t e i n t checkBoardInd iv idua l i ty ( i n t [ ] [ ] b , i n t d) {174 i f (d % 2 == 1) {175 //System . out . p r i n t l n (” minimax checkBI s i z e even ”+tTree .

evenGen . s i z e ( ) ) ;176 f o r ( i n t i = 0 ; i<tTree . evenGen . s i z e ( ) ; i++){177 i f ( tModel . tBoard . compareBoardsBool (b , tTree . evenGen .

get ( i ) . nodeBoard ) ) {178 //System . out . p r i n t l n (” minimax checkBoardIndi i= ”+i

) ;179 re turn ( i ) ;180 }181 }182 }183184 i f (d % 2 == 0) {

146 Bilag A

185 //System . out . p r i n t l n (” minimax checkBI s i z e odd ”+tTree .oddGen . s i z e ( ) ) ;

186 f o r ( i n t i = 0 ; i<tTree . oddGen . s i z e ( ) ; i++){187 i f ( tModel . tBoard . compareBoardsBool (b , tTree . oddGen . get

( i ) . nodeBoard ) ) {188 //System . out . p r i n t l n (” minimax checkBoardIndi2 i= ”+

i ) ;189 re turn ( i ) ;190 }191 }192 }193 //System . out . p r i n t l n (” minimax checkBoardIndi3 i = −1”) ;194 re turn (−1) ;195 }196197 p r i v a t e i n t checkBoardIndiv idua l i tyV2 ( i n t [ ] [ ] b , i n t d) {198 i f (d % 2 == 1) {199 //System . out . p r i n t l n (” minimax checkBI s i z e even ”+tTree .

evenGen . s i z e ( ) ) ;200 f o r ( i n t i = 0 ; i<tTree . evenGen . s i z e ( ) ; i++){201 i f ( tModel . tBoard . compareBoardsBool (b , tTree . evenGen .

get ( i ) . nodeBoard ) ) {202 //System . out . p r i n t l n (” minimax checkBoardIndi i= ”+i

) ;203 re turn ( i ) ;204 }205 }206 }207208 i f (d % 2 == 0) {209 //System . out . p r i n t l n (” minimax checkBI s i z e odd ”+tTree .

oddGen . s i z e ( ) ) ;210 f o r ( i n t i = 0 ; i<tTree . oddGen . s i z e ( ) ; i++){211 i f ( tModel . tBoard . compareBoardsBool (b , tTree . oddGen . get

( i ) . nodeBoard ) ) {212 //System . out . p r i n t l n (” minimax checkBoardIndi2 i= ”+

i ) ;213 re turn ( i ) ;214 }215 }216 }217 //System . out . p r i n t l n (” minimax checkBoardIndi3 i = −1”) ;218 re turn (−1) ;219 }220221 // sammenligner to braet222 // r e t u r n e r e r t rue hv i s de er ens223224225226227 // l a v e r t r a e e t og gemmer bladerne i Leaves228 pub l i c void c reateLeaves ( ) {229 f o r ( i n t d=1; d <= maxDepth ; d++){230 i f (d % 2 == 1) {

A.4 AITaijiMinimax.java 147

231 f o r ( i n t i = 0 ; i < tTree . oddGen . s i z e ( ) ; i++){232 c r ea t eCh i ld r en ( tTree . oddGen . get ( i ) , d ) ;233 }234 oddGenToLeaves ( ) ;235 // i f (d != 1)236 tTree . oddGen . c l e a r ( ) ;237 }238 i f (d % 2 == 0) {239 f o r ( i n t i = 0 ; i < tTree . evenGen . s i z e ( ) ; i++){240 c r ea t eCh i ld r en ( tTree . evenGen . get ( i ) , d ) ;241 }242 evenGenToLeaves ( ) ;243 tTree . evenGen . c l e a r ( ) ;244 }245 }246 //Node t = tNode . createCloneNode ( tTree . Leaves [ 1 ] ) ;247 // c r ea t eCh i ld r en ( t ) ;248 //System . out . p r i n t l n (” createGen ”+tTree . Leaves . get (0 ) ) ;249 // f o r ( i n t i =0; i<tTree . Leaves . s i z e ( ) ; i++)250 //{251 // System . out . p r i n t l n ( i+” ”+tTree . Leaves . s i z e ( ) ) ;252 // i f ( tModel . movesLeftN ( tTree . Leaves . get ( i ) ) ) {253 //Node temp = tNode . createCloneNode ( tTree . Leaves [ i

] ) ;254 // i f ( temp == n u l l )255 // System . out . p r i n t l n (”ARG NULL! ” ) ;256 // e l s e257 // System . out . p r i n t l n (”No n u l l ”) ;258259 // i n t tempA = temp . a ;260 //System . out . p r i n t l n (” minimax createGen : Node= ”+

temp+” a= ”+tempA) ;261 // c r ea t eCh i ld r en ( tTree . Leaves . get ( i ) ) ;262 // i f ( tTree . Leaves . get ( i ) . d % 2 == 0)263 // tTree . Leaves . get ( i ) . a=tModel . noRows∗ tModel .

noCols ; // s a e t t e r s co r e t i l e t abso lut maximum264 // i f ( tTree . Leaves . get ( i ) . d % 2 == 1)265 // tTree . Leaves . get ( i ) . a=−tModel . noRows∗ tModel .

noCols ; // s a e t t e r s co r e t i l e t abso lu t minimum266 //System . out . p r i n t l n (” a ”+tTree . Leaves [ i ] . a+” ”+

tTree . Leaves [ i ] . d ) ;267 // tTree . removeLeave ( i ) ;268 // i−−;269 //System . out . p r i n t l n (” i ”+ i ) ;270 // }271272 // }273 // tTree . dept = tTree . dept +1;274 //System . out . p r i n t l n (” Dept ”+tTree . dept ) ;275 }276277 p r i v a t e void calcScoreOnLeaves ( ) {278 f o r ( i n t i =0; i<tTree . Leaves . s i z e ( ) ; i++)279 tTree . Leaves . get ( i ) . a = tModel . g e tD i f ( tTree . Leaves . get (

i ) . nodeBoard ) ;

148 Bilag A

280 }281282 // f l y t t e r noder t i l Leaves hv i s de er f i n a l s t a t e s , e l l e r s

s a e t t e s s co r e t i l min283 p r i v a t e void oddGenToLeaves ( ) {284 f o r ( i n t i = 0 ; i<tTree . oddGen . s i z e ( ) ; i++){285 i f ( tModel . movesLeftN ( tTree . oddGen . get ( i ) ) )286 tTree . oddGen . get ( i ) . a=−tModel . noRows∗ tModel . noCols ;287 e l s e288 tTree . Leaves . add ( tTree . oddGen . get ( i ) ) ;289 }290 }291 // f l y t t e r noder t i l Leaves hv i s de er f i n a l s t a t e s , e l l e r s

s a e t t e s s co r e t i l max292 p r i v a t e void evenGenToLeaves ( ) {293 f o r ( i n t i = 0 ; i<tTree . evenGen . s i z e ( ) ; i++){294 i f ( tModel . movesLeftN ( tTree . evenGen . get ( i ) ) )295 tTree . evenGen . get ( i ) . a=tModel . noRows∗ tModel . noCols ;296 e l s e297 tTree . Leaves . add ( tTree . evenGen . get ( i ) ) ;298 }299 }300301 p r i v a t e void ca l cTree ( ) {302 f o r ( i n t d = maxDepth ; d>0; d−−){303 addLeavesToGen (d) ;304 calcGen (d) ;305 clearGen (d) ;306 }307 }308309 // T i l f o e j e r a l l e node i Leaves med dybden d t i l enten evenGen

e l l e r oddGen310 p r i v a t e void addLeavesToGen ( i n t d) {311 f o r ( i n t i =0; i<tTree . Leaves . s i z e ( ) ; i++){312 i f (d == tTree . Leaves . get ( i ) . d ) {313 i f (d % 2 == 0)314 i f ( ! tTree . evenGen . conta in s ( tTree . Leaves . get ( i ) ) )315 tTree . evenGen . add ( tTree . Leaves . get ( i ) ) ;316 i f (d % 2 == 1)317 i f ( ! tTree . oddGen . conta in s ( tTree . Leaves . get ( i ) ) )318 tTree . oddGen . add ( tTree . Leaves . get ( i ) ) ;319 }320 }321 }322323 p r i v a t e void calcGen ( i n t d) {324 i f (d % 2 == 0) {325 f o r ( i n t i =0; i<tTree . evenGen . s i z e ( ) ; i++){326 f o r ( i n t j =0; j<tTree . evenGen . get ( i ) . par . s i z e ( ) ; j++){327 i f ( ! tTree . oddGen . conta in s ( tTree . evenGen . get ( i ) . par

. get ( j ) ) )328 tTree . oddGen . add ( tTree . evenGen . get ( i ) . par . get ( j

) ) ;

A.4 AITaijiMinimax.java 149

329 i f ( tTree . evenGen . get ( i ) . a > tTree . evenGen . get ( i ) .par . get ( j ) . a )

330 tTree . evenGen . get ( i ) . par . get ( j ) . a = tTree .evenGen . get ( i ) . a ;

331 }332 }333 }334 i f (d % 2 == 1) {335 f o r ( i n t i =0; i<tTree . oddGen . s i z e ( ) ; i++){336 f o r ( i n t j =0; j<tTree . oddGen . get ( i ) . par . s i z e ( ) ; j++){337 i f ( ! tTree . evenGen . conta in s ( tTree . oddGen . get ( i ) . par

. get ( j ) ) )338 tTree . evenGen . add ( tTree . oddGen . get ( i ) . par . get ( j

) ) ;339 i f ( tTree . oddGen . get ( i ) . a < tTree . oddGen . get ( i ) . par

. get ( j ) . a )340 tTree . oddGen . get ( i ) . par . get ( j ) . a = tTree .

oddGen . get ( i ) . a ;341 }342 }343 }344 }345346 p r i v a t e void clearGen ( i n t d) {347 i f (d % 2 == 0)348 tTree . evenGen . c l e a r ( ) ;349 i f (d % 2 == 1 && d != 1)350 tTree . oddGen . c l e a r ( ) ;351 }352353 //}354355 // p r i v a t e void minMin ( ) {356 // i f ( ! checkMaxMin ( ) )357 // System . out . p r i n t l n (” minimax minMin n u l l ”) ;358 // f o r ( i n t i = 0 ; i<tTree . curMin ; i++){359 // i f ( tTree . min [ i ] . par == n u l l )360 // System . out . p r i n t l n (”minMin Nul l ”+ i ) ;361 // i f ( tTree . min [ i ] . par . a < tTree . min [ i ] . a ) {362 // tTree . min [ i ] . par . a = tTree . min [ i ] . a ;363 // //System . out . p r i n t l n (” minMin a ”+tTree . min [ i

] . a+” par . a ”+tTree . min [ i ] . par . a ) ;364 // i f ( ! tTree . checkMax ( tTree . min [ i ] . par ) )365 // tTree . addMax( tTree . min [ i ] . par ) ;366 // }367 // }368 //}369370 // p r i v a t e void maxMax( ) {371 // i f ( ! checkMaxMin ( ) )372 // System . out . p r i n t l n (”minimax maxMax n u l l ”) ;373 // i f ( ! checkMaxMinPar ( ) )374 // System . out . p r i n t l n (”minimax maxMax par n u l l ”) ;375 //System . out . p r i n t l n (”maxMax curMax ”+tTree . curMax ) ;376 // f o r ( i n t i = 0 ; i<tTree . curMax ; i++){

150 Bilag A

377 // i f ( tTree . max [ i ] . d > 0) { // f o r at undgaa n u l lpo in t e r hv i s roden er med i ”max”

378 // i f ( tTree . max [ i ] . par == n u l l )379 // //System . out . p r i n t l n (”maxMax Null i ”+ i+”

curMax ”+tTree . curMax+” D ”+tTree . max [ i ] . d ) ;380 // i f ( tTree . max [ i ] . par . a < tTree . max [ i ] . a ) {381 // tTree . max [ i ] . par . a = tTree . max [ i ] . a ;382 // //System . out . p r i n t l n (” minMin a ”+tTree .

max [ i ] . a+” par . a ”+tTree . max [ i ] . par . a ) ;383 // i f ( ! tTree . checkMin ( tTree . max [ i ] . par ) )384 // tTree . addMin ( tTree . max [ i ] . par ) ;385 // }386 // }387 // }388 //}389390 pub l i c Node returnMove ( ) {391 Node n ;392 n = tTree . oddGen . get (0 ) ;393 i f ( tTree . oddGen . s i z e ( ) > 1) {394 f o r ( i n t i = 0 ; i<tTree . oddGen . s i z e ( ) ; i++){395 i f (n . a>tTree . oddGen . get ( i ) . a ) {396 n=tTree . oddGen . get ( i ) ;397 }398 }399 }400 re turn (n) ;401 }402403 // r e t u r n e r e r det t raek der s k a l tage s ved at r e t u r n e r e r noden

med som indeho lde r traekket , vaer opmaerksom404 // paa at nodens braet ikke er b l ev e t r o t t e r e t kun s e l v e

t raekke t der s k a l f o r e t a g e s .405 pub l i c Node returnMoveMirRot ( ) {406 Random randomVal = new Random( ) ;407 Node n ;408 ArrayList<Node> move = new ArrayList<Node>() ;409 i n t wC,wR, bC,bR, ran ;410 n = tTree . oddGen . get (0 ) ;411 i f ( tTree . oddGen . s i z e ( ) > 1) {412 f o r ( i n t i = 0 ; i<tTree . oddGen . s i z e ( ) ; i++){413 i f (n . a>tTree . oddGen . get ( i ) . a ) {414 n=tTree . oddGen . get ( i ) ;415 }416 }417 f o r ( i n t i = 0 ; i<tTree . oddGen . s i z e ( ) ; i++){418 i f (n . a==tTree . oddGen . get ( i ) . a ) {419 move . add ( tTree . oddGen . get ( i ) ) ;420 }421 }422 ran = randomVal . next Int (move . s i z e ( ) ) ;423 n = move . get ( ran ) ;424 }425426 wC = n . wc ;

A.4 AITaijiMinimax.java 151

427 wR = n . wr ;428 bC = n . bc ;429 bR = n . br ;430 n . nodeBoard [wC] [wR]=2;431 n . nodeBoard [bC ] [ bR]=2;432433 i n t mr = tModel . tBoard . compareBoardsInt (n . nodeBoard , tModel

. tBoard . board [ tModel . currentTurn ] ) ;434 i f (mr == 1) {435 re turn (n) ;436 }437 i f (mr == 2) {438 n . br = tModel . noRows−1 − bR;439 n . wr = tModel . noRows−1 − wR;440 re turn (n) ;441 }442 i f (mr == 3) {443 n . bc = tModel . noCols−1 − bC;444 n . wc = tModel . noCols−1 − wC;445 re turn (n) ;446 }447 i f (mr == 4) {448 n . bc = tModel . noCols−1 − bC;449 n . wc = tModel . noCols−1 − wC;450 n . br = tModel . noRows−1 − bR;451 n . wr = tModel . noRows−1 − wR;452 re turn (n) ;453 }454 i f (mr == 5) {455 n . bc = bR;456 n . wc = wR;457 n . br = bC;458 n . wr = wC;459 re turn (n) ;460 }461 i f (mr == 6) {462 n . bc = tModel . noRows−1 − bR;463 n . wc = tModel . noRows−1 − wR;464 n . br = bC;465 n . wr = wC;466 re turn (n) ;467 }468 i f (mr == 7) {469 n . bc = bR;470 n . wc = wR;471 n . br = tModel . noCols−1 − bC;472 n . wr = tModel . noCols−1 − wC;473 re turn (n) ;474 }475 i f (mr == 8) {476 n . bc = tModel . noRows−1 − bR;477 n . wc = tModel . noRows−1 − wR;478 n . br = tModel . noCols−1 − bC;479 n . wr = tModel . noCols−1 − wC;480 re turn (n) ;

152 Bilag A

481 }482 re turn (n) ;483 }484485486 p r i v a t e void pr intLeaves ( ) {487 System . out . p r i n t l n (” Current Leaves ”) ;488 f o r ( i n t i =0; i<tTree . Leaves . s i z e ( ) ; i++){489 System . out . p r i n t l n ( i+” ”+tTree . Leaves . get ( i )+”

Depth : ”+tTree . Leaves . get ( i ) . d+” Score ”+tTree .Leaves . get ( i ) . a ) ;

490 System . out . p r i n t l n ( tTree . Leaves . get ( i ) . par+” ”+tTree . Leaves . get ( i ) . a+” ”+tTree . Leaves . get ( i ) .bc+” ”+tTree . Leaves . get ( i ) . br+” ”+tTree . Leaves .get ( i ) . wc+” ”+tTree . Leaves . get ( i ) . wr+” ”+tTree .Leaves . get ( i ) . c h i l d r e n+” ”+tTree . Leaves . get ( i ) .nodeBoard ) ;

491 System . out . p r i n t l n ( tTree . Leaves . get ( i ) . nodeBoard[ 0 ] [ 0 ] + ” ”+tTree . Leaves . get ( i ) . nodeBoard[ 1 ] [ 0 ] + ” ”+tTree . Leaves . get ( i ) . nodeBoard [ 2 ] [ 0 ] );

492 System . out . p r i n t l n ( tTree . Leaves . get ( i ) . nodeBoard[ 0 ] [ 1 ] + ” ”+tTree . Leaves . get ( i ) . nodeBoard[ 1 ] [ 1 ] + ” ”+tTree . Leaves . get ( i ) . nodeBoard [ 2 ] [ 1 ] );

493 System . out . p r i n t l n ( tTree . Leaves . get ( i ) . nodeBoard[ 0 ] [ 2 ] + ” ”+tTree . Leaves . get ( i ) . nodeBoard[ 1 ] [ 2 ] + ” ”+tTree . Leaves . get ( i ) . nodeBoard [ 2 ] [ 2 ] );

494 System . out . p r i n t l n ( ) ;495 }496 }497498 p r i v a t e void printEvenGen ( ) {499 System . out . p r i n t l n (”EvenGen”) ;500 f o r ( i n t i =0; i<tTree . evenGen . s i z e ( ) ; i++){501 System . out . p r i n t l n ( i+” ”+tTree . evenGen . get ( i )+”

Depth : ”+tTree . evenGen . get ( i ) . d+” Score ”+tTree. evenGen . get ( i ) . a ) ;

502 System . out . p r i n t l n ( tTree . evenGen . get ( i ) . par+” ”+tTree . evenGen . get ( i ) . a+” ”+tTree . evenGen . get ( i ). bc+” ”+tTree . evenGen . get ( i ) . br+” ”+tTree .evenGen . get ( i ) . wc+” ”+tTree . evenGen . get ( i ) . wr+””+tTree . evenGen . get ( i ) . c h i l d r e n+” ”+tTree .

evenGen . get ( i ) . nodeBoard ) ;503 System . out . p r i n t l n ( tTree . evenGen . get ( i ) . nodeBoard

[ 0 ] [ 0 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard[ 1 ] [ 0 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard[ 2 ] [ 0 ] ) ;

504 System . out . p r i n t l n ( tTree . evenGen . get ( i ) . nodeBoard[ 0 ] [ 1 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard[ 1 ] [ 1 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard[ 2 ] [ 1 ] ) ;

505 System . out . p r i n t l n ( tTree . evenGen . get ( i ) . nodeBoard[ 0 ] [ 2 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard

A.4 AITaijiMinimax.java 153

[ 1 ] [ 2 ] + ” ”+tTree . evenGen . get ( i ) . nodeBoard[ 2 ] [ 2 ] ) ;

506 System . out . p r i n t l n ( ) ;507 }508 }509510 p r i v a t e void printOddGen ( ) {511 System . out . p r i n t l n (”OddGen”) ;512 f o r ( i n t i =0; i<tTree . oddGen . s i z e ( ) ; i++){513 System . out . p r i n t l n ( i+” ”+tTree . oddGen . get ( i )+”

Depth : ”+tTree . oddGen . get ( i ) . d+” Score ”+tTree .oddGen . get ( i ) . a ) ;

514 System . out . p r i n t l n ( tTree . oddGen . get ( i ) . par+” ”+tTree . oddGen . get ( i ) . a+” ”+tTree . oddGen . get ( i ) .bc+” ”+tTree . oddGen . get ( i ) . br+” ”+tTree . oddGen .get ( i ) . wc+” ”+tTree . oddGen . get ( i ) . wr+” ”+tTree .oddGen . get ( i ) . c h i l d r e n+” ”+tTree . oddGen . get ( i ) .nodeBoard ) ;

515 System . out . p r i n t l n ( tTree . oddGen . get ( i ) . nodeBoard[ 0 ] [ 0 ] + ” ”+tTree . oddGen . get ( i ) . nodeBoard[ 1 ] [ 0 ] + ” ”+tTree . oddGen . get ( i ) . nodeBoard [ 2 ] [ 0 ] );

516 System . out . p r i n t l n ( tTree . oddGen . get ( i ) . nodeBoard[ 0 ] [ 1 ] + ” ”+tTree . oddGen . get ( i ) . nodeBoard[ 1 ] [ 1 ] + ” ”+tTree . oddGen . get ( i ) . nodeBoard [ 2 ] [ 1 ] );

517 System . out . p r i n t l n ( tTree . oddGen . get ( i ) . nodeBoard[ 0 ] [ 2 ] + ” ”+tTree . oddGen . get ( i ) . nodeBoard[ 1 ] [ 2 ] + ” ”+tTree . oddGen . get ( i ) . nodeBoard [ 2 ] [ 2 ] );

518 System . out . p r i n t l n ( ) ;519 }520 }521522523524 // p r i v a t e void printLeavePar ( i n t i ) {525 // System . out . p r i n t l n (” Current Leaves ”) ;526 // i n t s = tTree . Leaves [ i ] . c h i l d r e n . s i z e ( ) ;527 // f o r ( i n t j =0; j<=s ; j++){528 // System . out . p r i n t l n ( i+” ”+tTree . Leaves [ i ]+” Depth :

”+tTree . Leaves [ i ] . d+” Score ”+tTree . Leaves [ i ] . a ) ;529 // System . out . p r i n t l n ( tTree . Leaves [ i ] . par+” ”+tTree .

Leaves [ i ] . a+” ”+tTree . Leaves [ i ] . bc+” ”+tTree . Leaves [ i ] . br+””+tTree . Leaves [ i ] . wc+” ”+tTree . Leaves [ i ] . wr+” ”+tTree .

Leaves [ i ] . c h i l d r e n+” ”+tTree . Leaves [ i ] . nodeBoard ) ;530 // System . out . p r i n t l n ( tTree . Leaves [ i ] . c h i l d r e n . get ( j

) . nodeBoard [ 0 ] [ 0 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .nodeBoard [ 1 ] [ 0 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .nodeBoard [ 2 ] [ 0 ] ) ;

531 // System . out . p r i n t l n ( tTree . Leaves [ i ] . c h i l d r e n . get ( j) . nodeBoard [ 0 ] [ 1 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .nodeBoard [ 1 ] [ 1 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .nodeBoard [ 2 ] [ 1 ] ) ;

154 Bilag A

532 // System . out . p r i n t l n ( tTree . Leaves [ i ] . c h i l d r e n . get ( j) . nodeBoard [ 0 ] [ 2 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .nodeBoard [ 1 ] [ 2 ] + ” ”+tTree . Leaves [ i ] . c h i l d r e n . get ( j ) .nodeBoard [ 2 ] [ 2 ] ) ;

533 // System . out . p r i n t l n ( ) ;534 // }535 //}536537 p r i v a t e boolean checkMaxMin ( ) {538 f o r ( i n t i = 0 ; i < tTree . oddGen . s i z e ( ) ; i++){539 i f ( tTree . oddGen . get ( i ) == n u l l ) {540 System . out . p r i n t l n (” Nul l i ”+ i+” s i z e even ”+tTree

. curMax ) ;541 re turn ( f a l s e ) ;542 }543 }544 f o r ( i n t j = 0 ; j < tTree . evenGen . s i z e ( ) ; j++){545 i f ( tTree . evenGen . get ( j ) == n u l l ) {546 System . out . p r i n t l n (” Nul l j ”+j+” s i z e odd ”+tTree .

curMin ) ;547 re turn ( f a l s e ) ;548 }549550 }551 re turn ( t rue ) ;552 }553554 p r i v a t e boolean checkMaxMinPar ( ) {555 f o r ( i n t i = 0 ; i < tTree . oddGen . s i z e ( ) ; i++){556 i f ( tTree . oddGen . get ( i ) . par == n u l l ) {557 System . out . p r i n t l n (” Nul l Par i ”+ i+” odd ”+tTree .

oddGen . s i z e ( ) ) ;558 re turn ( f a l s e ) ;559 }560 }561 f o r ( i n t j = 0 ; j < tTree . evenGen . s i z e ( ) ; j++){562 i f ( tTree . evenGen . get ( j ) . par == n u l l ) {563 System . out . p r i n t l n (” Nul l Par j ”+j+” even ”+tTree .

evenGen . s i z e ( ) ) ;564 re turn ( f a l s e ) ;565 }566567 }568 re turn ( t rue ) ;569 }570571 // er s a e t t e s maxDepth572 p r i v a t e void setMaxDepth ( i n t mode) {573 // i ”Mode 0” f o r s o e g e r den at regne he l e t r a e e t igennem574 i f (mode == 0) {575 maxDepth = ( tModel . noCols∗ tModel . noRows/2) ;576 System . out . p r i n t l n (” minimax Mode 0 maxDepth = ”+

maxDepth) ;577 }

A.5 Board.java 155

578 // i ”Mode 1” s a e t t e s max fremregningen t i l 2 , hv i s der ermere en 5 traek t i l b a g e ,

579 // e l l e r s regner den h e l t igennem .580 i f (mode == 1) {581 i n t maxT = tModel . maxTurnsLeft ( ) ;582 i f (maxT > 10)583 maxDepth = 2 ;584 i f (maxT > 5 && maxT <= 10)585 maxDepth = 3 ;586 i f (maxT <= 5)587 maxDepth = maxT;588 System . out . p r i n t l n (” minimax Mode 1 maxDepth = ”+

maxDepth) ;589 }590 }591 }

A.5 Board.java

123 pub l i c c l a s s Board implements Cloneable {45 pub l i c i n t [ ] [ ] [ ] board ;6 p r i v a t e i n t [ ] [ ] oneBoard ;7 p r i v a t e i n t [ ] [ ] c l one ;8 // Konstanter f o r de f o r s k e l l i g e b r i kke r paa b r a e t t e t .9 f i n a l p r i v a t e i n t white = 1 , b lack = 0 , neu t ra l = 2 ;

1011 p r i v a t e Tai j iModel tModel ;1213 pub l i c Board ( Tai j iModel m)14 {15 tModel = m;16 board = new i n t [ tModel . maxTurns ] [ tModel . noCols ] [ tModel .

noRows ] ;17 oneBoard = new i n t [ tModel . noCols ] [ tModel . noRows ] ;18 }1920 // Henter fa rven paa et f e l t i paa s e l v e brae t t e t , der v i s e s paa

skaermen .21 pub l i c i n t getPieceAt ( i n t co l , i n t row )22 {23 re turn ( board [ tModel . currentTurn ] [ c o l ] [ row ] ) ;24 }2526 // Returnerer a l l e s p i l b r a e t n e f o r a l l e t raek gennem s p i l l e t .27 pub l i c i n t [ ] [ ] [ ] getBoard ( )28 {29 re turn ( board ) ;30 }3132 // Return b r a e t t e t f o r en enke l t tur i s p i l l e t .

156 Bilag A

33 pub l i c i n t [ ] [ ] getOneBoard ( i n t t )34 {35 oneBoard = board [ t ] ;36 re turn oneBoard ;3738 }3940 // P lac e r e r en br ik ( neutra l , white e l l e r b lack ) paa et f e l t i

den nuvaerende tur .41 //Modtager p o s i t i o n e n og farven paa br ikken som argument .42 pub l i c void s e t P i e c e ( i n t co l , i n t row , i n t p i e c e )43 {44 board [ tModel . currentTurn ] [ c o l ] [ row ] = p i e c e ;45 }4647 // Reset . Toemmer brae 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

udgangspos i t ionen .48 pub l i c void resetBoard ( )49 {50 i n t C = tModel . getNoCols ( ) ;51 i n t R = tModel . getNoRows ( ) ;5253 f o r ( i n t c = 0 ; c < C; c++)54 {55 f o r ( i n t r = 0 ; r < R; r++)56 {57 s e t P i e c e ( c , r , 2 ) ;58 }59 }60 board [ 0 ] [ 0 ] [ 0 ] = 1 ;61 }6263 // Kopiere b r a e t t e t f r a den nuvaerende tur t i l den naes te .64 pub l i c void copyBoard ( )65 {66 f o r ( i n t c=0; c < tModel . noCols ; c++)67 f o r ( i n t r =0; r < tModel . noRows ; r++)68 board [ tModel . currentTurn +1] [ c ] [ r ] = board [ tModel .

currentTurn ] [ c ] [ r ] ;69 }70 // Kopiere b r a e t t e t f r a den nuvaerende tur t i l tur t .71 pub l i c void copyBoardTo ( i n t t )72 {73 f o r ( i n t c=0; c < tModel . noCols ; c++)74 f o r ( i n t r =0; r < tModel . noRows ; r++)75 board [ tModel . currentTurn+t ] [ c ] [ r ] = board [ tModel .

currentTurn ] [ c ] [ r ] ;76 }7778 // Laver en klon a f b r a e t t e t f o r tur t79 pub l i c void cloneBoard ( i n t t )80 {81 c lone = new i n t [ tModel . noCols ] [ tModel . noRows ] ;82 f o r ( i n t c=0; c < tModel . noCols ; c++)83 f o r ( i n t r =0; r < tModel . noRows ; r++)

A.5 Board.java 157

84 c lone [ c ] [ r ] = board [ t ] [ c ] [ r ] ;85 }8687 // Kloner et braet og r e t u n e r e r klonen88 pub l i c i n t [ ] [ ] c l one ( i n t [ ] [ ] b )89 {90 c lone = new i n t [ tModel . noCols ] [ tModel . noRows ] ;91 f o r ( i n t c=0; c < tModel . noCols ; c++)92 f o r ( i n t r =0; r < tModel . noRows ; r++)93 c lone [ c ] [ r ] = b [ c ] [ r ] ;94 re turn (b) ;95 }9697 // 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 t98 pub l i c i n t [ ] [ ] getClone ( i n t t )99 {

100 cloneBoard ( t ) ;101 re turn ( c lone ) ;102 }103104 // sammenligner to braet , hv i s de er h e l t ens r e t u r n e r e s t rue105 pub l i c boolean compareBoards ( i n t [ ] [ ] b , i n t [ ] [ ] d ) {106 f o r ( i n t c=0; c < tModel . noCols ; c++){107 f o r ( i n t r =0; r < tModel . noRows ; r++){108 i f ( ( b [ c ] [ r ] != d [ c ] [ r ] ) ) {109 re turn ( f a l s e ) ;110 }111 }112 }113 re turn ( t rue ) ;114 }115116 // Sammenligner to braet , hv i s de er ens ( r o t t e r e t og/ e l l e r

s p e j l v e n d t ) r e t u r n e r e s en vaerd i mellem 1 og 8117 // e f t e r hvordan de er ens (1 er ens uden r o t a t i o n e l l e r

s p e j l v e n d i ng ) . Er de ikke ens r e t u r n e r e s 0118 pub l i c i n t compareBoardsInt ( i n t [ ] [ ] b , i n t [ ] [ ] d ) {119 i n t C = tModel . noCols −1;120 i n t R = tModel . noRows −1;121 boolean br = f a l s e ;122 f o r ( i n t c=0; c < tModel . noCols ; c++){123 f o r ( i n t r =0; r < tModel . noRows ; r++){124 i f (b [ c ] [ r ] != d [ c ] [ r ] ) {125 br = true ;126 break ;127 }128 }129 i f ( br )130 break ;131 }132 i f ( ! br )133 re turn (1 ) ;134135 br = f a l s e ;136 f o r ( i n t c=0; c < tModel . noCols ; c++){

158 Bilag A

137 f o r ( i n t r =0; r < tModel . noRows ; r++){138 i f (b [ c ] [ r ] != d [ c ] [ R−r ] ) {139 br = true ;140 break ;141 }142 }143 i f ( br )144 break ;145 }146 i f ( ! br )147 re turn (2 ) ;148149 br = f a l s e ;150 f o r ( i n t c=0; c < tModel . noCols ; c++){151 f o r ( i n t r =0; r < tModel . noRows ; r++){152 i f (b [ c ] [ r ] != d [C−c ] [ r ] ) {153 br = true ;154 break ;155 }156 }157 i f ( br )158 break ;159 }160 i f ( ! br )161 re turn (3 ) ;162163 br = f a l s e ;164 f o r ( i n t c=0; c < tModel . noCols ; c++){165 f o r ( i n t r =0; r < tModel . noRows ; r++){166 i f (b [ c ] [ r ] != d [C−c ] [ R−r ] ) {167 br = true ;168 break ;169 }170 }171 i f ( br )172 break ;173 }174 i f ( ! br )175 re turn (4 ) ;176177 i f ( tModel . noCols != tModel . noRows) // de f o e l g ende er kun

mulige hvis , b r a e t t e t e r kvadrat i sk178 re turn (0 ) ;179180 br = f a l s e ;181 f o r ( i n t c=0; c < tModel . noCols ; c++){182 f o r ( i n t r =0; r < tModel . noRows ; r++){183 i f (b [ c ] [ r ] != d [ r ] [ c ] ) {184 br = true ;185 break ;186 }187 }188 i f ( br )189 break ;190 }

A.5 Board.java 159

191 i f ( ! br )192 re turn (5 ) ;193194 br = f a l s e ;195 f o r ( i n t c=0; c < tModel . noCols ; c++){196 f o r ( i n t r =0; r < tModel . noRows ; r++){197 i f (b [ c ] [ r ] != d [R−r ] [ c ] ) {198 br = true ;199 break ;200 }201 }202 i f ( br )203 break ;204 }205 i f ( ! br )206 re turn (6 ) ;207208 br = f a l s e ;209 f o r ( i n t c=0; c < tModel . noCols ; c++){210 f o r ( i n t r =0; r < tModel . noRows ; r++){211 i f (b [ c ] [ r ] != d [ r ] [ C−c ] ) {212 br = true ;213 break ;214 }215 }216 i f ( br )217 break ;218 }219 i f ( ! br )220 re turn (7 ) ;221222 br = f a l s e ;223 f o r ( i n t c=0; c < tModel . noCols ; c++){224 f o r ( i n t r =0; r < tModel . noRows ; r++){225 i f (b [ c ] [ r ] != d [R−r ] [ C−c ] ) {226 br = true ;227 break ;228 }229 }230 i f ( br )231 break ;232 }233 i f ( ! br )234 re turn (8 ) ;235236 re turn (0 ) ;237 }238239 // sammenligner to braet , hv i s de er ens ( r o t t e r e t og/ e l l e r

s p e j l v e n d t ) r e t u r n e r e s t rue240 pub l i c boolean compareBoardsBool ( i n t [ ] [ ] b , i n t [ ] [ ] d ) {241 i n t C = tModel . noCols −1;242 i n t R = tModel . noRows −1;243 boolean br = f a l s e ;244 f o r ( i n t c=0; c < tModel . noCols ; c++){

160 Bilag A

245 f o r ( i n t r =0; r < tModel . noRows ; r++){246 i f (b [ c ] [ r ] != d [ c ] [ r ] ) {247 br = true ;248 break ;249 }250 }251 i f ( br )252 break ;253 }254 i f ( ! br )255 re turn ( t rue ) ;256257 br = f a l s e ;258 f o r ( i n t c=0; c < tModel . noCols ; c++){259 f o r ( i n t r =0; r < tModel . noRows ; r++){260 i f (b [ c ] [ r ] != d [ c ] [ R−r ] ) {261 br = true ;262 break ;263 }264 }265 i f ( br )266 break ;267 }268 i f ( ! br )269 re turn ( t rue ) ;270271 br = f a l s e ;272 f o r ( i n t c=0; c < tModel . noCols ; c++){273 f o r ( i n t r =0; r < tModel . noRows ; r++){274 i f (b [ c ] [ r ] != d [C−c ] [ r ] ) {275 br = true ;276 break ;277 }278 }279 i f ( br )280 break ;281 }282 i f ( ! br )283 re turn ( t rue ) ;284285 br = f a l s e ;286 f o r ( i n t c=0; c < tModel . noCols ; c++){287 f o r ( i n t r =0; r < tModel . noRows ; r++){288 i f (b [ c ] [ r ] != d [C−c ] [ R−r ] ) {289 br = true ;290 break ;291 }292 }293 i f ( br )294 break ;295 }296 i f ( ! br )297 re turn ( t rue ) ;298

A.5 Board.java 161

299 i f ( tModel . noCols != tModel . noRows) // de f o e l g ende er kunmulige hvis , b r a e t t e t e r kvadrat i sk

300 re turn ( f a l s e ) ;301302 br = f a l s e ;303 f o r ( i n t c=0; c < tModel . noCols ; c++){304 f o r ( i n t r =0; r < tModel . noRows ; r++){305 i f (b [ c ] [ r ] != d [ r ] [ c ] ) {306 br = true ;307 break ;308 }309 }310 i f ( br )311 break ;312 }313 i f ( ! br )314 re turn ( t rue ) ;315316 br = f a l s e ;317 f o r ( i n t c=0; c < tModel . noCols ; c++){318 f o r ( i n t r =0; r < tModel . noRows ; r++){319 i f (b [ c ] [ r ] != d [R−r ] [ c ] ) {320 br = true ;321 break ;322 }323 }324 i f ( br )325 break ;326 }327 i f ( ! br )328 re turn ( t rue ) ;329330 br = f a l s e ;331 f o r ( i n t c=0; c < tModel . noCols ; c++){332 f o r ( i n t r =0; r < tModel . noRows ; r++){333 i f (b [ c ] [ r ] != d [ r ] [ C−c ] ) {334 br = true ;335 break ;336 }337 }338 i f ( br )339 break ;340 }341 i f ( ! br )342 re turn ( t rue ) ;343344 br = f a l s e ;345 f o r ( i n t c=0; c < tModel . noCols ; c++){346 f o r ( i n t r =0; r < tModel . noRows ; r++){347 i f (b [ c ] [ r ] != d [R−r ] [ C−c ] ) {348 br = true ;349 break ;350 }351 }352 i f ( br )

162 Bilag A

353 break ;354 }355 i f ( ! br )356 re turn ( t rue ) ;357358 re turn ( f a l s e ) ;359 }360 }

A.6 FigureMap.java

1234 pub l i c c l a s s FigureMap {5 p r i v a t e i n t [ ] [ ] f i gBoard ;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

er endnu ikke har vae re t i brug .7 p r i v a t e i n t f igB = 2 ; // Laveste nummer f o r s o r t e f i g u r e r , der

er endnu ikke har vae re t i brug .8 p r i v a t e i n t wh i teP iece s = 0 , b l a ckP i e c e s = 0 ;9 p r i v a t e i n t noCols ; // anta l ko lonner

10 p r i v a t e i n t noRows ; // anta l raekker1112 pub l i c Tai j iModel tModel ;13 pub l i c Node tNode ;1415 pub l i c FigureMap ( Tai j iModel m) {16 t h i s . tModel = m;17 }1819 pub l i c FigureMap (Node n)20 {21 t h i s . tNode = n ;22 }2324 // udregner scoren f o r b r a e t t e t b .25 pub l i c i n t [ ] c a l S co r e ( i n t [ ] [ ] b , i n t co l s , i n t rows )26 {27 noCols = c o l s ;28 noRows = rows ;29 resetFigBoard ( ) ;30 mapFigures (b) ;31 countPieces ( ) ;32 i n t [ ] s c o r e ;33 s co r e = new i n t [ 2 ] ;34 s co r e [0 ]= whi teP iece s ;35 s co r e [1 ]= b lackP i e c e s ;36 re turn ( s co r e ) ;37 }3839 // udregner d i f f e r e n s e n mellem hvid og s o r t s co r e40 pub l i c i n t c a l D i f ( i n t [ ] [ ] b , i n t co l s , i n t rows )

A.6 FigureMap.java 163

41 {42 noCols = c o l s ;43 noRows = rows ;44 resetFigBoard ( ) ;45 mapFigures (b) ;46 countPieces ( ) ;47 i n t s co r e ;48 s co r e = whi teP iece s − b lackP i e c e s ;49 //System . out . p r i n t l n (” s co r e ”+sco r e+” WhiteS ”+whi teP iece s

+” BlackS ”+b lackP i e c e s ) ;50 re turn ( s co r e ) ;51 }5253 // Returner f i gBoarde t f o r et braet ( f i g u r B r a e t t e t )54 pub l i c i n t [ ] [ ] getFigBoard ( i n t [ ] [ ] b , i n t co l s , i n t rows ) {55 noCols = c o l s ;56 noRows = rows ;57 resetFigBoard ( ) ;58 mapFigures (b) ;59 re turn ( f igBoard ) ;60 }61626364 // Navnegiver de e n k e l t e f e l t e r e f t e r hv i lken f i g u r de hoere

t i l .65 //( Navnene er 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 )66 pub l i c void mapFigures ( i n t [ ] [ ] b ) {67 { // Foers te kolone nedad68 f igBoard = new i n t [ tModel . noCols ] [ tModel . noRows ] ;69 i n t c =0;70 {71 f o r ( i n t r =0; r < tModel . noRows ; r++)72 {73 i f (b [ c ] [ r ] == 1)74 {75 i f ( f igBoard [ c ] [ r ] == 0)76 {77 s e tF igu r e ( c , r , figW ) ;78 figW = figW+2;79 }80 }81 e l s e82 {83 i f (b [ c ] [ r ] == 0)84 {85 i f ( f igBoard [ c ] [ r ] == 0)86 {87 s e tF igu r e ( c , r , f i gB ) ;88 f igB = f igB +2;89 }90 }91 }92 }93 }

164 Bilag A

94 }95 { // Hor i son ta l ko r t l a eng ing96 f o r ( i n t c =0; c < tModel . noCols−1; c++)97 {98 f o r ( i n t r =0; r < tModel . noRows ; r++)99 {

100 i f (b [ c ] [ r ] == 0 && b [ c +1] [ r ] == 0 )101 {102 i f ( f igBoard [ c ] [ r ] == 0)103 {104 s e tF igu r e ( c , r , f i gB ) ;105 f igB=f igB +2;106 }107 s e tF igu r e ( c+1,r , f igBoard [ c ] [ r ] ) ;108 }109 e l s e110 {111 i f (b [ c ] [ r ] == 1 && b [ c +1] [ r ] == 1 )112 {113 i f ( f igBoard [ c ] [ r ] == 0)114 {115 s e tF igu r e ( c , r , figW ) ;116 figW=figW+2;117 }118 s e tF igu r e ( c+1,r , f igBoard [ c ] [ r ] ) ;119 }120 e l s e121 {122 i f (b [ c ] [ r ] != 1 && b [ c +1] [ r ] == 1 )123 {124 s e tF igu r e ( c+1,r , figW ) ;125 figW = figW+2;126 }127 e l s e128 {129 i f (b [ c ] [ r ] != 0 && b [ c +1] [ r ] == 0

)130 {131 s e tF igu r e ( c+1,r , f i gB ) ;132 f igB = f igB +2;133 }134 }135 }136 }137 }138 }139 }140 { // V e r t i k a l t ko r t l a eng ing141 f o r ( i n t c=0; c < tModel . noCols ; c++)142 {143 f o r ( i n t r =0; r < tModel . noRows−1; r++)144 {145 i f (b [ c ] [ r ] == 0 && b [ c ] [ r +1] == 0 )146 {147 i f ( f igBoard [ c ] [ r ] != 0)

A.6 FigureMap.java 165

148 {149 i f ( ( f igBoard [ c ] [ r ] != f igBoard [ c ] [ r

+1]) && f igBoard [ c ] [ r +1] != 0)150 {151 r ep l a c eF i g ( f igBoard [ c ] [ r +1] ,

f igBoard [ c ] [ r ] ) ;152 }153 }154155 e l s e156 {157 i f ( f igBoard [ c ] [ r +1] != 0)158 s e tF igu r e ( c , r , f igBoard [ c ] [ r +1]) ;159 e l s e160 {161 s e tF igu r e ( c , r , f i gB ) ;162 f igB=f igB +2;163 }164 }165 s e tF igu r e ( c , r +1, f igBoard [ c ] [ r ] ) ;166 }167 e l s e168 {169 i f (b [ c ] [ r ] == 1 && b [ c ] [ r +1] == 1 )170 {171 i f ( f igBoard [ c ] [ r ] != 0)172 {173 i f ( ( f igBoard [ c ] [ r ] != f igBoard [ c ] [

r +1]) && f igBoard [ c ] [ r +1] != 0)174 {175 r ep l a c eF i g ( f igBoard [ c ] [ r +1] ,

f igBoard [ c ] [ r ] ) ;176 }177 }178179 e l s e180 {181 i f ( f igBoard [ c ] [ r +1] != 0)182 s e tF igu r e ( c , r , f igBoard [ c ] [ r +1])

;183 e l s e184 {185 s e tF igu r e ( c , r , figW ) ;186 figW=figW+2;187 }188 }189 s e tF igu r e ( c , r +1, f igBoard [ c ] [ r ] ) ;190 }191 }192 }193 }194 }195 }196197 // 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

198 p r i v a t e void s e tF igu r e ( i n t co l , i n t row , i n t f i g )199 {200 f igBoard [ c o l ] [ row ] = f i g ;201 }202203 // Reset vae rd i e rne i f igBoard .204 pub l i c void resetFigBoard ( )205 {206 figW = 1 ;207 f igB = 2 ;208 f igBoard = new i n t [ noCols ] [ noRows ] ;209 f o r ( i n t c = 0 ; c < noCols ; c++)210 f o r ( i n t r = 0 ; r < noRows ; r++)211 s e tF igu r e ( c , r , 0 ) ;212 }213214 // Er s ta t e r a l l e f i g u r e med et bestemt navn med et nyt navn .215 p r i v a t e void r ep l a c eF i g ( i n t oldF , i n t newF)216 {217 f o r ( i n t c =0; c<tModel . noCols ; c++)218 f o r ( i n t r =0; r<tModel . noRows ; r++)219 i f ( f igBoard [ c ] [ r ] == oldF )220 s e tF igu r e ( c , r , newF) ;221 }222223 // T a e l l e r hvor mange f e l t e r der har f i gu rnavne t ” f i g ” .224 p r i v a t e i n t countFig ( i n t f i g )225 {226 i n t f =0;227 f o r ( i n t c =0; c<tModel . noCols ; c++)228 f o r ( i n t r =0; r<tModel . noRows ; r++)229 i f ( f igBoard [ c ] [ r ]== f i g )230 f++;231 re turn ( f ) ;232233 }234235 // T a e l l e r hvor mange f e l t e r der er f i gu rnavne t ” f i g ” i

f i gBoarde t fb .236 p r i v a t e i n t countFigB ( i n t f i g , i n t [ ] [ ] fb )237 {238 i n t f =0;239 f o r ( i n t c =0; c<tModel . noCols ; c++)240 f o r ( i n t r =0; r<tModel . noRows ; r++)241 i f ( fb [ c ] [ r ]== f i g )242 f++;243 re turn ( f ) ;244245 }246247 // Finder de to s t o e r s t e f i g u r e r f o r hver f a rv e og beregner

scoren f o r begge par t e r .248 pub l i c void countPieces ( )249 {250 i n t maxW1 = −1;

A.6 FigureMap.java 167

251 i n t maxW2 = −1;252 i n t maxB1 = −2;253 i n t maxB2 = −2;254255 f o r ( i n t w=1; w<figW ; w=w+2)256 i f ( countFig (w)>countFig (maxW1) )257 {258 maxW2 = maxW1;259 maxW1 = w;260 }261 e l s e262 i f ( countFig (w)>countFig (maxW2) )263 maxW2 = w;264 f o r ( i n t b=2; b<f i gB ; b=b+2)265 i f ( countFig (b)>countFig (maxB1) )266 {267 maxB2 = maxB1 ;268 maxB1 = b ;269 }270 e l s e271 i f ( countFig (b)>countFig (maxB2) )272 maxB2 = b ;273 whi teP iece s = countFig (maxW1)+countFig (maxW2) ;274 b la ckP i e c e s = countFig (maxB1)+countFig (maxB2) ;275 }276277 // r e tu rne 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

s o r t e f i g u r e , som der endnu kan p l a c e r e s br ik opad .278 pub l i c i n t [ ] [ ] [ ] g e tF ig s ( i n t [ ] [ ] fb ) {279 i n t [ ] [ ] [ ] f = new i n t [ 2 ] [ 2 ] [ 2 ] ;280 // f [ ] [ ] [ 0 ] = f i g u r navnet (nummer) , f [ ] [ ] [ 1 ] = f i g u r e n s

s t o e r r e l s e281 // f [ 1 ] [ ] [ ] = hvid f i gu r , f [ 0 ] [ ] [ ] = s o r t f i g u r282 // f [ ] [ 0 ] [ ] = s t o e r s t e f i g u r , f [ ] [ 1 ] [ ] = naest s t o e r r e s t e

f i g u r283 f [ 1 ] [ 0 ] [ 0 ] = −1;284 f [ 1 ] [ 1 ] [ 0 ] = −1;285 f [ 0 ] [ 0 ] [ 0 ] = −2;286 f [ 0 ] [ 1 ] [ 0 ] = −2;287 f [ 1 ] [ 0 ] [ 1 ] = 0 ;288 f [ 1 ] [ 1 ] [ 1 ] = 0 ;289 f [ 0 ] [ 0 ] [ 1 ] = 0 ;290 f [ 0 ] [ 1 ] [ 1 ] = 0 ;291 i n t [ ] f igN ;292 f igN = findMaxFigNames ( fb ) ;293294295 f o r ( i n t w=1; w<=figN [ 1 ] ; w=w+2){296 i f ( checkFig (w, fb ) ) {297 i n t W = countFigB (w, fb ) ;298 i f (W>f [ 1 ] [ 0 ] [ 1 ] )299 {300 f [ 1 ] [ 1 ] [ 0 ] = f [ 1 ] [ 0 ] [ 0 ] ;301 f [ 1 ] [ 1 ] [ 1 ] = f [ 1 ] [ 0 ] [ 1 ] ;302 f [ 1 ] [ 0 ] [ 0 ] = w;

168 Bilag A

303 f [ 1 ] [ 0 ] [ 1 ] = W;304 }305 e l s e306 i f (W>f [ 1 ] [ 1 ] [ 1 ] ) {307 f [ 1 ] [ 1 ] [ 0 ] = w;308 f [ 1 ] [ 1 ] [ 1 ] = W;309 }310 }311 }312 f o r ( i n t b=2; b<=figN [ 0 ] ; b=b+2){313 i f ( checkFig (b , fb ) ) {314 i n t B = countFigB (b , fb ) ;315 i f (B>f [ 0 ] [ 0 ] [ 1 ] ) {316 f [ 0 ] [ 1 ] [ 0 ] = f [ 0 ] [ 0 ] [ 0 ] ;317 f [ 0 ] [ 1 ] [ 1 ] = f [ 0 ] [ 0 ] [ 1 ] ;318 f [ 0 ] [ 0 ] [ 0 ] = b ;319 f [ 0 ] [ 0 ] [ 1 ] = B;320 }321 e l s e322 i f (B>f [ 0 ] [ 1 ] [ 1 ] ) {323 f [ 0 ] [ 1 ] [ 0 ] = b ;324 f [ 0 ] [ 1 ] [ 1 ] = B;325 }326 }327 }328 re turn ( f ) ;329 }330331 // r e tu rne 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

s o r t e f i g u r e , som der endnu kan p l a c e r e s br ik opad .332 pub l i c i n t [ ] [ ] [ ] g e tF ig s3 ( i n t [ ] [ ] fb ) {333 i n t [ ] [ ] [ ] f = new i n t [ 2 ] [ 3 ] [ 2 ] ;334 // f [ ] [ ] [ 0 ] = f i g u r navnet (nummer) , f [ ] [ ] [ 1 ] = f i g u r e n s

s t o e r r e l s e335 // f [ 1 ] [ ] [ ] = hvid f i gu r , f [ 0 ] [ ] [ ] = s o r t f i g u r336 // f [ ] [ 0 ] [ ] = s t o e r s t e f i g u r , f [ ] [ 1 ] [ ] = naest s t o e r r e s t e

f i gu r , f [ ] [ 2 ] [ ] = 3 . s t o e r s t e f i g u r337 f [ 1 ] [ 0 ] [ 0 ] = −1;338 f [ 1 ] [ 1 ] [ 0 ] = −1;339 f [ 1 ] [ 2 ] [ 0 ] = −1;340 f [ 0 ] [ 0 ] [ 0 ] = −2;341 f [ 0 ] [ 1 ] [ 0 ] = −2;342 f [ 0 ] [ 2 ] [ 0 ] = −2;343 f [ 1 ] [ 0 ] [ 1 ] = 0 ;344 f [ 1 ] [ 1 ] [ 1 ] = 0 ;345 f [ 1 ] [ 2 ] [ 1 ] = 0 ;346 f [ 0 ] [ 0 ] [ 1 ] = 0 ;347 f [ 0 ] [ 1 ] [ 1 ] = 0 ;348 f [ 0 ] [ 2 ] [ 1 ] = 0 ;349 i n t [ ] f igN ;350 f igN = findMaxFigNames ( fb ) ;351352 f o r ( i n t w=1; w<f igN [ 1 ] ; w=w+2){353 i f ( checkFig (w, fb ) ) {354 i n t W = countFigB (w, fb ) ;

A.6 FigureMap.java 169

355 i f (W>f [ 1 ] [ 0 ] [ 1 ] ) {356 f [ 1 ] [ 2 ] [ 0 ] = f [ 1 ] [ 1 ] [ 0 ] ;357 f [ 1 ] [ 2 ] [ 1 ] = f [ 1 ] [ 2 ] [ 1 ] ;358 f [ 1 ] [ 1 ] [ 0 ] = f [ 1 ] [ 0 ] [ 0 ] ;359 f [ 1 ] [ 1 ] [ 1 ] = f [ 1 ] [ 0 ] [ 1 ] ;360 f [ 1 ] [ 0 ] [ 0 ] = w;361 f [ 1 ] [ 0 ] [ 1 ] = W;362 }363 e l s e364 i f (W>f [ 1 ] [ 1 ] [ 1 ] ) {365 f [ 1 ] [ 2 ] [ 0 ] = f [ 1 ] [ 1 ] [ 0 ] ;366 f [ 1 ] [ 2 ] [ 1 ] = f [ 1 ] [ 2 ] [ 1 ] ;367 f [ 1 ] [ 1 ] [ 0 ] = w;368 f [ 1 ] [ 1 ] [ 1 ] = W;369 }370 e l s e {371 i f (W>f [ 1 ] [ 2 ] [ 1 ] ) {372 f [ 1 ] [ 2 ] [ 0 ] = w;373 f [ 1 ] [ 2 ] [ 1 ] = W;374 }375 }376 }377 f o r ( i n t b=2; b<f igN [ 0 ] ; b=b+2){378 i f ( checkFig (b , fb ) ) {379 i n t B = countFigB (b , fb ) ;380 i f (B>f [ 0 ] [ 0 ] [ 1 ] )381 {382 f [ 0 ] [ 1 ] [ 0 ] = f [ 0 ] [ 0 ] [ 0 ] ;383 f [ 0 ] [ 1 ] [ 1 ] = f [ 0 ] [ 0 ] [ 1 ] ;384 f [ 0 ] [ 0 ] [ 0 ] = b ;385 f [ 0 ] [ 0 ] [ 1 ] = B;386 }387 e l s e388 i f (B>f [ 0 ] [ 1 ] [ 1 ] ) {389 f [ 0 ] [ 2 ] [ 0 ] = f [ 0 ] [ 1 ] [ 0 ] ;390 f [ 0 ] [ 2 ] [ 1 ] = f [ 0 ] [ 2 ] [ 1 ] ;391 f [ 0 ] [ 1 ] [ 0 ] = b ;392 f [ 0 ] [ 1 ] [ 1 ] = B;393 }394 e l s e {395 i f (B>f [ 0 ] [ 2 ] [ 1 ] ) {396 f [ 0 ] [ 2 ] [ 0 ] = b ;397 f [ 0 ] [ 2 ] [ 1 ] = B;398 }399 }400 }401 }402 }403 re turn ( f ) ;404 }405406 // r e t u r n e r e true , hv i s der er minimum en f r i p lads opad

f i g u r e n407 p r i v a t e boolean checkFig ( i n t f , i n t [ ] [ ] fb ) {408 f o r ( i n t c =0; c < tModel . noCols ; c++){

170 Bilag A

409 f o r ( i n t r =0; r < tModel . noRows ; r++){410 i f ( fb [ c ] [ r ] == f ) {411 i f ( c < tModel . noCols−1 && fb [ c +1] [ r ] == 0) {412 i f ( r < tModel . noRows−1 && fb [ c +1] [ r +1] ==

0)413 re turn ( t rue ) ;414 i f ( r > 0 && fb [ c +1] [ r−1] == 0)415 re turn ( t rue ) ;416 i f ( c < tModel . noCols−2 && fb [ c +2] [ r ] == 0)417 re turn ( t rue ) ;418 }419 i f ( c > 0 && fb [ c−1] [ r ] == 0) {420 i f ( r < tModel . noRows−1 && fb [ c−1] [ r +1] ==

0)421 re turn ( t rue ) ;422 i f ( r > 0 && fb [ c−1] [ r−1] == 0)423 re turn ( t rue ) ;424 i f ( c > 1 && fb [ c−2] [ r ] == 0)425 re turn ( t rue ) ;426 }427 i f ( r < tModel . noRows−1 && fb [ c ] [ r +1] == 0) {428 i f ( c < tModel . noCols−1 && fb [ c +1] [ r +1] ==

0)429 re turn ( t rue ) ;430 i f ( c > 0 && fb [ c−1] [ r +1] == 0)431 re turn ( t rue ) ;432 i f ( r < tModel . noRows−2 && fb [ c ] [ r +2] == 0)433 re turn ( t rue ) ;434 }435 i f ( r > 0 && fb [ c ] [ r−1] == 0) {436 i f ( c < tModel . noCols−1 && fb [ c +1] [ r−1] ==

0)437 re turn ( t rue ) ;438 i f ( c > 0 && fb [ c−1] [ r−1] == 0)439 re turn ( t rue ) ;440 i f ( r > 1 && fb [ c ] [ r−2] == 0)441 re turn ( t rue ) ;442 }443 }444 }445 }446 re turn ( f a l s e ) ;447 }448449 // f i n d e r og r e tu rne r de h o e j s t e f i g navne anvendt i fb450 p r i v a t e i n t [ ] findMaxFigNames ( i n t [ ] [ ] fb ) {451 i n t [ ] f igN = new i n t [ 2 ] ;452 f o r ( i n t c =0; c < tModel . noCols ; c++){453 f o r ( i n t r =0; r < tModel . noRows ; r++){454 i f ( fb [ c ] [ r ]%2 == 1) {455 i f ( fb [ c ] [ r ] > f igN [ 1 ] )456 f igN [ 1 ] = fb [ c ] [ r ] ;457 }458 i f ( fb [ c ] [ r ]%2 == 0) {459 i f ( fb [ c ] [ r ] > f igN [ 0 ] )

A.7 Node.java 171

460 f igN [ 0 ] = fb [ c ] [ r ] ;461 }462 }463 }464 re turn ( f igN ) ;465 }466467 }

A.7 Node.java

12 import java . u t i l . ArrayList ;3456 pub l i c c l a s s Node{7 pub l i c i n t [ ] [ ] nodeBoard ;8 pub l i c i n t a ; // Score o f the board9 pub l i c i n t wc ; // Whire Column

10 pub l i c i n t wr ; // White Row11 pub l i c i n t bc ; // Black Column12 pub l i c i n t br ; // Black Row13 pub l i c i n t d ; // Depth14 pub l i c ArrayList<Node> par ;15 pub l i c ArrayList<Node> c h i l d r e n ;16 pub l i c Tai j iModel tModel ;1718 pub l i c Node (Node parent ) {19 t h i s . par = new ArrayList<Node>() ;20 t h i s . c h i l d r e n = new ArrayList<Node>() ;21 f o r ( i n t i = 0 ; i < 123 ; i++)22 f o r ( i n t j = 0 ; j < 123 ; j++)23 nodeBoard [ i ] [ j ] = 0 ;24 }2526 pub l i c Node ( ) {27 t h i s . c h i l d r e n = new ArrayList<Node>() ;28 nodeBoard = new i n t [ 1 2 3 ] [ 1 2 3 ] ;29 f o r ( i n t i = 0 ; i < 123 ; i++)30 f o r ( i n t j = 0 ; j < 123 ; j++)31 nodeBoard [ i ] [ j ] = 0 ;32 }3334 pub l i c Node addChild (Node n) {35 i f (n == n u l l )36 System . out . p r i n t l n (” Null002 node”+n) ;37 t h i s . c h i l d r e n . add (n) ;3839 re turn (n) ;40 }4142 // Laver en node udfra en given tur .

172 Bilag A

43 pub l i c Node createNode ( i n t t , Tai j iModel tModel )44 {45 nodeBoard = tModel . getOneBoard ( t ) ;46 a = tModel . g e tD i f ( nodeBoard ) ;47 t h i s . tModel = tModel ;48 re turn t h i s ;49 }5051 // Returnerer b r a e t t e t f o r en Node52 p r i v a t e i n t [ ] [ ] getNodeBoard (Node n)53 {54 re turn (n . nodeBoard ) ;55 }5657 // Laver en node udfra g ivne parameter .58 pub l i c Node createChi ldNode ( i n t wC, i n t wR, i n t bC, i n t bR, Node

parent )59 {60 Node n = new Node ( ) ;61 i n t [ ] [ ] c l one ;62 c lone = new i n t [ tModel . noCols ] [ tModel . noRows ] ;63 f o r ( i n t c=0; c < tModel . noCols ; c++)64 f o r ( i n t r =0; r < tModel . noRows ; r++)65 c lone [ c ] [ r ] = parent . nodeBoard [ c ] [ r ] ;66 n . nodeBoard = c lone ;67 n . wc = wC;68 n . wr = wR;69 n . bc = bC;70 n . br = bR;71 n . par = new ArrayList<Node>() ;72 n . par . add ( parent ) ;73 n . d = parent . d+1;74 i f (n . d % 2 == 0)75 n . a = tModel . noRows∗ tModel . noCols ;76 i f (n . d % 2 == 1)77 n . a = tModel . noRows∗ tModel . noCols ;7879 re turn (n) ;80 }8182 // Laver en kopie a f en node .83 pub l i c Node createCloneNode (Node org )84 {85 Node n = new Node ( ) ;86 i n t [ ] [ ] c l one ;87 c lone = new i n t [ tModel . noCols ] [ tModel . noRows ] ;88 f o r ( i n t c=0; c < tModel . noCols ; c++)89 f o r ( i n t r =0; r < tModel . noRows ; r++)90 c lone [ c ] [ r ] = org . nodeBoard [ c ] [ r ] ;91 n . nodeBoard = c lone ;92 n . a = tModel . g e tD i f ( nodeBoard ) ;93 n . wc = org . wc ;94 n . wr = org . wr ;95 n . bc = org . bc ;96 n . br = org . br ;

A.8 TaijiDriver.java 173

97 n . par = org . par ;98 re turn (n) ;99 }

100 }

A.8 TaijiDriver.java

12 c l a s s T a i j i D r i v e r3 {45 //Main metoden , er d r i v e r f o r a l l e de andre k l a s s e r .

Konstruerer en Taij iFrame og v i s e r den .6 pub l i c s t a t i c void main ( St r ing [ ] a rgs )7 {8 Taij iFrame tFrame = new Taij iFrame ( ) ;9 tFrame . showIt ( ) ;

10 }11 }

A.9 TaijiFrame.java

12 import java . awt . event . ∗ ;3 import javax . swing . ∗ ;4 import java . awt . event . MouseListener ;5 import java . awt . event . MouseEvent ;67 pub l i c c l a s s Taij iFrame extends JFrame8 {9 // Var i ab l e r t i l konst rukt ionen a f model len .

10 p r i v a t e i n t noCols = 9 ;11 p r i v a t e i n t noRows = 9 ;1213 // Elementerne i framen gemmes som pub l i c v a r i a b l e r , saa de kan

r e f e r e r e s t i l f r a metoder inde i de andre e lementer .14 pub l i c TurnPanel uPanel ;15 pub l i c Ta i j iPane l tPanel ;16 pub l i c Tai j iModel tModel ;17 pub l i c ScorePanel whiteScore , b lackScore ;18 pub l i c TaijiMenu tMenu ;1920 // Constructor . Laver a l l e de f o r s k e l l i g e e lementer og p l a c e r e r

dem i et border−l ayout .21 pub l i c Taij iFrame ( )22 {23 se tLoca t i on (100 , 100) ;24 s e t T i t l e (” T a i j i ”) ;2526 tModel = new Tai j iModel ( noCols , noRows) ;

174 Bilag A

27 whiteScore = new ScorePanel ( th i s , 1 ) ;28 b lackScore = new ScorePanel ( th i s , 0 ) ;29 tPanel = new Ta i j iPane l ( t h i s ) ;30 uPanel = new TurnPanel ( t h i s ) ;31 tMenu = new TaijiMenu ( t h i s ) ;3233 getContentPane ( ) . add ( tPanel , ” Center ”) ;34 getContentPane ( ) . add ( whiteScore , ”West”) ;35 getContentPane ( ) . add ( blackScore , ”East ”) ;36 getContentPane ( ) . add ( uPanel , ”South ”) ;3738 t h i s . setJMenuBar ( tMenu) ;39 t h i s . s e tDe fau l tC lo seOperat i on ( JFrame .EXIT ON CLOSE) ;40 t h i s . pack ( ) ;41 }4243 //Metode som r e p a i n t e r a l l e e lementerne i framen .44 pub l i c void r e p a i n t A l l ( )45 {46 t h i s . tPanel . r epa in t ( ) ;47 t h i s . whiteScore . r epa in t ( ) ;48 t h i s . b lackScore . r epa in t ( ) ;49 t h i s . uPanel . update ( ) ;50 }5152 //Goer Taij iFrame s y n l i g rent g r a f i s k .53 pub l i c void showIt ( )54 {55 s e t V i s i b l e ( t rue ) ;56 }5758 // S k j u l e r Taij iFrame ( b l i v e r ikke brugt )59 pub l i c void h i d e I t ( )60 {61 s e t V i s i b l e ( f a l s e ) ;62 }6364 }

A.10 TaijiHash.java

12 pub l i c c l a s s Tai j iHash {3 p r i v a t e Tai j iModel tModel ;4 p r i v a t e i n t [ ] [ ] valueBoard ; // valueBoard , b r a e t t e t med

symmetrisk ens v a e r d i e r567 pub l i c Tai j iHash ( Tai j iModel m)8 {9 tModel = m;

10 valueBoard = new i n t [ tModel . noCols ] [ tModel . noRows ] ;11 f o r ( i n t i = 0 ; i<tModel . noCols ; i++){

A.10 TaijiHash.java 175

12 f o r ( i n t j = 0 ; j<tModel . noRows ; j++){13 i n t a = ( tModel . noCols /2) ;14 valueBoard [ i ] [ j ]=0;15 }16 }17 }1819 // beregner en hash vaerd i udfra begge s p i l l e r s s co r e .20 pub l i c i n t hashFunction ( i n t [ ] [ ] b ) {21 i n t v ;22 i n t [ ] s = new i n t [ 2 ] ;23 s = tModel . fMap . ca lS co r e (b , tModel . noCols , tModel . noRows) ;24 v = s [0 ]+( s [ 1 ] ∗ ( tModel . maxS+1) ) ;25 re turn ( v ) ;26 }2728 // r e t u r n e r e r den h o e j s t mulige vae rd i f o r hashFunction29 pub l i c i n t getMaxH ( ) {30 i n t maxH = tModel . maxS+(( tModel . maxS+1)∗ tModel . maxS) ;31 re turn (maxH) ;32 }3334 // beregner en hash vaerd i b a s s e r e t paa p l a d s e r i n g a f b r i kke r

paa b r a e t t e t35 pub l i c i n t hashFunction2 ( i n t [ ] [ ] b ) {36 i n t v ;37 i n t bc ;38 i n t br ;3940 i n t nC = tModel . noCols ;41 i n t nR = tModel . noRows ;42 i n t cp ;43 i n t rp ;44 i n t maxV = nC∗nR;45 v = 0 ;4647 f o r ( i n t c = 0 ; c < tModel . noCols ; c++){48 f o r ( i n t r = 0 ; r< tModel . noRows ; r++){49 i f (b [ c ] [ r ] == 0) {50 i f ( tModel . noCols%2==0 && c>=tModel . noCols /2)51 bc = 1 ;52 e l s e53 bc = 0 ;5455 i f ( tModel . noRows%2==0 && r>=tModel . noRows/2)56 br = 1 ;57 e l s e58 br = 0 ;5960 v = ( v + ( ( ( Math . abs ( tModel . noCols/2−c )+bc ) ∗ (

Math . abs ( tModel . noRows/2−r )+br ) ) /2) )%maxV;61 }6263 i f (b [ c ] [ r ] == 1) {64 i f ( tModel . noCols%2==0 && c>=tModel . noCols /2)

176 Bilag A

65 bc = 1 ;66 e l s e67 bc = 0 ;6869 i f ( tModel . noRows%2==0 && r>=tModel . noRows/2)70 br = 1 ;71 e l s e72 br = 0 ;7374 v = ( v +( (Math . abs ( tModel . noCols/2−c )+bc ) ∗ (

Math . abs ( tModel . noRows/2−r )+br ) ) )%maxV;75 }76 }77 }78 re turn ( v ) ;79 }8081 // r e t u r n e r e r den h o e j s t mulige vae rd i f o r hashFunction282 pub l i c i n t getMaxH2 ( ) {83 i n t maxH = ( tModel . noCols∗ tModel . noRows)−1;84 re turn (maxH) ;85 }8687 // r e tu rne r en hash vaerd i som er sammen sat a f hashFunction 1

og 288 pub l i c i n t hashFunction3 ( i n t [ ] [ ] b ) {89 i n t v = ( hashFunction (b)+hashFunction2 (b) )%getMaxH ( ) ;90 re turn ( v ) ;91 }9293 // r e t u r n e r e r den h o e j s t mulige vae rd i f o r hashFunction394 pub l i c i n t getMaxH3 ( ) {95 re turn (getMaxH ( ) ) ;96 }97 }

A.11 TaijiListeners.java

12 import java . awt . event . ∗ ;3 import java . awt . ∗ ;4 import javax . swing . ∗ ;5 import java . i o . ∗ ;67 // L i s t ene r en t i l s e l v e brae t t e t , Ta i j iPane l .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 MouseListener9 {

10 // Var iablen som indeho lde r den Taij iFrame hvor i pane l e tT 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 .

11 p r i v a t e Taij iFrame tFrame ;1213 // Var i ab l e r t i l koord inate rne f r a de mouseevents som l i s t e n e r e n

fange r .

A.11 TaijiListeners.java 177

14 p r i v a t e i n t c l i ckCo l , cl ickRow ;1516 // Var i ab l e r som bruges i mouseClicked t i l at bestemme om det er

f o e r s t e l l e r andet ryk , e l l e r t i l at gemme vinderen .17 p r i v a t e St r ing winner ;1819 // Constructor20 //Modtager en Taij iFrame som argument .21 pub l i c T a i j i P a n e l L i s t e n e r ( Taij iFrame frame )22 {23 tFrame = frame ;24 }2526 //Den metode som modtager MouseEvent og ka lde r move metoden i

modellen , hv i s27 // det f l e t der k l i k k e s paa f o e r s t gang er den f r i t .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

d i a l o g med vinderen .29 //Modtager et MouseEvent som argument .30 pub l i c void mouseClicked ( MouseEvent event )31 {32 i n t x , y ;33 x = event . getX ( ) ;34 y = event . getY ( ) ;3536 c l i c k C o l = x /( tFrame . tPanel . getWidth ( ) /tFrame .

tModel . getNoCols ( ) ) ;37 clickRow = y /( tFrame . tPanel . getHeight ( ) /tFrame .

tModel . getNoRows ( ) ) ;38 winner = tFrame . tModel . move( c l i ckCo l , cl ickRow ) ;39 i f ( ! winner . equa l s (”None”) )40 {41 i f ( winner . equa l s (”Draw”) )42 JOptionPane . showMessageDialog ( nu l l , ”

The game i s a draw .\n” , ”Game over. ” , JOptionPane .INFORMATION MESSAGE) ;

43 e l s e44 JOptionPane . showMessageDialog ( nu l l ,

winner +” wins ! ” , ”Game over . ” ,JOptionPane .INFORMATION MESSAGE) ;

45 }46 tFrame . r e p a i n t A l l ( ) ;47 }4849 //Metoder t i l at o v e r s k r i v e de abs t rakte metoder f r a

f o r a e l d r e r e n MouseListener .50 pub l i c void mousePressed ( MouseEvent event )51 {52 }5354 pub l i c void mouseReleased ( MouseEvent event )55 {56 }57

178 Bilag A

58 pub l i c void mouseExited ( MouseEvent event )59 {60 }6162 pub l i c void mouseEntered ( MouseEvent event )63 {64 }6566 }6768 //Denne k l a s s e ” l y t t e r ” t i l de to knapper paa et TurnPanel . Den kan

enten s t i l l e en tur frem e l l e r en t i l b a g e .69 c l a s s TurnListener implements Act i onL i s t ene r70 {71 p r i v a t e Taij iFrame tFrame ;7273 // Constructor .74 //Modtager en Taij iFrame som argument .75 pub l i c TurnListener ( Taij iFrame frame )76 {77 tFrame = frame ;78 }7980 //Den metode der r e a g e r e r paa et ActionEvent . S t i l l e r enten

turen en frem81 // e l l e r t i l b a g e , og ka lde r r e p a i n t A l l ( ) f r a framen .82 pub l i c void act ionPerformed ( ActionEvent event )83 {84 St r ing aCommand = event . getActionCommand ( ) ;8586 i f (aCommand . equa l s (” Next Turn”) )87 {88 tFrame . tModel . turnForward ( ) ;89 tFrame . r e p a i n t A l l ( ) ;90 }91 e l s e92 {93 tFrame . tModel . turnBack ( ) ;94 tFrame . r e p a i n t A l l ( ) ;95 }96 }97 }9899 // L i s t ene r en t i l TaijiMenuen tMenu .

100 c l a s s TMListener implements Act i onL i s t ene r101 {102103 //En Taij iFrame som kan indeho lde tFrame , saa der kan r e f e r e r s

t i l den .104 p r i v a t e Taij iFrame tFrame ;105106 // Constructer .107 //Modtager en Taij iFrame som argument .108 pub l i c TMListener ( Taij iFrame frame )109 {

A.11 TaijiListeners.java 179

110 tFrame = frame ;111 }112113 //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 .

Konstruerer en JFi leChooser der enten kan bruges t i l atgemme e l l e r

114 // aabne gemte s p i l . Kan ogsaa lukke programmet ned e l l e r s t a r t eet nyt s p i l .

115 //Modtager et ActionEvent som argument .116 pub l i c void act ionPerformed ( ActionEvent evt )117 {118 JFi leChooser chooser = new JFi leChooser ( ) ;119120 i f ( evt . getSource ( ) i n s t a n c e o f JMenuItem )121 {122 St r ing command = evt . getActionCommand ( ) ;123 i f (command . equa l s (”Same s e t t i n g s ”) )124 {125 tFrame . tModel . r e s e t ( ) ;126 tFrame . r e p a i n t A l l ( ) ;127 }128 e l s e i f (command . equa l s (” Change s e t t i n g s ”) )129 {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 (

tFrame ) ;131 s e t t i n g s . showIt ( ) ;132 }133 e l s e i f (command . equa l s (” Save ”) )134 {135 i n t returnVal = chooser . showSaveDialog (

tFrame . tPanel ) ;136 i f ( returnVal == JFi leChooser .

APPROVE OPTION)137 {138 boolean save = true ;139 i f ( chooser . g e t S e l e c t e d F i l e ( ) .

e x i s t s ( ) == true )140 i f ( JOptionPane .

showConfirmDialog ( nu l l , ”F i l e a l r eady e x i s t s ,ove rwr i t e ?” , ”Warning ” ,JOptionPane .YES NO OPTION)!= JOptionPane .YES OPTION)

141 save = f a l s e ;142143 i f ( save == true )144 {145 i n t noCols = tFrame . tModel .

getNoCols ( ) ;146 i n t noRows = tFrame . tModel .

getNoRows ( ) ;147 i n t [ ] [ ] [ ] board = tFrame .

tModel . getBoard ( ) ;148 i n t lastTurn = board

[ 0 ] [ 0 ] [ 0 ] ;

180 Bilag A

149 St r ing txt = ”” ;150 txt = txt + lastTurn + ”T” ;151 f o r ( i n t t =1; t<=lastTurn ;

t++)152 f o r ( i n t c=0; c<noCols ;

c++)153 f o r ( i n t r =0; r<

noRows ; r++)154 {155 txt = txt +

board [t ] [ c ] [ r] ;

156 }157 try158 {159 F i l eWr i t e r

f i l e S a v e r =new Fi l eWr i t e r (chooser .g e t S e l e c t e d F i l e( ) ) ;

160 f i l e S a v e r . wr i t e ( txt) ;

161 f i l e S a v e r . c l o s e ( ) ;162 }163 catch ( IOException except ion

)164 {165 System . out . p r i n t l n

(”A problem hasoccured sav ingthe f i l e . ” ) ;

166 }167 }168 }169 }170 e l s e i f (command . equa l s (” Load ”) )171 {172 i n t returnVal = chooser . showOpenDialog (

tFrame . tPanel ) ;173 i f ( returnVal == JFi leChooser .

APPROVE OPTION)174 {175 try176 {177 i n t noCols = tFrame . tModel .

getNoCols ( ) ;178 i n t noRows = tFrame . tModel .

getNoRows ( ) ;179 i n t maxTurns = tFrame .

tModel . getMaxTurns ( ) ;180 i n t [ ] [ ] [ ] board = new i n t [

maxTurns ] [ noCols ] [noRows ] ;

A.11 TaijiListeners.java 181

181 Fi leReader l oade r = newFi leReader ( chooser .g e t S e l e c t e d F i l e ( ) ) ;

182 BufferedReader input = newBufferedReader ( l oade r ) ;

183 St r ing l i n e = input .readLine ( ) ;

184 i n t pos = 0 ;185 St r ing la s tTurnSt r ing = ”” ;186 whi l e ( l i n e . charAt ( pos ) !=

’T’ )187 {188 la s tTurnSt r ing =

las tTurnSt r ing+ l i n e . charAt (pos ) ;

189 pos++;190 }191 pos++;192 i n t lastTurn = I n t e g e r .

pa r s e In t ( l a s tTurnSt r ing) ;

193 board [ 0 ] [ 0 ] [ 0 ] = lastTurn ;194 f o r ( i n t t =1; t<=lastTurn ;

t++)195 f o r ( i n t c=0; c<noCols ;

c++)196 f o r ( i n t r =0; r<

noRows ; r++)197 {198 St r ing

p i e c e =”” +

l i n e .charAt (pos ) ;

199 board [ t ] [ c] [ r ] =

I n t e g e r.pa r s e In t( p i e c e );

200 pos++;201 }202 tFrame . tModel . newBoard (

board ) ;203 tFrame . tModel . setShowTurn ( ) ;204 tFrame . r e p a i n t A l l ( ) ;205 }206 catch ( IOException except ion )207 {208 System . out . p r i n t l n (”A

problem has occured

182 Bilag A

l oad ing the f i l e . ” ) ;209 }210 }211 }212 e l s e i f (command . equa l s (” Exit ”) )213 {214 System . e x i t (0 ) ;215 }216 e l s e i f (command . equa l s (” Rules ”) )217 {218 JOptionPane . showMessageDialog ( nu l l , ” Each

p laye r takes turns p l a c ing one p e i c e onthe board .\ nAll p i e c e s has a Dark and

a Light end . \nThe winner i s the one tohave the g r e a s t number\nof t h i e r

co l ou r p laced togehte r in two f i g u r e s .\nOnly the two b i g g e s t f i g u r e s count f o r

each p laye r . ” , ”Game r u l e s ” ,JOptionPane .INFORMATION MESSAGE) ;

219 }220 e l s e i f (command . equa l s (” About ”) )221 {222 JOptionPane . showMessageDialog ( nu l l , ”The

boardgame , T a i j i i s the c r e a t i o n o f

NA c©stor Romeral AndrA c©s \nThisimplementation was made by Morten Rask” , ”About T a i j i ” , JOptionPane .INFORMATION MESSAGE) ;

223 }224 }225 }226 }

A.12 TaijiMenu.java

12 import java . awt . event . ∗ ;3 import javax . swing . ∗ ;4 import java . awt . ∗ ;56 //Denne k l a s s e er menuen som er p l a c e r e t i Taij iFrame . Den

indeho lde r menu7 // ob j ek 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 .8 //Der er ogsaa mulighed f o r at l a e s e r e g l e r n e .9 // TaijiMenu er nedarvet f r a JMenuBar .

10 c l a s s TaijiMenu extends JMenuBar11 {1213 // Constructer . Laver a l l e menu−ob j ek t e r og t i l f o e j e r en

l i s t e n e r t i l dem .14 //Modtager en Taij iFrame som argument og g i v e r den v ide r e t i l

l i s t e n e r e n .15 pub l i c TaijiMenu ( Taij iFrame frame )

A.13 TaijiModel.java 183

16 {17 JMenu f i leMenu = new JMenu(”Game”) ;18 add ( f i l eMenu ) ;1920 //JMenuItem gameItem = new JMenuItem (”New game”) ;21 JMenuItem saveItem = new JMenuItem (” Save ”) ;22 JMenuItem loadItem = new JMenuItem (” Load ”) ;23 JMenuItem ex i t I t em = new JMenuItem (” Exit ”) ;2425 JMenu subMenu = new JMenu(”New game”) ;26 JMenuItem sameSet = new JMenuItem (”Same s e t t i n g s ”) ;27 JMenuItem changeSet = new JMenuItem (” Change s e t t i n g s ”) ;28 subMenu . add ( sameSet ) ;29 subMenu . add ( changeSet ) ;3031 f i l eMenu . add ( subMenu) ;32 f i l eMenu . addSeparator ( ) ;33 f i l eMenu . add ( saveItem ) ;34 f i l eMenu . add ( loadItem ) ;35 f i l eMenu . addSeparator ( ) ;36 f i l eMenu . add ( ex i t I t em ) ;3738 JMenu helpMenu = new JMenu(” Help ”) ;39 add ( helpMenu ) ;4041 JMenuItem ru l e s I t em = new JMenuItem (” Rules ”) ;42 JMenuItem aboutItem = new JMenuItem (” About ”) ;4344 helpMenu . add ( ru l e s I t em ) ;45 helpMenu . add ( aboutItem ) ;4647 TMListener TMLi = new TMListener ( frame ) ;4849 sameSet . addAct ionLis tener (TMLi) ;50 changeSet . addAct ionLis tener (TMLi) ;51 saveItem . addAct ionLis tener (TMLi) ;52 loadItem . addAct ionLis tener (TMLi) ;53 ex i t I t em . addAct ionLis tener (TMLi) ;54 ru l e s I t em . addAct ionLis tener (TMLi) ;55 aboutItem . addAct ionLis tener (TMLi) ;56 }5758 }

A.13 TaijiModel.java

1 import java . u t i l . Date ; // benyttes t i l at tage t i d paa AI ’ erne23 // Klassen Tai j iModel som r e p r a e s e n t e r e r he l e den ikke−g r a f i s k e de l

a f s p i l l e t .4 pub l i c c l a s s Tai j iModel5 {6

184 Bilag A

7 pub l i c AITaijiMinimax minimax ;8 pub l i c FigureMap fMap ;9 pub l i c Board tBoard ;

10 pub l i c Tai j iHash tHash ;11 pub l i c T a i j i P r i n t tPr in t ;12 pub l i c AITaij iAlphaBeta alphaBeta ;13 pub l i c AITaij iPureAlphaBeta pureAlphaBeta ;14 pub l i c AITaijiMinimax2 minimax2 ;15 pub l i c AITaijiGrowth growth ;16 pub l i c AITaijiLocalAreaAB localAreaAB ;171819 // Var i ab l e r20 pub l i c i n t noRows , noCols ; // a n t a l l e t a f raekker og kolonner21 pub l i c i n t maxTurns = 1000 ; // max anta l ture programmet kan

haandtere22 pub l i c i n t maxScore ; // Score hv i s e t h e l t braet var daekket a f

en f a r v e .23 pub l i c i n t maxS ; // den maximale s co r e f o r en s p i l l e r .24 // ( hv i s a l l e b r i kke r a f en f a rv e er med i

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 ef i g u r )

2526 f i n a l p r i v a t e i n t white = 1 , b lack = 0 , neu t ra l = 2 ; //

Konstanter f o r de f o r s k e l l i g e b r i kke r paa b r a e t t e t .2728 // o e j e b l i k s−i n fo rmat ion f o r s p i l l e t .29 p r i v a t e i n t cur rentP laye r = 1 ;30 pub l i c i n t currentTurn = 1 , noTurns = 1 , showTurn = 0 , s t a r t e r

= 1 ;31 p r i v a t e i n t whScore=0, b lScore =0;32 p r i v a t e i n t whitePlayer = 0 , b lackPlayer = 2 ; // 0 human , 1

minimax , 2 ab , 3 pure ab , 4 growth , 5 minimax2 , 6localAreaAB

3334 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

med det nye k l i k b l i v e r t i l p l a c e r i ng en a f en br ik .35 p r i v a t e boolean c l i c k = f a l s e ;36 p r i v a t e boolean gameOver = f a l s e ;373839 // 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

raekker som argumenter .40 pub l i c Tai j iModel ( i n t co l , i n t row )41 {42 noCols = c o l ;43 minimax = new AITaijiMinimax ( t h i s ) ;44 alphaBeta = new AITaij iAlphaBeta ( t h i s ) ;45 pureAlphaBeta = new AITaij iPureAlphaBeta ( t h i s ) ;46 minimax2 = new AITaijiMinimax2 ( t h i s ) ;47 growth = new AITaijiGrowth ( t h i s ) ;48 localAreaAB = new AITaijiLocalAreaAB ( t h i s ) ;49 fMap = new FigureMap ( t h i s ) ;50 tBoard = new Board ( t h i s ) ;51 tHash = new Tai j iHash ( t h i s ) ;

A.13 TaijiModel.java 185

52 tPr in t = new T a i j i P r i n t ( t h i s ) ;53 noRows = row ;54 tBoard . board = new i n t [ maxTurns ] [ noCols ] [ noRows ] ;55 maxScore = noCols∗noRows ;56 maxS = noCols∗noRows /2 ;57 r e s e t ( ) ;58 }596061 // Reset . Toemmer brae 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

udgangspos i t ionen .62 pub l i c void r e s e t ( )63 {64 currentTurn = 1 ;65 showTurn = 0 ;66 f o r ( i n t c = 0 ; c < noCols ; c++)67 {68 f o r ( i n t r = 0 ; r < noRows ; r++)69 {70 tBoard . s e t P i e c e ( c , r , 2 ) ;71 }72 }73 cur r entP laye r = 1 ;74 tBoard . board [ 0 ] [ 0 ] [ 0 ] = 1 ;75 }767778 // haandtere t raek f o r menneske l ig s p i l l e r e r og AI ’ erne79 // r e t u r n e r e om der er en v inder .80 pub l i c S t r ing move( i n t curCol , i n t curRow )81 {82 St r ing winner = ”None ” ;8384 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 (

hvid ) , == 1 s t a r t e r ai ’ en ( s o r t )85 i f ( whitePlayer == 0)86 playerTurn ( curCol , curRow , f a l s e ) ;87 i f ( whitePlayer == 2)88 alphaBetaTurn ( f a l s e ) ;89 i f ( whitePlayer == 4)90 growthTurn ( f a l s e ) ;91 i f ( whitePlayer == 6)92 localAreaABTurn ( f a l s e ) ;9394 }95 e l s e96 {97 i f ( b lackPlayer == 0)98 playerTurn ( curCol , curRow , t rue ) ;99 i f ( b lackPlayer == 1)

100 minimaxTurn ( ) ;101 i f ( b lackPlayer == 2)102 alphaBetaTurn ( t rue ) ;103 i f ( b lackPlayer == 3)104 pureAlphaBetaTurn ( ) ;

186 Bilag A

105 i f ( b lackPlayer == 4)106 growthTurn ( t rue ) ;107 i f ( b lackPlayer == 5)108 minimax2Turn ( ) ;109 i f ( b lackPlayer == 6)110 localAreaABTurn ( t rue ) ;111 }112113 switch ( gameOver ( ) )114 {115 case −1:116 break ;117 case 0 :118 winner = ” Black ” ;119 re turn ( winner ) ;120 case 1 :121 winner = ”White ” ;122 re turn ( winner ) ;123 case 2 :124 winner = ”Draw ” ;125 re turn ( winner ) ;126 }127128129130 re turn ( winner ) ;131 }132133 // Lader den menneske l ige s p i l l e r f o r e t a g e et ryk134 // Foretager et ryk , hv i s det er l o v l i g t . ( Et ryk er d e l t op i

en hvid og en s o r t de l )135 //Modtager p o s i t i o n f r a k l i k som argument136 p r i v a t e void playerTurn ( i n t curCol , i n t curRow , boolean b) {137 i n t b1 = 1 ;138 i n t b2 = 0 ;139 i f (b) {140 b1=0;141 b2=1;142 }143144 i f ( c l i c k == f a l s e )145 {146 i f ( checkMove ( tBoard . board [ currentTurn ] , curCol ,

curRow ) )147 {148 tBoard . copyBoard ( ) ;149 currentTurn++;150 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;151 tBoard . s e t P i e c e ( curCol , curRow , b1 ) ;152 c l i c k = true ;153 preCol = curCol ;154 preRow = curRow ;155 tBoard . getOneBoard ( currentTurn ) ;156 }157 }

A.13 TaijiModel.java 187

158 e l s e159 {160 i f ( checkMove ( tBoard . board [ currentTurn ] , curCol , curRow

) ) {161 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;162 tBoard . s e t P i e c e ( curCol , curRow , b2 ) ;163 cur r entP laye r = ( cur rentP laye r +1) % 2 ;164 c l i c k = f a l s e ;165 preCol = curCol ;166 preRow = curRow ;167 showTurn++;168 }169 e l s e {170 tBoard . s e t P i e c e ( preCol , preRow , 2) ;171 preCol = curCol ;172 preRow = curRow ;173 c l i c k = f a l s e ;174 currentTurn−−;175 }176177 }178 }179180 // f o r e t a g e r et t raek ved h ja e lp a f minimax ai ’ en . ( s p i l l e r kun

som s o r t )181 p r i v a t e void minimaxTurn ( ) {182 Date time = new Date ( ) ;183 long t1 = time . getTime ( ) ;184 minimax . c reateTree ( ) ;185 Node n ;186 n = minimax . returnMoveMirRot ( ) ;187 tBoard . copyBoard ( ) ;188 currentTurn++;189 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;190 showTurn++;191 tBoard . s e t P i e c e (n . wc , n . wr , white ) ;192 tBoard . s e t P i e c e (n . bc , n . br , b lack ) ;193 Date time2 = new Date ( ) ;194 long t2 = time2 . getTime ( ) ;195 long t3 = t2−t1 ;196 System . out . p r i n t l n (”TM − minimaxTurn time : ”+t3 ) ;197 }198199 // f o r e t a g e r et t raek ved h ja e lp a f AlphaBeta ai ’ en .200 // b = true hv i s den s k a l s p i l l e sort , f a l s e f o r hvid201 p r i v a t e void alphaBetaTurn ( boolean b) {202 Date time = new Date ( ) ;203 long t1 = time . getTime ( ) ;204 Node n ;205 n = alphaBeta . returnMove (b) ;206 tBoard . copyBoard ( ) ;207 currentTurn++;208 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;209 showTurn++;210 tBoard . s e t P i e c e (n . wc , n . wr , white ) ;

188 Bilag A

211 tBoard . s e t P i e c e (n . bc , n . br , b lack ) ;212 Date time2 = new Date ( ) ;213 long t2 = time2 . getTime ( ) ;214 long t3 = t2−t1 ;215 System . out . p r i n t l n (”TM − ABTurn time : ”+t3 ) ;216 }217 // f o r e t a g e r et t raek ved h ja e lp a f pureAlphaBeta AI ’ en . (

s p i l l e r kun som s o r t )218 p r i v a t e void pureAlphaBetaTurn ( ) {219 Date time = new Date ( ) ;220 long t1 = time . getTime ( ) ;221 Node n ;222 n = pureAlphaBeta . returnMoveBlack ( ) ;223 tBoard . copyBoard ( ) ;224 currentTurn++;225 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;226 showTurn++;227 tBoard . s e t P i e c e (n . wc , n . wr , white ) ;228 tBoard . s e t P i e c e (n . bc , n . br , b lack ) ;229 Date time2 = new Date ( ) ;230 long t2 = time2 . getTime ( ) ;231 long t3 = t2−t1 ;232 System . out . p r i n t l n (”TM − PureABTurn time : ”+t3 ) ;233 }234 // f o r e t a g e r et t raek ved h ja e lp a f minimax2 AI ’ en . ( s p i l l e r

kun som s o r t )235 p r i v a t e void minimax2Turn ( ) {236 Date time = new Date ( ) ;237 long t1 = time . getTime ( ) ;238 Node n ;239 n = minimax2 . returnMoveBlack ( ) ;240 tBoard . copyBoard ( ) ;241 currentTurn++;242 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;243 showTurn++;244 tBoard . s e t P i e c e (n . wc , n . wr , white ) ;245 tBoard . s e t P i e c e (n . bc , n . br , b lack ) ;246 Date time2 = new Date ( ) ;247 long t2 = time2 . getTime ( ) ;248 long t3 = t2−t1 ;249 System . out . p r i n t l n (”TM − growthTurn time : ”+t3 ) ;250 }251 // f o r e t a g e r et t raek ved h ja e lp a f Growth AI ’ en .252 // b = true hv i s den s k a l s p i l l e sort , f a l s e f o r hvid253 p r i v a t e void growthTurn ( boolean b) {254 Date time = new Date ( ) ;255 long t1 = time . getTime ( ) ;256 Node n ;257 n = growth . returnMove (b) ;258 tBoard . copyBoard ( ) ;259 currentTurn++;260 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;261 showTurn++;262 tBoard . s e t P i e c e (n . wc , n . wr , white ) ;263 tBoard . s e t P i e c e (n . bc , n . br , b lack ) ;

A.13 TaijiModel.java 189

264 Date time2 = new Date ( ) ;265 long t2 = time2 . getTime ( ) ;266 long t3 = t2−t1 ;267 System . out . p r i n t l n (”TM − growthTurn time : ”+t3 ) ;268 }269270 // f o r e t a g e r et t raek ved h ja e lp a f LocalArea AI ’ en .271 // b = true hv i s den s k a l s p i l l e sort , f a l s e f o r hvid272 p r i v a t e void localAreaABTurn ( boolean b) {273 Date time = new Date ( ) ;274 long t1 = time . getTime ( ) ;275 Node n ;276 n = localAreaAB . returnMove (b) ;277 tBoard . copyBoard ( ) ;278 currentTurn++;279 tBoard . board [ 0 ] [ 0 ] [ 0 ] = currentTurn ;280 showTurn++;281 tBoard . s e t P i e c e (n . wc , n . wr , white ) ;282 tBoard . s e t P i e c e (n . bc , n . br , b lack ) ;283 Date time2 = new Date ( ) ;284 long t2 = time2 . getTime ( ) ;285 long t3 = t2−t1 ;286 System . out . p r i n t l n (”TM − LAABTurn time : ”+t3 ) ;287 }288289 //Bestemmer om der er nog le l o v l i g e ryk t i l b a g e .290 pub l i c boolean movesLeft ( )291 {292 f o r ( i n t c=0; c < noCols ; c++)293 {294 f o r ( i n t r =0; r < noRows−1; r++)295 {296 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 2 &&

tBoard . board [ currentTurn ] [ c ] [ r +1] == 2)

297 re turn ( t rue ) ;298 }299 }300 f o r ( i n t c=0; c < noCols−1; c++)301 {302 f o r ( i n t r =0; r < noRows ; r++)303 {304 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 2 &&

tBoard . board [ currentTurn ] [ c +1] [ r ] == 2)

305 re turn ( t rue ) ;306 }307 }308 re turn ( f a l s e ) ;309 }310311 //Bestemmer om der er nog le l o v l i g e ryk t i l b a g e f o r Noden n .312 pub l i c boolean movesLeftN (Node n)313 {314 f o r ( i n t c=0; c < noCols ; c++)

190 Bilag A

315 {316 f o r ( i n t r =0; r < noRows−1; r++)317 {318 i f (n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c

] [ r +1] == 2 )319 re turn ( t rue ) ;320 }321 }322 f o r ( i n t c=0; c < noCols−1; c++)323 {324 f o r ( i n t r =0; r < noRows ; r++)325 {326 i f (n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c

+1] [ r ] == 2 )327 re turn ( t rue ) ;328 }329 }330 re turn ( f a l s e ) ;331 }332333 // r e t u r n e r e r et g y l d i g t t raek334 pub l i c i n t [ ] getAMove (Node n) {335 i n t [ ] m = new i n t [ 4 ] ;336 f o r ( i n t c=0; c < noCols ; c++)337 {338 f o r ( i n t r =0; r < noRows−1; r++)339 {340 i f (n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c ] [ r +1]

== 2 ) {341 m[ 0 ] = c ;342 m[ 1 ] = r ;343 m[ 2 ] = c ;344 m[ 3 ] = r +1;345 re turn (m) ;346 }347 }348 }349 f o r ( i n t c=0; c < noCols−1; c++){350 {351 f o r ( i n t r =0; r < noRows ; r++)352 {353 i f (n . nodeBoard [ c ] [ r ] == 2 && n . nodeBoard [ c +1] [ r ]

== 2 ) {354 m[ 0 ] = c ;355 m[ 1 ] = r ;356 m[ 2 ] = c +1;357 m[ 3 ] = r ;358 re turn (m) ;359 }360 }361 }362 }363 re turn (m) ;364 }365

A.13 TaijiModel.java 191

366 // Undersoeger om et ryk er l o v l i g t i s p i l l e t s nuvaerende tur .367 //Modtager p o s i t i o n e n der rykkes f r a og t i l som argumenter ,

r e t u r n e r e r t rue hv i s rykket er l o v l i g t .368 pub l i c boolean checkMove ( i n t [ ] [ ] b , i n t curCol , i n t curRow )369 {370 boolean r e s u l t = f a l s e ;371 i f ( c l i c k == f a l s e )372 {373 // Midtersekt ionen374 i f ( ( curCol > 0) && ( curCol < noCols−1) && ( curRow > 0) &&

( curRow < noRows−1) )375 {376 i f ( checkMidle (b , curCol , curRow ) )377 {378 r e s u l t = true ;379 }380 re turn ( r e s u l t ) ;381 }382 e l s e383 {384 // Venstre s i d e385 i f ( ( curCol == 0) && ( curRow > 0) && ( curRow < noRows

−1) )386 {387 i f ( checkLe f t (b , curCol , curRow ) )388 {389 r e s u l t = true ;390 }391 re turn ( r e s u l t ) ;392 }393 e l s e394 {395 // Hoejre s i d e396 i f ( ( curCol == noCols−1) && ( curRow > 0) && ( curRow

< noRows−1) )397 {398 i f ( checkRight (b , curCol , curRow ) )399 {400 r e s u l t = true ;401 }402 re turn ( r e s u l t ) ;403 }404 e l s e405 {406 //Toppen407 i f ( ( curCol > 0) && ( curCol < noCols−1) && (

curRow == 0) )408 {409 i f ( checkTop (b , curCol , curRow ) )410 {411 r e s u l t = true ;412 }413 re turn ( r e s u l t ) ;414 }415 e l s e

192 Bilag A

416 {417 //Bunden418 i f ( ( curCol > 0) && ( curCol < noCols−1) &&

( curRow == noRows−1) )419 {420 i f ( checkBottom (b , curCol , curRow ) )421 {422 r e s u l t = true ;423 }424 re turn ( r e s u l t ) ;425 }426 e l s e427 {428 // o e v e r s t e vens t r e h joerne429 i f ( curCol == 0 && curRow == 0)430 {431 i f ( checkTLC (b , curCol , curRow ) )432 {433 r e s u l t = true ;434 }435 re turn ( r e s u l t ) ;436 }437 e l s e438 {439 // o e v e r s t e hoe j r e h joe rne440 i f ( curCol == noCols−1 && curRow ==

0)441 {442 i f ( checkTRC(b , curCol , curRow )

)443 {444 r e s u l t = true ;445 }446 re turn ( r e s u l t ) ;447 }448 e l s e449 {450 // Nederste vens t r e h joerne451 i f ( curCol == 0 && curRow ==

noRows−1)452 {453 i f ( checkBLC (b , curCol ,

curRow ) )454 {455 r e s u l t = true ;456 }457 re turn ( r e s u l t ) ;458 }459 e l s e460 {461 // Nederste hoe j r e h joe rne462 i f ( curCol == noCols−1 &&

curRow == noRows−1)463 {

A.13 TaijiModel.java 193

464 i f ( checkBRC(b , curCol ,curRow ) )

465 {466 r e s u l t = true ;467 }468 re turn ( r e s u l t ) ;469 }470 }471 }472 }473 }474 }475 }476 }477 }478 }479 e l s e480 // check f o r andet k l i k ( p l a c e r i ng en a f den s o r t e de l a f

br ikken )481 i f ( ( b [ curCol ] [ curRow ] == 2) && ( ( ( curCol == preCol+1) && (

curRow == preRow ) ) | | ( ( curCol == preCol−1) && ( curRow== preRow ) ) | | ( ( curCol == preCol ) && ( curRow ==preRow+1) ) | | ( ( curCol == preCol ) && ( curRow == preRow−1) ) ) )

482 {483 r e s u l t = true ;484 re turn ( r e s u l t ) ;485 }486 re turn ( r e s u l t ) ;487 }488489 // anvendes i checkMove490 p r i v a t e boolean checkMidle ( i n t [ ] [ ] b , i n t Col , i n t Row)491 {492 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | (b [ Col ] [

Row−1] == 2 ) | | (b [ Col +1] [Row] == 2 ) | | (b [ Col −1] [Row] ==2 ) ) ) )

493 {494 re turn ( t rue ) ;495 }496 re turn ( f a l s e ) ;497 }498499 // anvendes i checkMove500 p r i v a t e boolean checkLe f t ( i n t [ ] [ ] b , i n t Col , i n t Row)501 {502 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | (b [ Col ] [

Row−1] == 2 ) | | (b [ Col +1] [Row] == 2 ) ) ) )503 {504 re turn ( t rue ) ;505 }506 re turn ( f a l s e ) ;507 }508509 // anvendes i checkMove

194 Bilag A

510 p r i v a t e boolean checkRight ( i n t [ ] [ ] b , i n t Col , i n t Row)511 {512 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | (b [ Col

] [ Row−1] == 2 ) | | (b [ Col −1] [Row] == 2 ) ) ) )513 {514 re turn ( t rue ) ;515 }516 re turn ( f a l s e ) ;517 }518519 // anvendes i checkMove520 p r i v a t e boolean checkTop ( i n t [ ] [ ] b , i n t Col , i n t Row)521 {522 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | (b [ Col

+1] [Row] == 2 ) | | (b [ Col −1] [Row] == 2 ) ) ) )523 {524 re turn ( t rue ) ;525 }526 re turn ( f a l s e ) ;527 }528529 // anvendes i checkMove530 p r i v a t e boolean checkBottom ( i n t [ ] [ ] b , i n t Col , i n t Row)531 {532 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row−1] == 2 ) | | (b [ Col

+1] [Row] == 2 ) | | (b [ Col −1] [Row] == 2 ) ) ) )533 {534 re turn ( t rue ) ;535 }536 re turn ( f a l s e ) ;537 }538539 // anvendes i checkMove540 p r i v a t e boolean checkTLC ( i n t [ ] [ ] b , i n t Col , i n t Row)541 {542 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | (b [ Col

+1] [Row] == 2 ) ) ) )543 {544 re turn ( t rue ) ;545 }546 re turn ( f a l s e ) ;547 }548549 // anvendes i checkMove550 p r i v a t e boolean checkTRC ( i n t [ ] [ ] b , i n t Col , i n t Row)551 {552 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row+1] == 2 ) | | (b [ Col

−1] [Row] == 2 ) ) ) )553 {554 re turn ( t rue ) ;555 }556 re turn ( f a l s e ) ;557 }558559 // anvendes i checkMove

A.13 TaijiModel.java 195

560 p r i v a t e boolean checkBLC ( i n t [ ] [ ] b , i n t Col , i n t Row)561 {562 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row−1] == 2 ) | | (b [ Col

+1] [Row] == 2 ) ) ) )563 {564 re turn ( t rue ) ;565 }566 re turn ( f a l s e ) ;567 }568569 // anvendes i checkMove570 p r i v a t e boolean checkBRC ( i n t [ ] [ ] b , i n t Col , i n t Row)571 {572 i f ( ( b [ Col ] [ Row] == 2) && ( ( ( b [ Col ] [ Row−1] == 2 ) | | (b [ Col

−1] [Row] == 2 ) ) ) )573 {574 re turn ( t rue ) ;575 }576 re turn ( f a l s e ) ;577 }578579580581582583584 // Undersoeger om der er en vinder , i den nuvaerende tur .585 p r i v a t e i n t gameOver ( )586 {587 i f ( fMap == n u l l )588 System . out . p r i n t l n (” Nul l ”) ;589 i n t [ ] s ;590 s = new i n t [ 2 ] ;591 s = fMap . ca lS co r e ( tBoard . board [ currentTurn ] , noCols

, noRows) ;592 whScore = s [ 0 ] ;593 b lScore = s [ 1 ] ;594 i n t winner= −1;595 i f ( movesLeft ( ) == f a l s e && c l i c k == f a l s e )596 {597 i f ( whScore > b lScore )598 {599 winner = 1 ;600 }601 i f ( b lScore > whScore )602 {603 winner = 0 ;604 }605 i f ( b lScore == whScore )606 {607 winner = 2 ;608 }609 }610611 re turn winner ;

196 Bilag A

612 }613614 // beregner det h o e j s t anta l mulige t i l bagevae r ende t raek615 pub l i c i n t maxTurnsLeft ( ) {616 i n t turns , boxed ; // Boxed er a n t a l l e t a f e n k e l t e

ind lykkede f r i e f e l t e r617 boxed = getBoxedIn ( ) ;618 turns = (noRows∗noCols /2) − ( currentTurn−1) − ( boxed /2) ;619 re turn ( turns ) ;620 }621622 // f i n d e r a n t a l l e t a f f r i e inde lukkede f e l t e r . (De f r i e f e l t e r

hvor det ikke l a enge r e er mul igt at p l a c e r e en br ik paa . )623 pub l i c i n t getBoxedIn ( ) {624 i n t boxed = 0 ;625 f o r ( i n t r =0; r < noRows ; r++){626 f o r ( i n t c =0; c < noCols ; c++){ // was noRows627 i f ( getPieceAt ( c , r ) == 2) {628 i f (0 < r && r < noRows−1){ // Midten a f

raekkerne629 i f (0 < c && c < noCols−1)630 i f ( getPieceAt ( c+1 , r ) != 2 &&

getPieceAt ( c−1 , r ) != 2 &&getPieceAt ( c , r+1) != 2 &&getPieceAt ( c , r−1) != 2)

631 boxed++;632 i f ( c == 0)633 i f ( getPieceAt ( c+1 , r ) != 2 &&

getPieceAt ( c , r+1) != 2 &&getPieceAt ( c , r−1) != 2)

634 boxed++;635 i f ( c == noCols−1)636 i f ( getPieceAt ( c−1 , r ) != 2 &&

getPieceAt ( c , r+1) != 2 &&getPieceAt ( c , r−1) != 2)

637 boxed++;638 }639 i f ( r == 0) { // o e v e r s t e raekke640 i f (0 < c && c < noCols−1)641 i f ( getPieceAt ( c+1 , r ) != 2 &&

getPieceAt ( c−1 , r ) != 2 &&getPieceAt ( c , r+1) != 2)

642 boxed++;643 i f ( c == 0)644 i f ( getPieceAt ( c+1 , r ) != 2 &&

getPieceAt ( c , r+1) != 2)645 boxed++;646 i f ( c == noCols−1)647 i f ( getPieceAt ( c−1 , r ) != 2 &&

getPieceAt ( c , r+1) != 2)648 boxed++;649 }650 i f ( r == noRows−1){ // Nedereste raekke651 i f (0 < c && c < noCols−1)

A.13 TaijiModel.java 197

652 i f ( getPieceAt ( c+1 , r ) != 2 &&getPieceAt ( c−1 , r ) != 2 &&getPieceAt ( c , r−1) != 2)

653 boxed++;654 i f ( c == 0)655 i f ( getPieceAt ( c+1 , r ) != 2 &&

getPieceAt ( c , r−1) != 2)656 boxed++;657 i f ( c == noCols−1)658 i f ( getPieceAt ( c−1 , r ) != 2 &&

getPieceAt ( c , r−1) != 2)659 boxed++;660 }661 }662 }663 }664665666667 re turn ( boxed ) ;668 }669670 // r e t u r n e r e r whScore671 pub l i c i n t getWhiteScore ( )672 {673 re turn ( whScore ) ;674 }675 // r e t u r n e r e r b lScore676 pub l i c i n t getBlackScore ( )677 {678 re turn ( b lScore ) ;679 }680681 // Returnere den nuvaerende tur .682 pub l i c i n t getCurrentTurn ( )683 {684 re turn ( currentTurn ) ;685 }686687 // Returnere den tur /” anta l b r i kke r paa b r a e t t e t ” der s k a l v i s e s

i GUI ’ en .688 pub l i c i n t getShowTurn ( )689 {690 re turn ( showTurn ) ;691 }692693 // 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 .694 pub l i c void setShowTurn ( )695 {696 showTurn = currentTurn −1;697 }698699 // 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 = sort , 1 = hvid )700 pub l i c void s e t S t a r t e r ( i n t s ) {701 s t a r t e r = s ;

198 Bilag A

702 }703704 // s a e t t e r hvem der s p i l l e r hvid705 pub l i c void setWhitePlayer ( i n t w) {706 whitePlayer = w;707 }708709 // s a e t t e r hvem der s p i l l e r s o r t710 pub l i c void se tB lackPlayer ( i n t b) {711 b lackPlayer = b ;712 }713714 // Returnere a n t a l l e t a f ko lonner .715 pub l i c i n t getNoCols ( )716 {717 re turn ( noCols ) ;718 }719720 // Returnere a n t a l l e t a f raekker .721 pub l i c i n t getNoRows ( )722 {723 re turn (noRows) ;724 }725726 // Returnerer den nuvaerende s p i l l e r .727 pub l i c i n t getCurrentPlayer ( )728 {729 re turn ( cur r entP laye r ) ;730 }731732 // r e t u r n e r e r he l e braet h i s t o r i e n f o r nuvaerende s p i l733 pub l i c i n t [ ] [ ] [ ] getBoard ( )734 {735 i n t [ ] [ ] [ ] b = tBoard . getBoard ( ) ;736 re turn (b) ;737 }738739 // r e t u r n e r e r braet f o r t raek nr . t740 pub l i c i n t [ ] [ ] getOneBoard ( i n t t )741 {742 // tBoard . copyBoardTo ( t +1) ;743 // i n t [ ] [ ] b = tBoard . getOneBoard ( t ) ;744 i n t [ ] [ ] b = tBoard . getClone ( t ) ;745 re turn (b) ;746 }747748 // r e t u r n e r e r fa rven a f br ikken paa plads ( co l , row ) ( sort , hvid

, f r i )749 pub l i c i n t getPieceAt ( i n t co l , i n t row )750 {751 i n t p = tBoard . getPieceAt ( co l , row ) ;752 re turn (p) ;753 }754

A.13 TaijiModel.java 199

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 co r e f o r b r a e t t e tnb

756 pub l i c i n t ge tD i f ( i n t [ ] [ ] nb )757 {758 i n t d i f = fMap . c a l D i f (nb , noCols , noRows) ;759 re turn ( d i f ) ;760 }761762 // 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 , hv i s der

s k i f t e s t i l u l i g e tur , sor t , hv i s det er en l i g e tur .763 pub l i c void turnBack ( )764 {765 i f ( currentTurn > 1)766 {767 currentTurn−−;768 showTurn−−;769 cur r entP laye r = currentTurn % 2 ;770 i n t [ ] s ;771 s = new i n t [ 2 ] ;772 s = fMap . ca lS co r e ( tBoard . board [ currentTurn ] , noCols

, noRows) ;773 whScore = s [ 0 ] ;774 b lScore = s [ 1 ] ;775 }776 }777778 // 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 , hv i s der

s k i f t e s t i l en u l i g e tur , sor t , hv i s der s k i f t e s t i l enl i g e tur .

779 pub l i c void turnForward ( )780 {781 i f ( currentTurn < tBoard . board [ 0 ] [ 0 ] [ 0 ] )782 {783 currentTurn++;784 showTurn++;785 cur r entP laye r = currentTurn % 2 ;786 i n t [ ] s ;787 s = new i n t [ 2 ] ;788 s = fMap . ca lS co r e ( tBoard . board [ currentTurn ] , noCols

, noRows) ;789 whScore = s [ 0 ] ;790 b lScore = s [ 1 ] ;791 }792 }793794 // S k i f t e r t i l den naes te s p i l l e r , s o r t hv i s nuvaerende er hvid ,

og v i c e ver sa .795 pub l i c void changePlayer ( )796 {797 cur r entP laye r = ( cur rentP laye r +1) % 2 ;798 }799800 //Modtager et nyt braet ( f r a et gemt s p i l ) , s a e t t e r den

nuvaerende tur t i l turen gemt i [ 0 ] [ 0 ] [ 0 ] i det nye board .801 //Modtager et 3−d imens ione l t array som argument .

200 Bilag A

802 pub l i c void newBoard ( i n t [ ] [ ] [ ] board )803 {804 t h i s . tBoard . board = board ;805 currentTurn = board [ 0 ] [ 0 ] [ 0 ] ;806 cur r entP laye r = currentTurn % 2 ;807 i n t [ ] s ;808 s = new i n t [ 2 ] ;809 s = fMap . ca lS co r e ( board [ currentTurn ] , noCols , noRows) ;810 whScore = s [ 0 ] ;811 b lScore = s [ 1 ] ;812 }813814 // Returnerer det maksimale anta l ture programmet kan haandtere .815 pub l i c i n t getMaxTurns ( )816 {817 re turn ( maxTurns ) ;818 }819820 // Returnerer det s e n e s t e traek , ua fhaeng ig t a f hv i lken type

s p i l l e r der har f o r e t a g e t det821 pub l i c i n t [ ] getLatestMove ( ) {822 i n t [ ] t = new i n t [ 4 ] ;823 i f ( currentTurn == 0) {824 re turn ( t ) ;825 }826 f o r ( i n t c=0; c < noCols ; c++){827 f o r ( i n t r =0; r < noRows ; r++){828 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] != tBoard . board

[ currentTurn −1] [ c ] [ r ] ) {829 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 1) {830 t [0 ]= c ;831 t [1 ]= r ;832 }833 i f ( tBoard . board [ currentTurn ] [ c ] [ r ] == 0) {834 t [2 ]= c ;835 t [3 ]= r ;836 }837 }838 }839 }840 re turn ( t ) ;841 }842843844 }

A.14 TaijiPanels.java

12 import javax . swing . ∗ ;3 import java . awt . ∗ ;4 import java . lang . ∗ ;5

A.14 TaijiPanels.java 201

6 // Klassen Ta i j iPane 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 oga l l e b r i kke r v i s e s .

7 //Er nedarvet f r a JPanel .8 c l a s s Ta i j iPane l extends JPanel9 {

1011 // Var i ab l e r med in fo rmat ion om b r a e t t e t s udseende .12 p r i v a t e i n t noRows , noCols ;1314 //En Taij iFrame som metoderne i Ta i j iPane l kan r e f e r e r e t i l .15 p r i v a t e Taij iFrame tFrame ;16 // p r i v a t e Board tBoard ;1718 // Constructor . Giver tFrame en vaerd i saa der kan r e f e r e r e s t i l

den , d e f i n e r e r a n t a l l e t a f raekker og s o e j l e r .19 //Modtager en tFrame som argument .20 pub l i c Ta i j iPane l ( Taij iFrame frame )21 {22 tFrame = frame ;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 ) ;24 t h i s . addMouseListener ( a b l i s ) ;25 noRows = tFrame . tModel . getNoRows ( ) ;26 noCols = tFrame . tModel . getNoCols ( ) ;27 t h i s . setBackground ( Color . gray ) ;28 t h i s . s e t P r e f e r r e d S i z e (new Dimension (500 ,500) ) ;29 }3031 // Tegner s e l v e b r a e t t e t .32 pub l i c void paintComponent ( Graphics g )33 {34 super . paintComponent ( g ) ;35 i n t width = t h i s . getWidth ( ) ;36 i n t he ight = t h i s . getHeight ( ) ;37 i n t colWidth = width/ noCols ;38 i n t rowHeight = he ight /noRows ;3940 g . s e tCo lo r ( Color . b lack ) ;4142 f o r ( i n t i = 1 ; i <= noCols − 1 ; i++)43 {44 g . drawLine ( i ∗colWidth , 0 , i ∗colWidth , he ight ) ;45 }4647 f o r ( i n t i = 1 ; i <= noRows − 1 ; i++)48 {49 g . drawLine (0 , i ∗ rowHeight , width , i ∗ rowHeight ) ;50 }5152 f o r ( i n t c = 0 ; c < noCols ; c++) // was noRows53 {54 f o r ( i n t r = 0 ; r < noRows ; r++) // was noCols55 {56 i f ( tFrame . tModel . getPieceAt ( c , r ) == 1)57 {58 g . s e tCo lo r ( Color . white ) ;

202 Bilag A

59 g . f i l l R e c t ( c∗colWidth , r ∗ rowHeight ,colWidth , rowHeight ) ;

60 }61 e l s e i f ( tFrame . tModel . getPieceAt ( c , r ) == 0)62 {63 g . s e tCo lo r ( Color . b lack ) ;64 g . f i l l R e c t ( c∗colWidth , r ∗ rowHeight ,

colWidth , rowHeight ) ;65 }66 }67 }68 }69 }7071 // Klassen ScorePanel v i s e r scoren f o r enten hvid e l l e r s o r t s p i l l e r

.72 //Er nedarvet f r a JPanel .73 c l a s s ScorePanel extends JPanel74 {7576 // Var iabe l der v i s e r scoren i o e j e b l i k k e t . Samt ang iver hv i l ken

s p i l l e r s co r e ScorePanel s k a l v i s e .77 p r i v a t e i n t s co r e ;78 p r i v a t e i n t playerNumber ;7980 //En Taij iFrame som metoderne i Ta i j iPane l kan r e f e r e r e t i l .81 p r i v a t e Taij iFrame tFrame ;8283 // Constructor .84 //Modtager en frame og en s p i l l e r som argumenter .85 pub l i c ScorePanel ( Taij iFrame frame , i n t p laye r )86 {87 tFrame = frame ;88 playerNumber = player ;89 t h i s . s e t P r e f e r r e d S i z e (new Dimension (50 ,500) ) ;90 }9192 // Vise 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 .93 pub l i c void paintComponent ( Graphics g )94 {95 super . paintComponent ( g ) ;96 St r ing s c o r e S t r i n g ;97 i n t middleHeight = ( t h i s . getHeight ( ) /2) ;98 i n t middleWidth = ( t h i s . getWidth ( ) /2) ;99 i f ( playerNumber == 1)

100 {101 s co r e = tFrame . tModel . getWhiteScore ( ) ;102 s c o r e S t r i n g = ”” + sco r e ;103 t h i s . setBackground ( Color . gray ) ;104 g . s e tCo lo r ( Color . white ) ;105 g . drawString ( s co r eS t r i ng , middleWidth , middleHeight

) ;106 }107 e l s e108 {

A.14 TaijiPanels.java 203

109 s co r e = tFrame . tModel . getBlackScore ( ) ;110 s c o r e S t r i n g = ”” + sco r e ;111 t h i s . setBackground ( Color . gray ) ;112 g . s e tCo lo r ( Color . b lack ) ;113 g . drawString ( s co r eS t r i ng , middleWidth , middleHeight

) ;114 }115 }116 }117118 // Klassen TurnPanel v i s e r hv i lken f a r v e s tur det er . Bruges ogsaa

t i l at gaa frem og t i l b a g e gennem turene .119 //Er nedarvet f r a JPanel .120 c l a s s TurnPanel extends JPanel121 {122 p r i v a t e Taij iFrame uFrame ;123124 //En l a b e l som v i s e r hvor mange br i kke r der er b l ev e t l a g t ( tur

) .125 p r i v a t e JLabel uLabel ;126127 // Constructor .128 //Modtager Taij iFrame som argument .129 pub l i c TurnPanel ( Taij iFrame frame )130 {131 uFrame = frame ;132133 t h i s . s e t P r e f e r r e d S i z e (new Dimension (500 ,50) ) ;134 t h i s . setBackground ( Color . l i ghtGray ) ;135136137 BorderLayout bLayout = new BorderLayout ( ) ;138 t h i s . setLayout ( bLayout ) ;139140 JButton fButton = new JButton (” Next Turn ”) ;141 JButton bButton = new JButton (” Last Turn ”) ;142 uLabel = new JLabel (””+ uFrame . tModel . getShowTurn ( ) ,

SwingConstants .CENTER) ;143144 t h i s . add ( fButton , ”East ”) ;145 t h i s . add ( uLabel , ” Center ”) ;146 t h i s . add ( bButton , ”West”) ;147148 TurnListener t L i s t = new TurnListener (uFrame) ;149 fButton . addAct ionLis tener ( t L i s t ) ;150 bButton . addAct ionLis tener ( t L i s t ) ;151152 }153154 // Opdaterer uLabel og s k i f t e r baggrundsfarven e f t e r hv i l ken

s p i l l e r s tur det er .155 pub l i c void update ( )156 {157 uLabel . setText (””+uFrame . tModel . getShowTurn ( ) ) ;158 i f (uFrame . tModel . getCurrentPlayer ( ) == 1)

204 Bilag A

159 {160 t h i s . setBackground ( Color . l i ghtGray ) ;161 }162 e l s e163 {164 t h i s . setBackground ( Color . gray ) ;165 }166 }167168 }

A.15 TaijiPrint.java

1 // denne k l a s s e r s t aa r f o r at udsk r i v e r indeho lde t a f Nodes t i lt e s t formaal

2 pub l i c c l a s s T a i j i P r i n t {3 pub l i c Tai j iModel tModel ;45 pub l i c T a i j i P r i n t ( Tai j iModel m) {6 t h i s . tModel = m;7 }89 // udsk r i v e r vae rd i e rne f o r f o r a e l d r e n e t i l Noden n

10 pub l i c void pr intParScore (Node n) {11 System . out . p r i n t (” tPr in t pr intParScore d=”+n . d+” n . par

s c o r e s : ”) ;12 f o r ( i n t i =0; i<n . par . s i z e ( ) ; i++){13 System . out . p r i n t (n . par . get ( i ) . a+” ”) ;14 }15 System . out . p r i n t l n (” end n . a=”+n . a ) ;16 }1718 // a l t e r n a t i v t t i l p r in tCh i ld r en19 pub l i c void pr in tCh i ld r en2 (Node n) {20 i f ( tModel . noCols == 3)21 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++)22 printNode3x (n . c h i l d r e n . get ( i ) ) ;23 e l s e24 i f ( tModel . noCols == 4)25 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++)26 printNode4x (n . c h i l d r e n . get ( i ) ) ;27 e l s e28 i f ( tModel . noCols == 5)29 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++)30 printNode5x (n . c h i l d r e n . get ( i ) ) ;31 e l s e32 i f ( tModel . noCols == 6)33 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++)34 printNode6x (n . c h i l d r e n . get ( i ) ) ;35 e l s e36 i f ( tModel . noCols == 7)37 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++)38 printNode7x (n . c h i l d r e n . get ( i ) ) ;

A.15 TaijiPrint.java 205

39 e l s e40 i f ( tModel . noCols == 8)41 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ;

i++)42 printNode8x (n . c h i l d r e n . get ( i ) ) ;43 e l s e44 i f ( tModel . noCols == 9)45 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e

( ) ; i++)46 printNode9x (n . c h i l d r e n . get ( i ) ) ;47 }4849 // udsk r i v e r braet og anden in fo rmat ion f o r boernene a f Noden n50 // og t i l f o r s k e l f r a pr intCHi ldren 2 f o r de et nummer saa de

er nemmere at holde s t y r paa51 pub l i c void pr in tCh i ld r en (Node n) {52 i f ( tModel . noCols == 3)53 pr intChi ldren3x (n) ;54 e l s e55 i f ( tModel . noCols == 4)56 pr intCh i ldren4x (n) ;57 e l s e58 i f ( tModel . noCols == 5)59 pr intCh i ldren5x (n) ;60 e l s e61 i f ( tModel . noCols == 6)62 pr intCh i ldren6x (n) ;63 e l s e64 i f ( tModel . noCols == 7)65 pr intCh i ldren7x (n) ;66 e l s e67 i f ( tModel . noCols == 8)68 pr intCh i ldren8x (n) ;69 e l s e70 i f ( tModel . noCols == 9)71 pr intCh i ld ren9x (n) ;72 }7374 // f o r braet med 3 ko loner75 pub l i c void pr intCh i ldren3x (Node n) {76 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;77 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){78 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth :

”+n . c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get( i ) . a ) ;

79 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 . 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 . get ( i ) . br+” w ”+n . c h i l d r e n . get (i ) . wc+”,”+n . 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+” ”+n . c h i l d r e n . get ( i ) . nodeBoard) ;

80 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard[ 0 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 0 ] ) ;

206 Bilag A

81 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard[ 0 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 1 ] ) ;

82 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard[ 0 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 2 ] ) ;

83 i f ( tModel . noRows > 3) {84 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 3 ] ) ;

85 i f ( tModel . noRows > 4) {86 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 4 ] ) ;

87 i f ( tModel . noRows > 5) {88 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 5 ] ) ;

89 i f ( tModel . noRows > 6) {90 System . out . p r i n t l n (n . c h i l d r e n . get ( i

) . nodeBoard [ 0 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 6 ] ) ;

91 i f ( tModel . noRows > 7) {92 System . out . p r i n t l n (n . c h i l d r e n .

get ( i ) . nodeBoard [ 0 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 7 ] ) ;

93 i f ( tModel . noRows > 8) {94 System . out . p r i n t l n (n .

c h i l d r e n . get ( i ) .nodeBoard [ 0 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 8 ] ) ;

95 i f ( tModel . noRows > 9) {96 System . out . p r i n t l n (n .

c h i l d r e n . get ( i ) .nodeBoard [ 0 ] [ 9 ] + ””+n . c h i l d r e n . get ( i ). nodeBoard [ 1 ] [ 9 ] + ””+n . c h i l d r e n . get ( i ). nodeBoard [ 2 ] [ 9 ] ) ;

97 }98 }99 }

100 }101 }102 }

A.15 TaijiPrint.java 207

103 }104 System . out . p r i n t l n ( ) ;105 }106 }107108 // f o r braet med 4 ko loner109 pub l i c void pr intCh i ldren4x (Node n) {110 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;111 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){112 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n

. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;113 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

. 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

. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .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+””+n . c h i l d r e n . get ( i ) . nodeBoard ) ;

114 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 0 ] ) ;

115 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 1 ] ) ;

116 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 2 ] ) ;

117 i f ( tModel . noRows > 3) {118 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] ) ;

119 i f ( tModel . noRows > 4) {120 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 4 ] ) ;

121 i f ( tModel . noRows > 5) {122 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 5 ] ) ;

123 i f ( tModel . noRows > 6) {124 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] ) ;

125 i f ( tModel . noRows > 7) {126 System . out . p r i n t l n (n . c h i l d r e n . get ( i

) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard

208 Bilag A

[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 3 ] [ 7 ] ) ;

127 i f ( tModel . noRows > 8) {128 System . out . p r i n t l n (n . c h i l d r e n .

get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 8 ] ) ;

129130 }131 }132 }133 }134 }135 }136 System . out . p r i n t l n ( ) ;137 }138 }139140 // f o r braet med 5 ko loner141 pub l i c void pr intCh i ldren5x (Node n) {142 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;143 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){144 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n

. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;145 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

. 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

. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .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+””+n . c h i l d r e n . get ( i ) . nodeBoard ) ;

146 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 0 ] ) ;

147 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 1 ] ) ;

148 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 2 ] ) ;

149 i f ( tModel . noRows > 3) {150 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 4 ] [ 3 ] ) ;

151 i f ( tModel . noRows > 4) {

A.15 TaijiPrint.java 209

152 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 4 ] ) ;

153 i f ( tModel . noRows > 5) {154 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 4 ] [ 5 ] ) ;

155 i f ( tModel . noRows > 6) {156 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 6 ] ) ;

157 i f ( tModel . noRows > 7) {158 System . out . p r i n t l n (n . c h i l d r e n . get ( i

) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 7 ] ) ;

159 i f ( tModel . noRows > 8) {160 System . out . p r i n t l n (n . c h i l d r e n .

get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 4 ] [ 8 ] ) ;

161162 }163 }164 }165 }166 }167 }168 System . out . p r i n t l n ( ) ;169 }170 }171172 // f o r braet med 6 ko loner173 pub l i c void pr intCh i ldren6x (Node n) {174 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;175 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){

210 Bilag A

176 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;

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. 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. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .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+””+n . c h i l d r e n . get ( i ) . nodeBoard ) ;

178 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 0 ] ) ;

179 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 1 ] ) ;

180 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 2 ] ) ;

181 i f ( tModel . noRows > 3) {182 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 3 ] ) ;

183 i f ( tModel . noRows > 4) {184 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 4 ] ) ;

185 i f ( tModel . noRows > 5) {186 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 5 ] ) ;

187 i f ( tModel . noRows > 6) {188 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 6 ] ) ;

189 i f ( tModel . noRows > 7) {

A.15 TaijiPrint.java 211

190 System . out . p r i n t l n (n . c h i l d r e n . get ( i) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 7 ] ) ;

191 i f ( tModel . noRows > 8) {192 System . out . p r i n t l n (n . c h i l d r e n .

get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 8 ] ) ;

193194 }195 }196 }197 }198 }199 }200 System . out . p r i n t l n ( ) ;201 }202 }203204 // f o r braet med 7 ko loner205 pub l i c void pr intCh i ldren7x (Node n) {206 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;207 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){208 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n

. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;209 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

. 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

. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .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+””+n . c h i l d r e n . get ( i ) . nodeBoard ) ;

210 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 0 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 0 ] ) ;

211 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 1 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 1 ] ) ;

212 Bilag A

212 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 2 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 2 ] ) ;

213 i f ( tModel . noRows > 3) {214 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 6 ] [ 3 ] ) ;

215 i f ( tModel . noRows > 4) {216 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 6 ] [ 4 ] ) ;

217 i f ( tModel . noRows > 5) {218 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 6 ] [ 5 ] ) ;

219 i f ( tModel . noRows > 6) {220 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 6 ] [ 6 ] ) ;

221 i f ( tModel . noRows > 7) {222 System . out . p r i n t l n (n . c h i l d r e n . get ( i

) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 6 ] [ 7 ] ) ;

223 i f ( tModel . noRows > 8) {

A.15 TaijiPrint.java 213

224 System . out . p r i n t l n (n . c h i l d r e n .get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 6 ] [ 8 ] ) ;

225226 }227 }228 }229 }230 }231 }232 System . out . p r i n t l n ( ) ;233 }234 }235236 // f o r braet med 8 ko loner237 pub l i c void pr intCh i ldren8x (Node n) {238 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;239 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){240 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n

. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;241 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

. 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

. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .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+””+n . c h i l d r e n . get ( i ) . nodeBoard ) ;

242 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 0 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 0 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 7 ] [ 0 ] ) ;

243 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 1 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 1 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 7 ] [ 1 ] ) ;

244 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 2 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 2 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 7 ] [ 2 ] ) ;

245 i f ( tModel . noRows > 3) {

214 Bilag A

246 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 6 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 7 ] [ 3 ] ) ;

247 i f ( tModel . noRows > 4) {248 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 6 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 7 ] [ 4 ] ) ;

249 i f ( tModel . noRows > 5) {250 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 6 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 7 ] [ 5 ] ) ;

251 i f ( tModel . noRows > 6) {252 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 6 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 7 ] [ 6 ] ) ;

253 i f ( tModel . noRows > 7) {254 System . out . p r i n t l n (n . c h i l d r e n . get ( i

) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 6 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 7 ] [ 7 ] ) ;

255 i f ( tModel . noRows > 8) {256 System . out . p r i n t l n (n . c h i l d r e n .

get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard

A.15 TaijiPrint.java 215

[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 6 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 7 ] [ 8 ] ) ;

257258 }259 }260 }261 }262 }263 }264 System . out . p r i n t l n ( ) ;265 }266 }267268 // f o r braet med 9 ko loner269 pub l i c void pr intCh i ldren9x (Node n) {270 System . out . p r i n t l n (” tPr in t Pr int Chi ldren ”+n) ;271 f o r ( i n t i =0; i<n . c h i l d r e n . s i z e ( ) ; i++){272 System . out . p r i n t l n ( i+” ”+n . c h i l d r e n . get ( i )+” Depth : ”+n

. c h i l d r e n . get ( i ) . d+” Score ”+n . c h i l d r e n . get ( i ) . a ) ;273 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

. 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

. get ( i ) . br+” w ”+n . c h i l d r e n . get ( i ) . wc+”,”+n .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+””+n . c h i l d r e n . get ( i ) . nodeBoard ) ;

274 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 0 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 0 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 0 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 0 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 7 ] [ 0 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 8 ] [ 0 ] ) ;

275 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 1 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 1 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 1 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 1 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 7 ] [ 1 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 8 ] [ 1 ] ) ;

276 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard [ 0 ] [ 2 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 2 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 5 ] [ 2 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 6 ] [ 2 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 7 ] [ 2 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard

216 Bilag A

[ 8 ] [ 2 ] ) ;277 i f ( tModel . noRows > 3) {278 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 1 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 2 ] [ 3 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 3 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 4 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 6 ] [ 3 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard [ 7 ] [ 3 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard [ 8 ] [ 3 ] ) ;

279 i f ( tModel . noRows > 4) {280 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) . nodeBoard

[ 0 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 2 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 6 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 7 ] [ 4 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 8 ] [ 4 ] ) ;

281 i f ( tModel . noRows > 5) {282 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 1 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 3 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 4 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 6 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 7 ] [ 5 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 8 ] [ 5 ] ) ;

283 i f ( tModel . noRows > 6) {284 System . out . p r i n t l n (n . c h i l d r e n . get ( i ) .

nodeBoard [ 0 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 1 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 2 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 3 ] [ 6 ] + ””+n . c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 6 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 6 ] + ” ”+n . c h i l d r e n . get (i ) . nodeBoard [ 6 ] [ 6 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 7 ] [ 6 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard [ 8 ] [ 6 ] ) ;

285 i f ( tModel . noRows > 7) {286 System . out . p r i n t l n (n . c h i l d r e n . get ( i

) . nodeBoard [ 0 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 2 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 3 ] [ 7 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 4 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 5 ] [ 7 ] + ” ”+n . c h i l d r e n .get ( i ) . nodeBoard [ 6 ] [ 7 ] + ” ”+n .

A.15 TaijiPrint.java 217

c h i l d r e n . get ( i ) . nodeBoard[ 7 ] [ 7 ] + ” ”+n . c h i l d r e n . get ( i ) .nodeBoard [ 8 ] [ 7 ] ) ;

287 i f ( tModel . noRows > 8) {288 System . out . p r i n t l n (n . c h i l d r e n .

get ( i ) . nodeBoard [ 0 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i ) . nodeBoard[ 1 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 2 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 3 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 4 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 5 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 6 ] [ 8 ] + ” ”+n .c h i l d r e n . get ( i ) . nodeBoard[ 7 ] [ 8 ] + ” ”+n . c h i l d r e n . get ( i) . nodeBoard [ 8 ] [ 8 ] ) ;

289290 }291 }292 }293 }294 }295 }296 System . out . p r i n t l n ( ) ;297 }298 }299300 // udsk r i v e r in fo rmat ion f o r en enke l t node301 pub l i c void printNode (Node n) {302 i f ( tModel . noCols == 3)303 printNode3x (n) ;304 e l s e305 i f ( tModel . noCols == 4)306 printNode4x (n) ;307 e l s e308 i f ( tModel . noCols == 5)309 printNode5x (n) ;310 e l s e311 i f ( tModel . noCols == 6)312 printNode6x (n) ;313 e l s e314 i f ( tModel . noCols == 7)315 printNode7x (n) ;316 e l s e317 i f ( tModel . noCols == 8)318 printNode8x (n) ;319 e l s e320 i f ( tModel . noCols == 9)321 printNode9x (n) ;322323 }324325 // f o r braet med 3 ko loner

218 Bilag A

326 pub l i c void printNode3x (Node n) {327 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”

Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

328 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] ) ;

329 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] ) ;

330 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] ) ;

331 i f ( tModel . noRows > 3) {332 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] ) ;333 i f ( tModel . noRows > 4) {334 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] ) ;335 i f ( tModel . noRows > 5) {336 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] ) ;337 i f ( tModel . noRows > 6) {338 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] ) ;339 i f ( tModel . noRows > 7) {340 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] ) ;

341 i f ( tModel . noRows > 8) {342 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] ) ;

343344345 }346 }347 }348 }349 }350 }351 System . out . p r i n t l n ( ) ;352 }353354 // f o r braet med 4 ko loner355 pub l i c void printNode4x (Node n) {356 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”

Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

357 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] ) ;

358 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] ) ;

359 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] ) ;

360 i f ( tModel . noRows > 3) {361 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard [ 3 ] [ 3 ] )

A.15 TaijiPrint.java 219

;362 i f ( tModel . noRows > 4) {363 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .nodeBoard [ 3 ] [ 4 ] ) ;

364 i f ( tModel . noRows > 5) {365 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n. nodeBoard [ 3 ] [ 5 ] ) ;

366 i f ( tModel . noRows > 6) {367 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ””+n . nodeBoard [ 3 ] [ 6 ] ) ;

368 i f ( tModel . noRows > 7) {369 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] ) ;

370 i f ( tModel . noRows > 8) {371 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .nodeBoard [ 3 ] [ 8 ] ) ;

372373374 }375 }376 }377 }378 }379 }380 System . out . p r i n t l n ( ) ;381 }382383 // f o r braet med 5 ko loner384 pub l i c void printNode5x (Node n) {385 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”

Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

386 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+n . nodeBoard [ 4 ] [ 0 ] ) ;

387 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+n . nodeBoard [ 4 ] [ 1 ] ) ;

388 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+n . nodeBoard [ 4 ] [ 2 ] ) ;

389 i f ( tModel . noRows > 3) {390 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] ) ;

391 i f ( tModel . noRows > 4) {392 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] ) ;

220 Bilag A

393 i f ( tModel . noRows > 5) {394 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] ) ;

395 i f ( tModel . noRows > 6) {396 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ””+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard

[ 4 ] [ 6 ] ) ;397 i f ( tModel . noRows > 7) {398 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .nodeBoard [ 4 ] [ 7 ] ) ;

399 i f ( tModel . noRows > 8) {400 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard[ 4 ] [ 8 ] ) ;

401402403 }404 }405 }406 }407 }408 }409 System . out . p r i n t l n ( ) ;410 }411412 // f o r braet med 6 ko loner413 pub l i c void printNode6x (Node n) {414 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”

Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

415 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] ) ;

416 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] ) ;

417 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] ) ;

418 i f ( tModel . noRows > 3) {419 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard [ 5 ] [ 3 ] );

420 i f ( tModel . noRows > 4) {421 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .nodeBoard [ 5 ] [ 4 ] ) ;

A.15 TaijiPrint.java 221

422 i f ( tModel . noRows > 5) {423 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+n . nodeBoard [ 5 ] [ 5 ] ) ;

424 i f ( tModel . noRows > 6) {425 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ””+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard

[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] ) ;426 i f ( tModel . noRows > 7) {427 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard[ 5 ] [ 7 ] ) ;

428 i f ( tModel . noRows > 8) {429 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] ) ;

430431432 }433 }434 }435 }436 }437 }438 System . out . p r i n t l n ( ) ;439 }440441 // f o r braet med 7 ko loner442 pub l i c void printNode7x (Node n) {443 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”

Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

444 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] + ” ”+n . nodeBoard[ 6 ] [ 0 ] ) ;

445 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] + ” ”+n . nodeBoard[ 6 ] [ 1 ] ) ;

446 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] + ” ”+n . nodeBoard[ 6 ] [ 2 ] ) ;

447 i f ( tModel . noRows > 3) {448 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard[ 5 ] [ 3 ] + ” ”+n . nodeBoard [ 6 ] [ 3 ] ) ;

222 Bilag A

449 i f ( tModel . noRows > 4) {450 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .nodeBoard [ 5 ] [ 4 ] + ” ”+n . nodeBoard [ 6 ] [ 4 ] ) ;

451 i f ( tModel . noRows > 5) {452 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+n . nodeBoard [ 5 ] [ 5 ] + ” ”+n . nodeBoard [ 6 ] [ 5 ] ) ;

453 i f ( tModel . noRows > 6) {454 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ””+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard

[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] + ” ”+n .nodeBoard [ 6 ] [ 6 ] ) ;

455 i f ( tModel . noRows > 7) {456 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard[ 5 ] [ 7 ] + ” ”+n . nodeBoard [ 6 ] [ 7 ] ) ;

457 i f ( tModel . noRows > 8) {458 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] + ””+n . nodeBoard [ 6 ] [ 8 ] ) ;

459460461 }462 }463 }464 }465 }466 }467 System . out . p r i n t l n ( ) ;468 }469470 // f o r braet med 8 ko loner471 pub l i c void printNode8x (Node n) {472 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”

Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

473 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] + ” ”+n . nodeBoard[ 6 ] [ 0 ] + ” ”+n . nodeBoard [ 7 ] [ 0 ] ) ;

474 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] + ” ”+n . nodeBoard[ 6 ] [ 1 ] + ” ”+n . nodeBoard [ 7 ] [ 1 ] ) ;

475 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+

A.15 TaijiPrint.java 223

n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] + ” ”+n . nodeBoard[ 6 ] [ 2 ] + ” ”+n . nodeBoard [ 7 ] [ 2 ] ) ;

476 i f ( tModel . noRows > 3) {477 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard[ 5 ] [ 3 ] + ” ”+n . nodeBoard [ 6 ] [ 3 ] + ” ”+n . nodeBoard [ 7 ] [ 3 ] );

478 i f ( tModel . noRows > 4) {479 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .nodeBoard [ 5 ] [ 4 ] + ” ”+n . nodeBoard [ 6 ] [ 4 ] + ” ”+n .nodeBoard [ 7 ] [ 4 ] ) ;

480 i f ( tModel . noRows > 5) {481 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+n . nodeBoard [ 5 ] [ 5 ] + ” ”+n . nodeBoard [ 6 ] [ 5 ] + ””+n . nodeBoard [ 7 ] [ 5 ] ) ;

482 i f ( tModel . noRows > 6) {483 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ””+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard

[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] + ” ”+n .nodeBoard [ 6 ] [ 6 ] + ” ”+n . nodeBoard [ 7 ] [ 6 ] ) ;

484 i f ( tModel . noRows > 7) {485 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard[ 5 ] [ 7 ] + ” ”+n . nodeBoard [ 6 ] [ 7 ] + ” ”+n .nodeBoard [ 7 ] [ 7 ] ) ;

486 i f ( tModel . noRows > 8) {487 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] + ””+n . nodeBoard [ 6 ] [ 8 ] + ” ”+n .nodeBoard [ 7 ] [ 8 ] ) ;

488489490 }491 }492 }493 }494 }495 }496 System . out . p r i n t l n ( ) ;497 }498499 // f o r braet med 9 ko loner500 pub l i c void printNode9x (Node n) {

224 Bilag A

501 System . out . p r i n t l n (” tPr in t PrintNode ”+n+” Depth : ”+n . d+”Score ”+n . a+” par ”+n . par+” w ”+n . wc+”,”+n . wr+” b ”+n .bc+”,”+n . br+” c h i l d r e n : ”+n . c h i l d r e n ) ;

502 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 0 ] + ” ”+n . nodeBoard[ 1 ] [ 0 ] + ” ”+n . nodeBoard [ 2 ] [ 0 ] + ” ”+n . nodeBoard [ 3 ] [ 0 ] + ” ”+n . nodeBoard [ 4 ] [ 0 ] + ” ”+n . nodeBoard [ 5 ] [ 0 ] + ” ”+n . nodeBoard[ 6 ] [ 0 ] + ” ”+n . nodeBoard [ 7 ] [ 0 ] + ” ”+n . nodeBoard [ 8 ] [ 0 ] ) ;

503 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 1 ] + ” ”+n . nodeBoard[ 1 ] [ 1 ] + ” ”+n . nodeBoard [ 2 ] [ 1 ] + ” ”+n . nodeBoard [ 3 ] [ 1 ] + ” ”+n . nodeBoard [ 4 ] [ 1 ] + ” ”+n . nodeBoard [ 5 ] [ 1 ] + ” ”+n . nodeBoard[ 6 ] [ 1 ] + ” ”+n . nodeBoard [ 7 ] [ 1 ] + ” ”+n . nodeBoard [ 8 ] [ 1 ] ) ;

504 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 2 ] + ” ”+n . nodeBoard[ 1 ] [ 2 ] + ” ”+n . nodeBoard [ 2 ] [ 2 ] + ” ”+n . nodeBoard [ 3 ] [ 2 ] + ” ”+n . nodeBoard [ 4 ] [ 2 ] + ” ”+n . nodeBoard [ 5 ] [ 2 ] + ” ”+n . nodeBoard[ 6 ] [ 2 ] + ” ”+n . nodeBoard [ 7 ] [ 2 ] + ” ”+n . nodeBoard [ 8 ] [ 2 ] ) ;

505 i f ( tModel . noRows > 3) {506 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 3 ] + ” ”+n . nodeBoard

[ 1 ] [ 3 ] + ” ”+n . nodeBoard [ 2 ] [ 3 ] + ” ”+n . nodeBoard[ 3 ] [ 3 ] + ” ”+n . nodeBoard [ 4 ] [ 3 ] + ” ”+n . nodeBoard[ 5 ] [ 3 ] + ” ”+n . nodeBoard [ 6 ] [ 3 ] + ” ”+n . nodeBoard[ 7 ] [ 3 ] + ” ”+n . nodeBoard [ 8 ] [ 3 ] ) ;

507 i f ( tModel . noRows > 4) {508 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 4 ] + ” ”+n .

nodeBoard [ 1 ] [ 4 ] + ” ”+n . nodeBoard [ 2 ] [ 4 ] + ” ”+n .nodeBoard [ 3 ] [ 4 ] + ” ”+n . nodeBoard [ 4 ] [ 4 ] + ” ”+n .nodeBoard [ 5 ] [ 4 ] + ” ”+n . nodeBoard [ 6 ] [ 4 ] + ” ”+n .nodeBoard [ 7 ] [ 4 ] + ” ”+n . nodeBoard [ 8 ] [ 4 ] ) ;

509 i f ( tModel . noRows > 5) {510 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 5 ] + ” ”+n .

nodeBoard [ 1 ] [ 5 ] + ” ”+n . nodeBoard [ 2 ] [ 5 ] + ” ”+n. nodeBoard [ 3 ] [ 5 ] + ” ”+n . nodeBoard [ 4 ] [ 5 ] + ” ”+n . nodeBoard [ 5 ] [ 5 ] + ” ”+n . nodeBoard [ 6 ] [ 5 ] + ””+n . nodeBoard [ 7 ] [ 5 ] + ” ”+n . nodeBoard [ 8 ] [ 5 ] ) ;

511 i f ( tModel . noRows > 6) {512 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 6 ] + ” ”+n .

nodeBoard [ 1 ] [ 6 ] + ” ”+n . nodeBoard [ 2 ] [ 6 ] + ””+n . nodeBoard [ 3 ] [ 6 ] + ” ”+n . nodeBoard

[ 4 ] [ 6 ] + ” ”+n . nodeBoard [ 5 ] [ 6 ] + ” ”+n .nodeBoard [ 6 ] [ 6 ] + ” ”+n . nodeBoard [ 7 ] [ 6 ] + ””+n . nodeBoard [ 8 ] [ 6 ] ) ;

513 i f ( tModel . noRows > 7) {514 System . out . p r i n t l n (n . nodeBoard [ 0 ] [ 7 ] + ”

”+n . nodeBoard [ 1 ] [ 7 ] + ” ”+n . nodeBoard[ 2 ] [ 7 ] + ” ”+n . nodeBoard [ 3 ] [ 7 ] + ” ”+n .nodeBoard [ 4 ] [ 7 ] + ” ”+n . nodeBoard[ 5 ] [ 7 ] + ” ”+n . nodeBoard [ 6 ] [ 7 ] + ” ”+n .nodeBoard [ 7 ] [ 7 ] + ” ”+n . nodeBoard[ 8 ] [ 7 ] ) ;

515 i f ( tModel . noRows > 8) {516 System . out . p r i n t l n (n . nodeBoard

[ 0 ] [ 8 ] + ” ”+n . nodeBoard [ 1 ] [ 8 ] + ””+n . nodeBoard [ 2 ] [ 8 ] + ” ”+n .nodeBoard [ 3 ] [ 8 ] + ” ”+n . nodeBoard[ 4 ] [ 8 ] + ” ”+n . nodeBoard [ 5 ] [ 8 ] + ””+n . nodeBoard [ 6 ] [ 8 ] + ” ”+n .

A.16 TaijiSettings.java 225

nodeBoard [ 7 ] [ 8 ] + ” ”+n . nodeBoard[ 8 ] [ 8 ] ) ;

517518519 }520 }521 }522 }523 }524 }525 System . out . p r i n t l n ( ) ;526 }527 }

A.16 TaijiSettings.java

1 import java . awt . event . ∗ ;2 import javax . swing . ∗ ;3 import java . awt . ∗ ;45 pub l i c c l a s s T a i j i S e t t i n g s extends JDialog {6 // Se lve d i a l o g e n s panel .7 p r i v a t e JPanel mainPanel = new JPanel ( ) ;89 // Radiobuttons t i l at vae lge AI og andre s e t t i n g s .

10 p r i v a t e JRadioButton oneButton = new JRadioButton (” Player VSPlayer ”) ;

11 p r i v a t e JRadioButton twoButton = new JRadioButton (” Player VSLocalArea ”) ;

12 p r i v a t e JRadioButton threeButton = new JRadioButton (” Player VSAlphaBeta ”) ;

13 p r i v a t e JRadioButton fourButton = new JRadioButton (” Player VSGrowth ”) ;

14 p r i v a t e JRadioButton f iveButton = new JRadioButton (” LocalAreaVS Player ”) ;

15 p r i v a t e JRadioButton s ixButton = new JRadioButton (” AlphaBeta VSPlayer ”) ;

16 p r i v a t e JRadioButton sevenButton = new JRadioButton (” Growth VSPlayer ”) ;

17 p r i v a t e ButtonGroup group = new ButtonGroup ( ) ;1819 //To knapper som godkende e l l e r a f v i s e r det anta l b locks som er

va l g t .20 p r i v a t e JButton okButton = new JButton (”Ok”) ;21 p r i v a t e JButton cancelButton = new JButton (” Cancel ”) ;2223 p r i v a t e Taij iFrame tFrame ;2425 // Constructor .26 //Modtager en AtaxxFrame som argument .27 pub l i c T a i j i S e t t i n g s ( Taij iFrame frame )28 {29 super ( frame , ” T a i j i s e t t i n g s ” , t rue ) ;

226 Bilag A

3031 tFrame = frame ;3233 JLabel ques t i on = new JLabel (” Sh a l l we play a game?”) ;34 JLabel f i r s t F i l l e r = new JLabel ( ) ;35 JLabel s e c o n d F i l l e r = new JLabel ( ) ;36 JLabel t h i r d F i l l e r = new JLabel ( ) ;37 JLabel f o u r t h F i l l e r = new JLabel ( ) ;38 JLabel f i f t h F i l l e r = new JLabel ( ) ;39 JLabel s i x t h F i l l e r = new JLabel ( ) ;4041 t h i s . getContentPane ( ) . setLayout (new BorderLayout ( ) ) ;42 t h i s . getContentPane ( ) . add ( mainPanel , ” Center ”) ;4344 mainPanel . setLayout (new GridLayout (8 , 2 , 10 , 0 ) ) ;45 mainPanel . add ( ques t i on ) ;46 mainPanel . add ( oneButton ) ;47 mainPanel . add ( f i r s t F i l l e r ) ;48 mainPanel . add ( twoButton ) ;49 mainPanel . add ( s e c o n d F i l l e r ) ;50 mainPanel . add ( threeButton ) ;51 mainPanel . add ( t h i r d F i l l e r ) ;52 mainPanel . add ( fourButton ) ;53 mainPanel . add ( f o u r t h F i l l e r ) ;54 mainPanel . add ( f iveButton ) ;55 mainPanel . add ( f i f t h F i l l e r ) ;56 mainPanel . add ( s ixButton ) ;57 mainPanel . add ( s i x t h F i l l e r ) ;58 mainPanel . add ( sevenButton ) ;59 mainPanel . add ( okButton ) ;60 mainPanel . add ( cancelButton ) ;6162 group . add ( oneButton ) ;63 group . add ( twoButton ) ;64 group . add ( threeButton ) ;65 group . add ( fourButton ) ;66 group . add ( f iveButton ) ;67 group . add ( s ixButton ) ;68 group . add ( sevenButton ) ;69 oneButton . setActionCommand (”1”) ;70 twoButton . setActionCommand (”2”) ;71 threeButton . setActionCommand (”3”) ;72 fourButton . setActionCommand (”4”) ;73 f iveButton . setActionCommand (”5”) ;74 s ixButton . setActionCommand (”6”) ;75 sevenButton . setActionCommand (”7”) ;76 oneButton . s e t S e l e c t e d ( t rue ) ;77 twoButton . s e t S e l e c t e d ( f a l s e ) ;78 threeButton . s e t S e l e c t e d ( f a l s e ) ;79 fourButton . s e t S e l e c t e d ( f a l s e ) ;80 f iveButton . s e t S e l e c t e d ( f a l s e ) ;81 s ixButton . s e t S e l e c t e d ( f a l s e ) ;82 sevenButton . s e t S e l e c t e d ( f a l s e ) ;8384 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 TaijiSettings.java 227

85 okButton . addAct ionLis tener ( BLis ) ;86 cance lButton . addAct ionLis tener ( BLis ) ;8788 t h i s . pack ( ) ;89 }9091 //Metode der goer d ia l ogen s y n l i g .92 pub l i c void showIt ( )93 {94 s e t V i s i b l e ( t rue ) ;95 }9697 // L i s t ener−k l a s s en t i l d i a l ogen . Implementerer i n t e r f a c e t

Act i onL i s t ene r .98 // Giver enten et sae t b locks v ide r e t i l r e s e t i AtaxxModel ,

e l l e r gaar ud a f d ia l ogen uden at s t a r t e et nyt s p i l .99 c l a s s S e t t i n g s L i s t e n e r implements Act i onL i s t ene r

100 {101 //Metode der r e a g e r e r paa et ActionEvent . Ved ok gaar den

v ide r e t i l at s t a r t e et nyt s p i l , ved e thve r t andetevent lukkes d ia l ogen .

102 //Modtager et ActionEvent som argument .103 pub l i c void act ionPerformed ( ActionEvent evt )104 {105 i f ( evt . getActionCommand ( ) . equa l s (”Ok”) )106 {107 i n t s e t = I n t e g e r . pa r s e In t ( group . g e t S e l e c t i o n ( )

. getActionCommand ( ) ) ;108 System . out . p r i n t l n (” Se t t i ng ”+s e t ) ;109 i f ( s e t == 1) { // Player VS Player110 tFrame . tModel . s e t S t a r t e r (1 ) ;111 tFrame . tModel . setWhitePlayer (0 ) ;112 tFrame . tModel . s e tB lackPlayer (0 ) ;113 }114 i f ( s e t == 2) { // Player VS LocalArea115 tFrame . tModel . s e t S t a r t e r (1 ) ;116 tFrame . tModel . setWhitePlayer (0 ) ;117 tFrame . tModel . s e tB lackPlayer (6 ) ;118 }119 i f ( s e t == 3) { // Player VS AlphaBeta120 tFrame . tModel . s e t S t a r t e r (1 ) ;121 tFrame . tModel . setWhitePlayer (0 ) ;122 tFrame . tModel . s e tB lackPlayer (2 ) ;123 }124 i f ( s e t == 4) { // Player VS Growth125 tFrame . tModel . s e t S t a r t e r (1 ) ;126 tFrame . tModel . setWhitePlayer (0 ) ;127 tFrame . tModel . s e tB lackPlayer (4 ) ;128 }129 i f ( s e t == 5) { // LocalAera VS Player130 tFrame . tModel . s e t S t a r t e r (1 ) ;131 tFrame . tModel . setWhitePlayer (6 ) ;132 tFrame . tModel . s e tB lackPlayer (0 ) ;133 }134 i f ( s e t == 6) { // AlphaBeta VS Player

228 Bilag A

135 tFrame . tModel . s e t S t a r t e r (1 ) ;136 tFrame . tModel . setWhitePlayer (2 ) ;137 tFrame . tModel . s e tB lackPlayer (0 ) ;138 }139 i f ( s e t == 7) { // Growth VS Player140 tFrame . tModel . s e t S t a r t e r (1 ) ;141 tFrame . tModel . setWhitePlayer (4 ) ;142 tFrame . tModel . s e tB lackPlayer (0 ) ;143 }144 tFrame . tModel . r e s e t ( ) ;145 tFrame . r e p a i n t A l l ( ) ;146 s e t V i s i b l e ( f a l s e ) ;147 }148 e l s e149 {150 s e t V i s i b l e ( f a l s e ) ;151 }152 }153 }154 }

A.17 Tree.java

1 import java . u t i l . ArrayList ;2 pub l i c c l a s s Tree { // denne k l a s s e er kun anvendt i Minimax AI ’ en3 pub l i c Node Root ;4 pub l i c Node Cur ; // cur rent node5 pub l i c ArrayList<Node> evenGen ;6 pub l i c ArrayList<Node> oddGen ;7 pub l i c ArrayList<Node> Leaves ;8 pub l i c i n t curLeaves ; // Current number o f l e a v e s9 pub l i c i n t to ta lLeave s ; //Temperary number o f l e a v e s . curLeaves

+newly added l e a v e s .10 pub l i c i n t curMin ;11 pub l i c i n t curMax ;121314 pub l i c Tree ( ) {15 Root = new Node ( ) ;16 Cur = new Node ( ) ;17 Leaves = new ArrayList<Node>() ;18 evenGen = new ArrayList<Node>() ;19 oddGen = new ArrayList<Node>() ;2021 }2223 // s a e t t e r roden24 pub l i c void setRoot (Node n) {25 Root = n ;26 }27 // s a e t t e r cur r ent node28 pub l i c void setCur (Node n) {29 Cur = n ;

A.17 Tree.java 229

30 }3132 // t i l f o e j e r e t blad33 pub l i c void addLeave (Node n) {34 Leaves . add (n) ;35 }3637 pub l i c void addMin (Node n) {38 curMin++;39 }404142 pub l i c void addMax(Node n) {43 curMax++;44 }4546 pub l i c void resetMin ( ) {47 curMin=0;48 }4950 pub l i c void resetMax ( ) {51 curMax=0;52 }5354 pub l i c void addLeaveT (Node n) {55 to ta lLeave s++;56 }5758 pub l i c void removeLeave ( i n t l ) {59 Leaves . remove ( l ) ;60 }6162 pub l i c void removeLeaveT ( i n t l ) {63 tota lLeaves −−;64 }6566 pub l i c void removeLeaveC ( i n t l ) {67 curLeaves−−;68 tota lLeaves −−;69 }707172 pub l i c i n t getCurLeaves ( ) {73 re turn ( curLeaves ) ;74 }7576 }

230

Bilag B

Kildeliste

B.1 Hjemmesider:

Taiji beskrivelse pa boardgamegeek.comhttp://www.boardgamegeek.com/boardgame/31926Sidst besøgt: 1/10-09

Taiji anmeldelse pa ogrecave.comhttp://ogrecave.com/reviews/taiji.shtmlSidst besøgt: 1/10-09

Opfriskning af Javahttp://javabog.dk/Sidst besøgt: 1/10-09

B.2 Bøger:

”Artificial Inteligence - A Moderne Approach - Second Edition”af Stuart J. Russel og Peter Norvig

232 Bilag B

”Introduction to Algorithms - Second Edition”af Thmos H. Cormen, Charles E. Leiserson, Ronald L. Rivest og Clifford Stein

233

234