Skip to content

Commit 12cf1f0

Browse files
hopshackleclaude
andcommitted
Heuristics without settings are equal to any other of their class
NullActionHeuristic had no equals, so MCTS parameters read back from JSON did not equal those written (TunableParametersTest). The same for the other heuristics that hold no settings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 5426aa7 commit 12cf1f0

13 files changed

Lines changed: 157 additions & 4 deletions

‎src/main/java/games/poker/metrics/PokerHandHeuristic.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
3737

3838
return (11 - hand.a.rank) / 10.0;
3939
}
40+
41+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
42+
// read back from JSON equals the one written
43+
@Override
44+
public boolean equals(Object obj) {
45+
return obj != null && obj.getClass() == getClass();
46+
}
47+
48+
@Override
49+
public int hashCode() {
50+
return getClass().getName().hashCode();
51+
}
4052
}

‎src/main/java/games/powergrid/PowerGridHeuristic.java‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,15 @@ private static double clamp01(double v) {
169169
return v < 0 ? 0 : (v > 1 ? 1 : v);
170170
}
171171

172-
}
172+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
173+
// read back from JSON equals the one written
174+
@Override
175+
public boolean equals(Object obj) {
176+
return obj != null && obj.getClass() == getClass();
177+
}
178+
179+
@Override
180+
public int hashCode() {
181+
return getClass().getName().hashCode();
182+
}
183+
}

‎src/main/java/games/puertorico/PuertoRicoStateHeuristic.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
2222
}
2323

2424
}
25+
26+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
27+
// read back from JSON equals the one written
28+
@Override
29+
public boolean equals(Object obj) {
30+
return obj != null && obj.getClass() == getClass();
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
return getClass().getName().hashCode();
36+
}
2537
}

‎src/main/java/games/seasaltpaper/heuristics/LeadHeuristic.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
3535
// only return 1 if won
3636
return Utils.clamp((scores[playerId] - max) / params.victoryCondition[gs.getNPlayers() - 2], -1, 1);
3737
}
38+
39+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
40+
// read back from JSON equals the one written
41+
@Override
42+
public boolean equals(Object obj) {
43+
return obj != null && obj.getClass() == getClass();
44+
}
45+
46+
@Override
47+
public int hashCode() {
48+
return getClass().getName().hashCode();
49+
}
3850
}

‎src/main/java/games/seasaltpaper/heuristics/ScoreAndHandHeuristic.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
2525
// only return 1 if won
2626
return Utils.clamp(scoreAndHand/params.victoryCondition[gs.getNPlayers()-2], -1, 0.99);
2727
}
28+
29+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
30+
// read back from JSON equals the one written
31+
@Override
32+
public boolean equals(Object obj) {
33+
return obj != null && obj.getClass() == getClass();
34+
}
35+
36+
@Override
37+
public int hashCode() {
38+
return getClass().getName().hashCode();
39+
}
2840
}

‎src/main/java/games/seasaltpaper/heuristics/ScoreHeuristic.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
2020
// only return 1 if won
2121
return Utils.clamp(gs.getGameScore(playerId)/params.victoryCondition[gs.getNPlayers()-2], -1, 0.99);
2222
}
23+
24+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
25+
// read back from JSON equals the one written
26+
@Override
27+
public boolean equals(Object obj) {
28+
return obj != null && obj.getClass() == getClass();
29+
}
30+
31+
@Override
32+
public int hashCode() {
33+
return getClass().getName().hashCode();
34+
}
2335
}

‎src/main/java/games/spades/SpadesHeuristic.java‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,16 @@ public int suggestBid(SpadesGameState state, int playerId) {
145145

146146
return Math.min(6, Math.max(1, suggestedBid));
147147
}
148-
}
148+
149+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
150+
// read back from JSON equals the one written
151+
@Override
152+
public boolean equals(Object obj) {
153+
return obj != null && obj.getClass() == getClass();
154+
}
155+
156+
@Override
157+
public int hashCode() {
158+
return getClass().getName().hashCode();
159+
}
160+
}

‎src/main/java/games/stratego/StrategoHeuristic.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,15 @@ public double evaluateState(AbstractGameState gs, int playerId) {
5454
return playerScore - oppScore;
5555
}
5656

57+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
58+
// read back from JSON equals the one written
59+
@Override
60+
public boolean equals(Object obj) {
61+
return obj != null && obj.getClass() == getClass();
62+
}
5763

64+
@Override
65+
public int hashCode() {
66+
return getClass().getName().hashCode();
67+
}
5868
}

‎src/main/java/games/virus/VirusHeuristic.java‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
2424
}
2525
return nHealthyOrgans * 1.0 / vgs.playerBodies.get(playerId).organs.size();
2626
}
27-
}
27+
28+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
29+
// read back from JSON equals the one written
30+
@Override
31+
public boolean equals(Object obj) {
32+
return obj != null && obj.getClass() == getClass();
33+
}
34+
35+
@Override
36+
public int hashCode() {
37+
return getClass().getName().hashCode();
38+
}
39+
}

‎src/main/java/players/heuristics/MultiLeaderHeuristic.java‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,16 @@ public double evaluateState(AbstractGameState gs, int playerId) {
1818

1919
return retValue;
2020
}
21-
}
21+
22+
// no settings (any fields are fixed, or worked out from the game): any two are the same heuristic, so that one
23+
// read back from JSON equals the one written
24+
@Override
25+
public boolean equals(Object obj) {
26+
return obj != null && obj.getClass() == getClass();
27+
}
28+
29+
@Override
30+
public int hashCode() {
31+
return getClass().getName().hashCode();
32+
}
33+
}

0 commit comments

Comments
 (0)