-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathStandardReversiScore.java
More file actions
107 lines (100 loc) · 5.34 KB
/
StandardReversiScore.java
File metadata and controls
107 lines (100 loc) · 5.34 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
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
public class StandardReversiScore implements Function<ReversiBoard, Integer> {
// 序盤〜中盤の手の評価を行う関数
private static final List<Pair<List<Boolean>, Integer> > CORNERS_SCORE = Collections.unmodifiableList(Arrays.asList(
// 角,角の隣,角の隣の隣 の順番で, 自石が置かれていれば true, o.w. false.
// 角が取れていれば100点, 角を取れずにその隣に自石が置かれていると-50点
Pair.of(Arrays.asList(true, true, true), 100),
Pair.of(Arrays.asList(true, true, false), 100),
Pair.of(Arrays.asList(true, false, true), 100),
Pair.of(Arrays.asList(true, false, false), 100),
Pair.of(Arrays.asList(false, false, true), 10),
Pair.of(Arrays.asList(false, false, false), 0),
Pair.of(Arrays.asList(false, true, true), -50),
Pair.of(Arrays.asList(false, true, false), -50)
));
private final int k1;
private final int k2;
public StandardReversiScore(int k1, int k2) {
this.k1 = k1;
this.k2 = k2;
}
@Override
public Integer apply(ReversiBoard board) {
final int iMin = board.getHeightMin();
final int iMax = board.getHeightMax();
final int jMin = board.getWidthMin();
final int jMax = board.getWidthMax();
final Player.ID selfPlayer = board.nextTurn();
int selfMovableCount = 0;
for(int i = iMin; i <= iMax; ++i) {
for(int j = jMin; j <= jMax; ++j) {
if(board.isAvailable(selfPlayer, j, i)) ++selfMovableCount;
}
}
final Player.ID enemyPlayer = board.opposite();
int enemyMovableCount = 0;
for(int i = iMin; i <= iMax; ++i) {
for(int j = jMin; j <= jMax; ++j) {
if(board.isAvailable(enemyPlayer, j, i)) ++enemyMovableCount;
}
}
int ansCornerScore;
if(jMax - jMin >= 2 && iMax - iMin >= 2) {
int [] cornerScores = new int[2];
Player.ID[] players = new Player.ID[] { selfPlayer, enemyPlayer };
for(int i = 0; i < 2; ++i) {
Player.ID player = players[i];
Boolean[][] corners = new Boolean[][]{
bits(board, player, Pair.of(jMin + 0, iMin + 0), Pair.of(jMin + 1, iMin + 0), Pair.of(jMin + 2, iMin + 0)),
bits(board, player, Pair.of(jMin + 0, iMin + 0), Pair.of(jMin + 0, iMin + 1), Pair.of(jMin + 0, iMin + 2)),
bits(board, player, Pair.of(jMin + 0, iMin + 0), Pair.of(jMin + 1, iMin + 1), Pair.of(jMin + 2, iMin + 2)),
bits(board, player, Pair.of(jMax - 0, iMin + 0), Pair.of(jMax - 1, iMin + 0), Pair.of(jMax - 2, iMin + 0)),
bits(board, player, Pair.of(jMax - 0, iMin + 0), Pair.of(jMax - 0, iMin + 1), Pair.of(jMax - 0, iMin + 2)),
bits(board, player, Pair.of(jMax - 0, iMin + 0), Pair.of(jMax - 1, iMin + 1), Pair.of(jMax - 2, iMin + 2)),
bits(board, player, Pair.of(jMin + 0, iMax - 0), Pair.of(jMin + 1, iMax - 0), Pair.of(jMin + 2, iMax - 0)),
bits(board, player, Pair.of(jMin + 0, iMax - 0), Pair.of(jMin + 0, iMax - 1), Pair.of(jMin + 0, iMax - 2)),
bits(board, player, Pair.of(jMin + 0, iMax - 0), Pair.of(jMin + 1, iMax - 1), Pair.of(jMin + 2, iMax - 2)),
bits(board, player, Pair.of(jMax - 0, iMax - 0), Pair.of(jMax - 1, iMax - 0), Pair.of(jMax - 2, iMax - 0)),
bits(board, player, Pair.of(jMax - 0, iMax - 0), Pair.of(jMax - 0, iMax - 1), Pair.of(jMax - 0, iMax - 2)),
bits(board, player, Pair.of(jMax - 0, iMax - 0), Pair.of(jMax - 1, iMax - 1), Pair.of(jMax - 2, iMax - 2))
};
int sum = 0;
for (Boolean[] corner : corners) {
sum += cornerScore(corner);
}
cornerScores[i] = sum;
}
ansCornerScore = cornerScores[0] - cornerScores[1];
}
else {
System.err.println("WARNING: Corner score was not calculated");
ansCornerScore = 0;
}
return k1 * (selfMovableCount - enemyMovableCount) + k2 * ansCornerScore;
}
private Boolean[] bits(ReversiBoard board, Player.ID player, Pair<Integer, Integer>... positions) {
ReversiBoard.State playerState = board.playerState(player);
Boolean[] bits = new Boolean[positions.length];
for(int i = 0; i < positions.length; ++i) {
Pair<Integer, Integer> position = positions[i];
ReversiBoard.State state = board.get(position.getKey(), position.getValue());
if(playerState.equals(state)) bits[i] = true;
else bits[i] = false;
}
return bits;
}
private int cornerScore(Boolean[] corner) {
List<Boolean> cornerList = Arrays.asList(corner);
for(Pair<List<Boolean>, Integer> cornerScore : CORNERS_SCORE) {
if(cornerScore.getKey().equals(cornerList)) {
return cornerScore.getValue();
}
}
System.err.println("WARNING: Unexpected pattern of corner");
return 0;
}
}