Vervolgens wou ik in vier stappen een AI agent maken die een waardig tegenstander van een menselijke speler zou worden.
Stap 1. 4 op een rij met twee menselijke spelers.
Stap 2. 4 op een rij waarbij de gebruiker tegen een (zeer simpele) AI-agent speelt. De AI-agent weet enkel wat geldige zetten zijn (kies een kolom tussen 0 en 7 en die niet vol is). Als keuze voor de kolom gebruikt ie een randomize-functie.
Stap 3. Deze agent kent de geldige zetten, maar kijkt ook naar de stand van het bord om zijn keuze te maken.
Stap 4. De agent kijkt niet alleen naar geldige stappen en maakt een inschatting wat de beste volgende stap. Deze agent houdt bij zijn inschatting ook rekening met 2 of meer toekomstige stappen van hem en zijn tegenstander.
In deze versie van 4 op een rij speel je als gebruiker tegen een zeer eenvoudige agent. Eigenlijk kiest de agent alleen maar een willekeurige kolom voor zijn zet. Hij is nog net wel zo intelligent dat ie weet dat alleen geldige zetten zijn toegestaan. M.a.w. zetten tussen 0 en 7 (aantal kolommen in het bord) en dat de kolom niet vol mag zijn.
Bord.java beschrijft het bord en de belangrijkste spelregels.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | package javaapplication10; import java.util.Scanner; /** * * @author gerard */ class Board{ byte[][] board = new byte[6][7]; public Board(){ board = new byte[][]{ {0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,}, {0,0,0,0,0,0,0,}, }; } public void undoMove(int column){ for(int i=0;i<=5;++i){ if(board[i][column] != 0) { board[i][column] = 0; break; } } } } public class Bord { private Board b; private Scanner scan; private int nextMoveLocation=-1; private int maxDepth = 9; private static final char[] symbolen = new char[] { 'X', 'O','.' }; private final char[][] velden; private int breedte; private int hoogte; private int gekozenKolom = -1; // laatst gekozen kolom private int grensRij = -1;// hoogste rij (grensrij)bij deze kolom public Bord(int pbreedte, int phoogte) { this.velden = new char[phoogte][pbreedte]; for (int rij = 0; rij < this.velden.length; rij++) { for (int kolom = 0; kolom < this.velden[rij].length; kolom++) { this.velden[rij][kolom] = symbolen[2]; } } breedte = this.velden[0].length; hoogte = this.velden.length; } public String toString() { String BordBeeld = ""; for (int rij = 0; rij < this.hoogte; rij++) { for (int kolom = 0; kolom < this.breedte; kolom++) { BordBeeld = BordBeeld + this.velden[rij][kolom]; } BordBeeld = BordBeeld + "\n"; } return BordBeeld; } public boolean isLegaleZet(int pkolom){ boolean result = true; if ( !(0 <= pkolom && pkolom < breedte)) { System.out.println("Kolom moeten tussen 0 and " + (this.hoogte - 1) + " zijn"); result = false; } return result; } public boolean KolomIsVol(int pkolom) { boolean result = true; int hoogte = 0;// this.velden.length - 1; if (this.velden[hoogte][pkolom] != symbolen[2]) { System.out.println("Deze Kolom is vol."); result = false; } return result; } public boolean BordIsVol() { boolean result = true; int aantalVolleKol = 0; for (int kol = 0;kol <= this.breedte -1; kol++) { if (KolomIsVol(kol)) { aantalVolleKol++; } } if (aantalVolleKol < this.breedte) { result = false; } return result; } //Placing a Move on the board public void DoeZet(int column, int player){ for (int h = this.hoogte -1; h>=0; h--) { if (this.velden[h][column] == '.') {// er is nog ruimte this.gekozenKolom = column; this.grensRij = h; this.velden[this.grensRij][this.gekozenKolom] = symbolen[player]; break; } } } public boolean WinnendeZet() { char sym = this.velden[this.grensRij][this.gekozenKolom]; String reeks = String.format("%c%c%c%c", sym, sym, sym, sym); return bevat(this.horizontaal(), reeks) || bevat(this.vertikaal(), reeks) || bevat(this.slashDiagonaal(), reeks) || bevat(this.backslashDiagonaal(), reeks); } /** * zit er een winnende reeks in de horizontale rij */ private String horizontaal() { return new String(this.velden[this.grensRij]); } /** * zit er een winende reeks en ide verticale rij */ private String vertikaal() { StringBuilder sb = new StringBuilder(this.hoogte); for (int h = 0; h < this.hoogte; h++) { sb.append(this.velden[h][this.gekozenKolom]); } return sb.toString(); } /** * * */ private String slashDiagonaal() { StringBuilder sb = new StringBuilder(this.hoogte); for (int h = 0; h < this.hoogte; h++) { int w = this.gekozenKolom + this.grensRij - h; if (0 <= w && w < this.breedte) { sb.append(this.velden[h][w]); } } return sb.toString(); } /** * */ private String backslashDiagonaal() { StringBuilder sb = new StringBuilder(this.hoogte); for (int h = 0; h < this.hoogte; h++) { int w = this.gekozenKolom - this.grensRij + h; if (0 <= w && w < this.breedte) { sb.append(this.velden[h][w]); } } return sb.toString(); } private boolean bevat(String hooiberg, String naald) { return hooiberg.contains(naald); } } |
spel.java handelt de interactie tussen speler (gebruiker) en agent af.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | package javaapplication10; import java.util.Random; import java.util.Scanner; /** * * @author gerard */ public class Spel { Bord b = new Bord(7,8); int zet; public int GebruikerKiestZet(){ System.out.println("Your move (0-6): "); Scanner scan = new Scanner(System.in); int g_zet = scan.nextInt(); while (!b.isLegaleZet(g_zet) || !b.KolomIsVol(g_zet)){ g_zet = scan.nextInt(); } return g_zet; } public int AgentKiestZet() { int max = 7; // dit moet nog geparametiseerd worden int min =0; Random random = new Random(); int l_zet = random.nextInt(max - min + 1) + min; while (!b.isLegaleZet(l_zet) || !b.KolomIsVol(l_zet)){ l_zet = random.nextInt(max - min + 1) + min; } return l_zet; } public int speel() { System.out.println(b); // remise moet nog worden ingebouwd. while(true){ zet = GebruikerKiestZet(); b.DoeZet(zet, 0); System.out.println(b); if (b.WinnendeZet()) {System.out.println("You Win!");break;} zet = AgentKiestZet(); b.DoeZet(zet, 1); System.out.println(b); if (b.WinnendeZet()) {System.out.println("Agent wins!");break;} } return 1; } /** * @param args the command line arguments */ public static void main(String[] args) { Spel spel = new Spel(); spel.speel(); // ingebouwd moe tworden wie begint agent of gebruiker // Scanner scan = new Scanner(System.in); // System.out.println("Would you like to play first? (yes/no) "); //String answer = scan.next().trim(); // if(answer.equalsIgnoreCase("yes")) GebruikerKiestZet(); // b.displayBoard(); // b.placeMove(3, 1); // b.displayBoard(); } } |