@@ -227,6 +227,8 @@ export default class Engine {
227
227
oldPhase : Phase ;
228
228
randomFactions ?: Faction [ ] ;
229
229
version = version ;
230
+ replayVersion : string ;
231
+ replay : boolean ; // be more permissive during replay
230
232
231
233
get expansions ( ) {
232
234
return 0 ;
@@ -266,13 +268,19 @@ export default class Engine {
266
268
// Tells the UI if the new move should be on the same line or not
267
269
newTurn = true ;
268
270
269
- constructor ( moves : string [ ] = [ ] , options : EngineOptions = { } , engineVersion ?: string ) {
271
+ constructor ( moves : string [ ] = [ ] , options : EngineOptions = { } , engineVersion ?: string , replay = false ) {
270
272
this . options = options ;
271
273
if ( engineVersion ) {
272
274
this . version = engineVersion ;
273
275
}
276
+ this . replay = replay ;
277
+ if ( replay ) {
278
+ this . options . noFedCheck = true ;
279
+ this . options . flexibleFederations = true ;
280
+ }
274
281
this . sanitizeOptions ( ) ;
275
282
this . loadMoves ( moves ) ;
283
+ this . options = options ;
276
284
}
277
285
278
286
/** Fix old options passed. To remove when legacy data is no more in database */
@@ -311,12 +319,23 @@ export default class Engine {
311
319
}
312
320
313
321
move ( _move : string , allowIncomplete = true ) {
314
- assert ( this . newTurn , "Cannot execute a move after executing an incomplete move" ) ;
322
+ if ( this . replay ) {
323
+ this . newTurn = true ;
324
+ } else {
325
+ assert ( this . newTurn , "Cannot execute a move after executing an incomplete move" ) ;
326
+ }
315
327
316
328
const execute = ( ) => {
317
- if ( ! this . executeMove ( move ) ) {
318
- assert ( allowIncomplete , `Move ${ move } (line ${ this . moveHistory . length + 1 } ) is not complete!` ) ;
319
- this . newTurn = false ;
329
+ try {
330
+ if ( ! this . executeMove ( move ) ) {
331
+ if ( ! this . replay ) {
332
+ assert ( allowIncomplete , `Move ${ move } (line ${ this . moveHistory . length + 1 } ) is not complete!` ) ;
333
+ }
334
+ this . newTurn = false ;
335
+ }
336
+ } catch ( e ) {
337
+ console . log ( this . assertContext ( ) ) ;
338
+ throw e ;
320
339
}
321
340
} ;
322
341
@@ -329,7 +348,9 @@ export default class Engine {
329
348
execute ( ) ;
330
349
}
331
350
332
- assert ( this . turnMoves . length === 0 , "Unnecessary commands at the end of the turn: " + this . turnMoves . join ( ". " ) ) ;
351
+ if ( ! this . replay ) {
352
+ assert ( this . turnMoves . length === 0 , "Unnecessary commands at the end of the turn: " + this . turnMoves . join ( ". " ) ) ;
353
+ }
333
354
this . moveHistory . push ( moveToShow ) ;
334
355
}
335
356
@@ -711,7 +732,7 @@ export default class Engine {
711
732
return false ;
712
733
}
713
734
714
- static fromData ( data : Record < string , any > ) {
735
+ static fromData ( data : Record < string , any > ) : Engine {
715
736
const engine = new Engine ( ) ;
716
737
delete engine . version ;
717
738
@@ -836,10 +857,12 @@ export default class Engine {
836
857
}
837
858
}
838
859
839
- assert (
840
- this . playerToMove === ( player as PlayerEnum ) ,
841
- "Wrong turn order in move " + move + ", expected player " + ( this . playerToMove + 1 ) + this . assertContext ( )
842
- ) ;
860
+ if ( ! this . replay ) {
861
+ assert (
862
+ this . playerToMove === ( player as PlayerEnum ) ,
863
+ "Wrong turn order in move " + move + ", expected player " + ( this . playerToMove + 1 )
864
+ ) ;
865
+ }
843
866
this . processedPlayer = player ;
844
867
845
868
const split = params . split ?? true ;
@@ -896,7 +919,7 @@ export default class Engine {
896
919
if ( subphase ) {
897
920
this . generateAvailableCommands ( subphase , data ) ;
898
921
if ( this . availableCommands . length === 0 ) {
899
- if ( required ) {
922
+ if ( required && ! this . replay ) {
900
923
// not allowed - see https://github.com/boardgamers/gaia-project/issues/76
901
924
this . availableCommands = [ { name : Command . DeadEnd , player : this . currentPlayer , data : subphase } ] ;
902
925
} else {
@@ -927,10 +950,10 @@ export default class Engine {
927
950
}
928
951
929
952
checkCommand ( command : Command ) {
930
- assert (
931
- ( this . availableCommand = this . findAvailableCommand ( this . playerToMove , command ) ) ,
932
- `Command ${ command } is not in the list of available commands: ${ this . assertContext ( ) } `
933
- ) ;
953
+ this . availableCommand = this . findAvailableCommand ( this . playerToMove , command ) ;
954
+ if ( ! this . availableCommand && ! this . replay ) {
955
+ assert ( this . availableCommand , `Command ${ command } is not in the list of available commands` ) ;
956
+ }
934
957
}
935
958
936
959
private assertContext ( ) : string {
@@ -1525,10 +1548,12 @@ export default class Engine {
1525
1548
}
1526
1549
1527
1550
[ Command . Bid ] ( player : PlayerEnum , faction : string , bid : number ) {
1528
- const bidsAC = this . avCommand < Command . Bid > ( ) . data . bids ;
1529
- const bidAC = bidsAC . find ( ( b ) => b . faction === faction ) ;
1530
- assert ( bidAC . bid . includes ( + bid ) , "You have to bid the right amount" ) ;
1531
- assert ( bidAC , `${ faction } is not in the available factions` ) ;
1551
+ if ( ! this . replay ) {
1552
+ const bidsAC = this . avCommand < Command . Bid > ( ) . data . bids ;
1553
+ const bidAC = bidsAC . find ( ( b ) => b . faction === faction ) ;
1554
+ assert ( bidAC , `${ faction } is not in the available factions` ) ;
1555
+ assert ( bidAC . bid . includes ( + bid ) , "You have to bid the right amount" ) ;
1556
+ }
1532
1557
this . executeBid ( player , faction , bid ) ;
1533
1558
}
1534
1559
@@ -1746,7 +1771,7 @@ export default class Engine {
1746
1771
return false ;
1747
1772
} ;
1748
1773
1749
- assert ( isPossible ( cost , income ) , `spend ${ cost } for ${ income } is not allowed: ${ this . assertContext ( ) } ` ) ;
1774
+ assert ( isPossible ( cost , income ) , `spend ${ cost } for ${ income } is not allowed` ) ;
1750
1775
1751
1776
pl . payCosts ( cost , Command . Spend ) ;
1752
1777
pl . gainRewards ( income , Command . Spend ) ;
@@ -1796,7 +1821,7 @@ export default class Engine {
1796
1821
[ Command . FormFederation ] ( player : PlayerEnum , hexes : string , federation : Federation ) {
1797
1822
const pl = this . player ( player ) ;
1798
1823
1799
- const fedInfo = pl . checkAndGetFederationInfo ( hexes , this . map , this . options . flexibleFederations ) ;
1824
+ const fedInfo = pl . checkAndGetFederationInfo ( hexes , this . map , this . options . flexibleFederations , this . replay ) ;
1800
1825
1801
1826
assert ( fedInfo , `Impossible to form federation at ${ hexes } ` ) ;
1802
1827
assert (
0 commit comments