Skip to content

Commit f918987

Browse files
MarioteceP
Mario
authored andcommitted
- added alphaBetaPruning algorithms to get better moves
- added deepcopy (with byte-streams) to get different object with same state
1 parent ef2246b commit f918987

10 files changed

+463
-56
lines changed

TicTacToe - Computer Enemy.iml

+12
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,17 @@
77
</content>
88
<orderEntry type="inheritedJdk" />
99
<orderEntry type="sourceFolder" forTests="false" />
10+
<orderEntry type="module-library">
11+
<library name="JUnit5.2">
12+
<CLASSES>
13+
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.6.0/junit-jupiter-api-5.6.0.jar!/" />
14+
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.1.0/apiguardian-api-1.1.0.jar!/" />
15+
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar!/" />
16+
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.6.0/junit-platform-commons-1.6.0.jar!/" />
17+
</CLASSES>
18+
<JAVADOC />
19+
<SOURCES />
20+
</library>
21+
</orderEntry>
1022
</component>
1123
</module>

src/algs/AlphaBetaPruning.java

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
package algs;
2+
3+
import feld.Feld;
4+
import spielbrett.Spielbrett;
5+
import spielbrett.SpielbrettController;
6+
7+
import java.util.ArrayList;
8+
9+
public class AlphaBetaPruning {
10+
11+
private static double maxDepth;
12+
private static Feld besterZug;
13+
14+
private AlphaBetaPruning() {
15+
}
16+
17+
public static Feld run(SpielbrettController spielbrettController,char player, double maxDepth) {
18+
if (maxDepth < 1) {
19+
throw new IllegalArgumentException("Max depth must be greater than 0.");
20+
}
21+
22+
AlphaBetaPruning.besterZug = new Feld(-1,-1);
23+
AlphaBetaPruning.maxDepth = maxDepth;
24+
alphaBetaPruning(spielbrettController, player, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0);
25+
return besterZug;
26+
}
27+
28+
private static int alphaBetaPruning(SpielbrettController spielbrettController, char player, double alpha, double beta, int currentDepth) {
29+
30+
//Methode geht nicht weiter, wegen spielVorbei oder currentDepth++ == max
31+
32+
if (currentDepth++ == maxDepth || spielVorbei(spielbrettController.getSpielbrett())) {
33+
return score(spielbrettController.getSpielbrett(), player, currentDepth);
34+
}
35+
36+
if (spielbrettController.getSpielerAmZug() == 'O')
37+
return getMax(spielbrettController, player, alpha, beta, currentDepth);
38+
else // == 'X'
39+
return getMin(spielbrettController, player, alpha, beta, currentDepth);
40+
}
41+
42+
private static int zugZuInt(Feld zug) {
43+
if (zug.getSpalte() == 0 && zug.getZeile() == 0) {
44+
return 0;
45+
46+
} else if (zug.getSpalte() == 0 && zug.getZeile() == 1) {
47+
return 1;
48+
49+
} else if (zug.getSpalte() == 0 && zug.getZeile() == 2) {
50+
return 2;
51+
52+
} else if (zug.getSpalte() == 1 && zug.getZeile() == 0) {
53+
return 3;
54+
55+
} else if (zug.getSpalte() == 1 && zug.getZeile() == 1) {
56+
return 4;
57+
58+
} else if (zug.getSpalte() == 1 && zug.getZeile() == 2) {
59+
return 5;
60+
61+
} else if (zug.getSpalte() == 2 && zug.getZeile() == 0) {
62+
return 6;
63+
} else if (zug.getSpalte() == 2 && zug.getZeile() == 1) {
64+
return 7;
65+
} else if (zug.getSpalte() == 2 && zug.getZeile() == 2) {
66+
return 8;
67+
68+
}
69+
70+
return -1;
71+
}
72+
73+
public static int getMax(SpielbrettController spielbrettController, char player, double alpha, double beta, int currentDepth) {
74+
75+
for (Feld zug : freieFelder(spielbrettController.getSpielbrett())) {
76+
77+
78+
SpielbrettController modSpielbrettController = new SpielbrettController();
79+
modSpielbrettController.setSpielbrett(spielbrettController.getSpielbrett().deepCopy());
80+
81+
modSpielbrettController.zugSetzen(zug, player);
82+
83+
int score = alphaBetaPruning(modSpielbrettController, player, alpha, beta, currentDepth+1);
84+
85+
if (score > alpha) {
86+
alpha = score;
87+
besterZug = zug;
88+
}
89+
90+
if (alpha >= beta) {
91+
break;
92+
}
93+
}
94+
95+
if(besterZug.getSpalte() != -1 && besterZug.getZeile() != -1){
96+
spielbrettController.zugSetzen(besterZug, player);
97+
}
98+
99+
return (int) alpha;
100+
101+
}
102+
103+
public static int getMin(SpielbrettController spielbrettController, char player, double alpha, double beta, int currentDepth) {
104+
105+
for (Feld zug : freieFelder(spielbrettController.getSpielbrett())) {
106+
107+
//Dummy
108+
SpielbrettController modSpielbrettController = new SpielbrettController();
109+
modSpielbrettController.setSpielbrett(spielbrettController.getSpielbrett().deepCopy());
110+
111+
modSpielbrettController.zugSetzen(zug, player);
112+
113+
int score = alphaBetaPruning(modSpielbrettController, player, alpha, beta, currentDepth+1);
114+
115+
if (score < beta) {
116+
beta = score;
117+
besterZug = zug;
118+
}
119+
120+
if (alpha >= beta) {
121+
break;
122+
}
123+
}
124+
125+
if(besterZug.getSpalte() != -1 && besterZug.getZeile() != -1){
126+
spielbrettController.zugSetzen(besterZug, player);
127+
}
128+
129+
return (int) beta;
130+
}
131+
132+
public static boolean spielVorbei(Spielbrett spielbrett) {
133+
for (int spalte = 0; spalte < 3; spalte++) {
134+
for (int zeile = 0; zeile < 3; zeile++) {
135+
if (spielbrett.getFeld(spalte, zeile).getSign() == ' ') {
136+
return false;
137+
}
138+
}
139+
}
140+
return true;
141+
}
142+
143+
private static int score(Spielbrett spielbrett, char sign, int currentDepth) {
144+
int rueckgabe;
145+
146+
if (sign == 'O') {
147+
rueckgabe = 10 - currentDepth;
148+
} else {
149+
rueckgabe = -10 + currentDepth;
150+
}
151+
152+
153+
for (int c = 0; c < spielbrett.getSpielfeld().length; c++) {
154+
155+
//Zeile
156+
if (spielbrett.getFeld(c, 0).getSign() == sign
157+
&& spielbrett.getFeld(c, 1).getSign() == sign
158+
&& spielbrett.getFeld(c, 2).getSign() == sign) {
159+
return rueckgabe;
160+
}
161+
162+
//Spalte
163+
if (spielbrett.getFeld(0, c).getSign() == sign
164+
&& spielbrett.getFeld(1, c).getSign() == sign
165+
&& spielbrett.getFeld(2, c).getSign() == sign) {
166+
return rueckgabe;
167+
}
168+
}
169+
170+
/**
171+
* Diagonal 1
172+
*/
173+
if (spielbrett.getFeld(0, 0).getSign() == sign
174+
&& spielbrett.getFeld(1, 1).getSign() == sign
175+
&& spielbrett.getFeld(2, 2).getSign() == sign) {
176+
return rueckgabe;
177+
}
178+
179+
/**
180+
* Diagonal 2
181+
*/
182+
if (spielbrett.getFeld(0, 2).getSign() == sign
183+
&& spielbrett.getFeld(1, 1).getSign() == sign
184+
&& spielbrett.getFeld(2, 0).getSign() == sign) {
185+
return rueckgabe;
186+
}
187+
188+
return 0;
189+
}
190+
191+
public static ArrayList<Feld> freieFelder(Spielbrett spielbrett) {
192+
ArrayList<Feld> felder = new ArrayList<>();
193+
194+
for (int spalte = 0; spalte < 3; spalte++) {
195+
for (int zeile = 0; zeile < 3; zeile++) {
196+
if (spielbrett.getFeld(spalte, zeile).getSign() == ' ') {
197+
felder.add(spielbrett.getFeld(spalte, zeile));
198+
}
199+
}
200+
}
201+
202+
return felder;
203+
}
204+
205+
}

0 commit comments

Comments
 (0)