-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArtificialInteligence.java
More file actions
126 lines (113 loc) · 3.38 KB
/
Copy pathArtificialInteligence.java
File metadata and controls
126 lines (113 loc) · 3.38 KB
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
import java.util.ArrayList;
import java.util.List;
public class ArtificialInteligence {
//Tested
private CodeRunner runner;
public ArtificialInteligence(CodeRunner runner){
this.runner = runner;
}
public int recommendMove(Board b) {
double record = Double.NEGATIVE_INFINITY;
int best = -1;
for(int direction = 0; direction < 4; direction++){
List<Board> moveOutcomes = allPossibleOutcomesOfMove(b,direction);
double assessment = assessBoard(moveOutcomes);
if (assessment > record && b.canMove(direction)){
best = direction;
record = assessment;
}
}
return best;
}
public int recommendMove(Board b, int movesDeep) {
if(movesDeep <= 1){
return recommendMove(b);
}
double record = Double.NEGATIVE_INFINITY;
int best = (int) (Math.random() * 4);
for(int direction = 0; direction < 4; direction++){
List<Board> moveOutcomes = bestOutcome(allPossibleOutcomesOfMove(b,direction), movesDeep - 1);
double assessment = assessBoard(moveOutcomes);
if (assessment > record && b.canMove(direction)){
best = direction;
record = assessment;
}
}
return best;
}
public List<Board> bestOutcome(Board b, int movesDeep){
return allPossibleOutcomesOfMove(b,recommendMove(b, movesDeep));
}
public List<Board> bestOutcome(List<Board> boards, int movesDeep){
List<Board> toReturn = new ArrayList<Board>();
for (Board b: boards){
toReturn.addAll(bestOutcome(b, movesDeep));
}
return toReturn;
}
//Tested
public List<Board> allPossibleOutcomesOfMove(Board initial, int direction){
Board moved = initial.clone();
moved.moveContents(direction);
List<Board> setOfOutcomes = new ArrayList<>();
for (int x = 0; x < moved.getSize(); x++){
for (int y = 0; y < moved.getSize(); y++){
if (moved.getSpace(x, y) == null){
Board toAdd = moved.clone();
new Tile(runner.TILE_MULTIPLIER,runner.POWER_SPAWN_VALUE,toAdd,x,y);
setOfOutcomes.add(toAdd);
}
}
}
return setOfOutcomes;
}
//assess a set of Boards by averaging the set of boards
public double assessBoard(List<Board> boards){
double sum = 0;
for(Board b : boards){
sum += assessBoard(b);
}
return sum / boards.size();
}
//Assess the value of a single board. Currently just finds the value of a single board.
public double assessBoard(Board board){
return countOpenSpaces(board) + monotonisity(board) / 20;
}
//Counts the number of open spaces in a board, Successfully tested
public int countOpenSpaces(Board board){
int count = 0;
for (int i = 0; i < board.playBoard.length; i++){
for (Tile t : board.playBoard[i]){
if (t == null)
count++;
}
}
return count;
}
public double monotonisity(Board board){
double monotonisityRightLeft = 0;
for (int i = 0; i < board.getSize(); i++){
Tile previousTile = null;
for (Tile t: board.playBoard[i]){
if(t != null){
if (previousTile != null)
monotonisityRightLeft += Math.signum(t.getValue()-previousTile.getValue());
previousTile = t;
}
}
}
double monotonisityUpDown = 0;
for (int j = 0; j < board.getSize(); j++){
Tile previousTile = null;
for (int i = 0; i < board.getSize(); i++){
Tile t = board.getSpace(i, j);
if(t != null){
if (previousTile != null)
monotonisityUpDown += Math.signum(t.getValue()-previousTile.getValue());
previousTile = t;
}
}
}
return Math.abs(monotonisityRightLeft) + Math.abs(monotonisityUpDown);
}
}