Skip to content

Commit 8c50526

Browse files
committed
Jaipur Skeleton
1 parent 73d6782 commit 8c50526

20 files changed

Lines changed: 1628 additions & 36 deletions

src/main/java/core/AbstractGameState.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import utilities.ElapsedCpuChessTimer;
1515

1616
import java.util.*;
17+
import java.util.function.BiFunction;
18+
import java.util.function.Function;
1719
import java.util.function.Supplier;
1820

1921
import static java.util.stream.Collectors.toList;
@@ -392,7 +394,14 @@ public final Stack<IExtendedSequence> getActionsInProgress() {
392394
* @param playerId
393395
* @return
394396
*/
395-
public double getTiebreak(int playerId) {
397+
public Double getTiebreak(int playerId) {
398+
return getTiebreak(playerId, 1);
399+
}
400+
401+
/**
402+
* @param tier - if multiple tiebreaks available in the game, this parameter can be used to specify what each one does, applied in the order 1,2,3 ...
403+
*/
404+
public Double getTiebreak(int playerId, int tier) {
396405
return 0.0;
397406
}
398407

@@ -406,21 +415,39 @@ public double getTiebreak(int playerId) {
406415
* @param playerId player ID
407416
* @return The ordinal position of the player; 1 is 1st, 2 is 2nd and so on.
408417
*/
409-
public int getOrdinalPosition(int playerId) {
410-
double playerScore = getGameScore(playerId);
418+
public int getOrdinalPosition(int playerId, Function<Integer, Double> scoreFunction, BiFunction<Integer, Integer, Double> tiebreakFunction) {
411419
int ordinal = 1;
420+
double playerScore = scoreFunction.apply(playerId);
412421
for (int i = 0, n = getNPlayers(); i < n; i++) {
413-
double otherScore = getGameScore(i);
422+
double otherScore = scoreFunction.apply(i);
414423
if (otherScore > playerScore)
415424
ordinal++;
416-
else if (otherScore == playerScore) {
417-
if (getTiebreak(i) > getTiebreak(playerId))
425+
else if (otherScore == playerScore && tiebreakFunction != null) {
426+
if (getOrdinalPositionTiebreak(i, tiebreakFunction, 1) > getOrdinalPositionTiebreak(playerId, tiebreakFunction, 1))
418427
ordinal++;
419428
}
420429
}
421430
return ordinal;
422431
}
432+
public int getOrdinalPositionTiebreak(int playerId, BiFunction<Integer, Integer, Double> tiebreakFunction, int tier) {
433+
int ordinal = 1;
434+
Double playerScore = tiebreakFunction.apply(playerId, tier);
435+
if (playerScore == null) return ordinal;
423436

437+
for (int i = 0, n = getNPlayers(); i < n; i++) {
438+
double otherScore = tiebreakFunction.apply(i, tier);
439+
if (otherScore > playerScore)
440+
ordinal++;
441+
else if (otherScore == playerScore) {
442+
if (getOrdinalPositionTiebreak(i, tiebreakFunction, tier+1) > getOrdinalPositionTiebreak(playerId, tiebreakFunction, tier+1))
443+
ordinal++;
444+
}
445+
}
446+
return ordinal;
447+
}
448+
public int getOrdinalPosition(int playerId) {
449+
return getOrdinalPosition(playerId, this::getGameScore, this::getTiebreak);
450+
}
424451

425452
/**
426453
* Provide a list of component IDs which are hidden in partially observable copies of games.

src/main/java/core/Game.java

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import core.actions.DoNothing;
55
import core.interfaces.IPrintable;
66
import core.turnorders.ReactiveTurnOrder;
7-
import evaluation.listeners.GameListener;
87
import evaluation.metrics.Event;
8+
import evaluation.listeners.GameListener;
99
import evaluation.summarisers.TAGNumericStatSummary;
1010
import games.GameType;
1111
import gui.AbstractGUIManager;
@@ -30,8 +30,6 @@
3030
import java.util.Collections;
3131
import java.util.List;
3232
import java.util.concurrent.atomic.AtomicInteger;
33-
34-
import evaluation.metrics.*;
3533
import static utilities.Utils.componentToImage;
3634

3735
public class Game {
@@ -901,8 +899,6 @@ private void terminateVideoRecording() {
901899
}
902900
}
903901

904-
905-
906902
/**
907903
* The recommended way to run a game is via evaluations.Frontend, however that may not work on
908904
* some games for some screen sizes due to the vagaries of Java Swing...
@@ -916,19 +912,16 @@ private void terminateVideoRecording() {
916912
* and then run this class.
917913
*/
918914
public static void main(String[] args) {
919-
String gameType = Utils.getArg(args, "game", "GameTemplate");
915+
String gameType = Utils.getArg(args, "game", "Jaipur");
920916
boolean useGUI = Utils.getArg(args, "gui", true);
921-
int playerCount = Utils.getArg(args, "nPlayers", 2);
922917
int turnPause = Utils.getArg(args, "turnPause", 0);
923918
long seed = Utils.getArg(args, "seed", System.currentTimeMillis());
919+
ActionController ac = new ActionController();
924920

925-
ActionController ac = new ActionController(); //null;
926-
927-
/* Set up players for the game */
928-
ArrayList<AbstractPlayer> players = new ArrayList<>(playerCount);
929-
930-
players.add(new RandomPlayer());
921+
// 1. Set up the players for the game.
922+
ArrayList<AbstractPlayer> players = new ArrayList<>();
931923
// players.add(new RandomPlayer());
924+
players.add(new RandomPlayer());
932925
// players.add(new MCTSPlayer());
933926
// MCTSParams params1 = new MCTSParams();
934927
// players.add(new MCTSPlayer(params1));
@@ -937,14 +930,14 @@ public static void main(String[] args) {
937930
players.add(new HumanGUIPlayer(ac));
938931
// players.add(new HumanConsolePlayer());
939932
// players.add(new FirstActionPlayer());
940-
// players.add(new HumanConsolePlayer());
941933

942-
/* 4. Game parameter configuration. Set to null to ignore and use default parameters */
934+
// 2. Game parameter configuration. Set to null to ignore and use default parameters
943935
String gameParams = null;
944936

945-
/* 5. Run! */
937+
// 3. Run!
946938
runOne(GameType.valueOf(gameType), gameParams, players, seed, false, null, useGUI ? ac : null, turnPause);
947939

940+
// 4. Run several games
948941
// ArrayList<GameType> games = new ArrayList<>(Arrays.asList(GameType.values()));
949942
// games.remove(LoveLetter);
950943
// games.remove(Pandemic);

src/main/java/core/components/Counter.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import java.io.FileReader;
1010
import java.io.IOException;
1111
import java.util.ArrayList;
12+
import java.util.Arrays;
1213
import java.util.List;
14+
import java.util.Objects;
1315

1416
public class Counter extends Component {
1517
protected int[] values;
@@ -57,16 +59,22 @@ public boolean increment(int amount) {
5759
this.valueIdx += amount;
5860
return clamp();
5961
}
62+
public boolean increment() {
63+
return increment(1);
64+
}
6065

61-
/**
62-
* Decrement the value of this counter.
63-
* @param amount - how much to decrease this counter by.
64-
* @return - true if succeeded, false if capped at min
65-
*/
66+
/**
67+
* Decrement the value of this counter.
68+
* @param amount - how much to decrease this counter by.
69+
* @return - true if succeeded, false if capped at min
70+
*/
6671
public boolean decrement(int amount) {
6772
this.valueIdx -= amount;
6873
return clamp();
6974
}
75+
public boolean decrement() {
76+
return decrement(1);
77+
}
7078

7179
private boolean clamp() {
7280
if (this.valueIdx > this.maximum) {
@@ -201,8 +209,24 @@ public void loadCounter(JSONObject counter) {
201209
parseComponent(this, counter);
202210
}
203211

212+
@Override
213+
public boolean equals(Object o) {
214+
if (this == o) return true;
215+
if (!(o instanceof Counter)) return false;
216+
if (!super.equals(o)) return false;
217+
Counter counter = (Counter) o;
218+
return valueIdx == counter.valueIdx && minimum == counter.minimum && maximum == counter.maximum && Arrays.equals(values, counter.values);
219+
}
220+
204221
@Override
205222
public int hashCode() {
206-
return componentID;
223+
int result = Objects.hash(super.hashCode(), valueIdx, minimum, maximum);
224+
result = 31 * result + Arrays.hashCode(values);
225+
return result;
226+
}
227+
228+
@Override
229+
public String toString() {
230+
return "" + getValue();
207231
}
208232
}

src/main/java/games/GameType.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import games.dotsboxes.*;
2020
import games.explodingkittens.*;
2121
import games.explodingkittens.gui.ExplodingKittensGUIManager;
22+
import games.jaipurskeleton.*;
2223
import games.loveletter.*;
2324
import games.loveletter.gui.LoveLetterGUIManager;
2425
import games.pandemic.*;
@@ -165,7 +166,9 @@ public enum GameType {
165166
Arrays.asList(Dice, Abstract),
166167
Collections.singletonList(PushYourLuck),
167168
CantStopGameState.class, CantStopForwardModel.class, CantStopParameters.class, CantStopGUIManager.class
168-
);
169+
),
170+
Jaipur(2,2, null, null,
171+
JaipurGameState.class, JaipurForwardModel.class, JaipurParameters.class, JaipurGUIManager.class);
169172

170173
// Core classes where the game is defined
171174
final Class<? extends AbstractGameState> gameStateClass;

src/main/java/games/coltexpress/ColtExpressGameState.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public double getGameScore(int playerId) {
238238
}
239239

240240
@Override
241-
public double getTiebreak(int playerId) {
241+
public Double getTiebreak(int playerId) {
242242
// we use the number of bullet cards
243243
// in the players own deck and hands
244244
// fewer is better - so we return a negative number
@@ -249,7 +249,7 @@ public double getTiebreak(int playerId) {
249249
for (ColtExpressCard card : playerHandCards.get(playerId).getComponents())
250250
if (card.cardType == ColtExpressCard.CardType.Bullet)
251251
bulletsTaken++;
252-
return -bulletsTaken;
252+
return (double) -bulletsTaken;
253253
}
254254

255255
@Override

0 commit comments

Comments
 (0)