22
33import core .actions .AbstractAction ;
44import utilities .ElapsedCpuChessTimer ;
5- import utilities .Utils ;
65
76import java .util .Arrays ;
87import java .util .List ;
98import java .util .Random ;
9+ import java .util .stream .IntStream ;
10+
11+ import static core .CoreConstants .GameResult .*;
1012
1113public abstract class AbstractForwardModel {
1214
@@ -18,10 +20,10 @@ public abstract class AbstractForwardModel {
1820 * @param firstState - initial state.
1921 */
2022 protected void abstractSetup (AbstractGameState firstState ) {
21- firstState .gameStatus = Utils .GameResult .GAME_ONGOING ;
22- firstState .playerResults = new Utils .GameResult [firstState .getNPlayers ()];
23- Arrays .fill (firstState .playerResults , Utils .GameResult .GAME_ONGOING );
24- firstState .gamePhase = AbstractGameState .DefaultGamePhase .Main ;
23+ firstState .gameStatus = CoreConstants .GameResult .GAME_ONGOING ;
24+ firstState .playerResults = new CoreConstants .GameResult [firstState .getNPlayers ()];
25+ Arrays .fill (firstState .playerResults , CoreConstants .GameResult .GAME_ONGOING );
26+ firstState .gamePhase = CoreConstants .DefaultGamePhase .Main ;
2527 firstState .playerTimer = new ElapsedCpuChessTimer [firstState .getNPlayers ()];
2628 for (int i = 0 ; i < firstState .getNPlayers (); i ++) {
2729 firstState .playerTimer [i ] = new ElapsedCpuChessTimer (firstState .gameParameters .thinkingTimeMins ,
@@ -73,12 +75,7 @@ protected void abstractSetup(AbstractGameState firstState) {
7375 */
7476 protected abstract AbstractForwardModel _copy ();
7577
76- /**
77- * Performs any end of game computations, as needed. Not necessary to be implemented in the subclass, but can be.
78- * The last thing to be called in the game loop, after the game is finished.
79- */
80- protected void endGame (AbstractGameState gameState ) {
81- }
78+ protected abstract void endPlayerTurn (AbstractGameState state );
8279
8380 /**
8481 * Current player tried to play an illegal action.
@@ -98,8 +95,8 @@ protected void illegalActionPlayed(AbstractGameState gameState, AbstractAction a
9895 */
9996 protected final void disqualifyOrRandomAction (boolean flag , AbstractGameState gameState ) {
10097 if (flag ) {
101- gameState .setPlayerResult (Utils .GameResult .DISQUALIFY , gameState .getCurrentPlayer ());
102- gameState . turnOrder . endPlayerTurn (gameState );
98+ gameState .setPlayerResult (CoreConstants .GameResult .DISQUALIFY , gameState .getCurrentPlayer ());
99+ endPlayerTurn (gameState );
103100 } else {
104101 List <AbstractAction > possibleActions = computeAvailableActions (gameState );
105102 int randomAction = new Random (gameState .getGameParameters ().getRandomSeed ()).nextInt (possibleActions .size ());
@@ -127,18 +124,20 @@ public final void setup(AbstractGameState gameState) {
127124 */
128125 public final void next (AbstractGameState currentState , AbstractAction action ) {
129126 if (action != null ) {
127+ int player = currentState .getCurrentPlayer ();
128+ currentState .recordAction (action , player );
130129 if (currentState .isActionInProgress ()) {
131130 // we register the action with the currently active ActionSequence
132131 currentState .currentActionInProgress ().registerActionTaken (currentState , action );
133132 }
134133 _next (currentState , action );
135- currentState .recordAction (action );
136134 } else {
137135 if (currentState .coreGameParameters .verbose ) {
138136 System .out .println ("Invalid action." );
139137 }
140138 illegalActionPlayed (currentState , action );
141139 }
140+ currentState .advanceGameTick ();
142141 }
143142
144143 /**
@@ -155,6 +154,31 @@ public final List<AbstractAction> computeAvailableActions(AbstractGameState game
155154 return _computeAvailableActions (gameState );
156155 }
157156
157+ /**
158+ * Performs any end of game computations, as needed.
159+ * This should not normally need to be overriden - but can be. For example if a game is purely co-operative
160+ * or has an insta-win situation without the concept of a game score.
161+ * The last thing to be called in the game loop, after the game is finished.
162+ */
163+ protected void endGame (AbstractGameState gs ) {
164+ gs .setGameStatus (CoreConstants .GameResult .GAME_END );
165+ // If we have more than one person in Ordinal position of 1, then this is a draw
166+ boolean drawn = IntStream .range (0 , gs .getNPlayers ()).map (gs ::getOrdinalPosition ).filter (i -> i == 1 ).count () > 1 ;
167+ for (int p = 0 ; p < gs .getNPlayers (); p ++) {
168+ int o = gs .getOrdinalPosition (p );
169+ if (o == 1 && drawn )
170+ gs .setPlayerResult (DRAW , p );
171+ else if (o == 1 )
172+ gs .setPlayerResult (WIN , p );
173+ else
174+ gs .setPlayerResult (LOSE , p );
175+ }
176+ if (gs .getCoreGameParameters ().verbose ) {
177+ System .out .println (Arrays .toString (gs .getPlayerResults ()));
178+ }
179+ }
180+
181+
158182 /**
159183 * Returns a copy of this forward model with a new random seed.
160184 *
0 commit comments