@@ -599,10 +599,19 @@ export class ArimaaGame extends GameBase {
599599 // now we just have to check completeness and return
600600 let complete : - 1 | 0 | 1 ;
601601 let message : string ;
602- // in free mode, always 0 with specific message
602+ // in free mode:
603+ // - usually 0 with specific message
604+ // - but must have 1 rabbit and none on the goal row
603605 if ( this . variants . includes ( "free" ) ) {
604- complete = 0 ;
605- message = i18next . t ( "apgames:validation.arimaa.PARTIAL_FREE" )
606+ const rabbits = [ ...cloned . board . entries ( ) ] . filter ( e => e [ 1 ] [ 1 ] === cloned . currplayer && e [ 1 ] [ 0 ] === "R" ) . map ( e => e [ 0 ] ) ;
607+ const goal = cloned . currplayer === 1 ? "8" : "1" ;
608+ if ( rabbits . length === 0 || rabbits . filter ( cell => cell . endsWith ( goal ) ) . length > 0 ) {
609+ complete = - 1 ;
610+ message = i18next . t ( "apgames:validation.arimaa.PARTIAL_FREE_NO" )
611+ } else {
612+ complete = 0 ;
613+ message = i18next . t ( "apgames:validation.arimaa.PARTIAL_FREE" )
614+ }
606615 }
607616 // otherwise, you have to place all your pieces
608617 else {
@@ -906,6 +915,18 @@ export class ArimaaGame extends GameBase {
906915 this . hands = undefined ;
907916 }
908917
918+ // After free setup, activate all traps
919+ if ( this . variants . includes ( "free" ) && this . stack . length === 2 ) {
920+ for ( const trap of traps ) {
921+ if ( this . board . has ( trap ) && this . isAlone ( trap ) ) {
922+ const [ trapPc , trapOwner ] = this . board . get ( trap ) ! ;
923+ this . board . delete ( trap ) ;
924+ this . results . push ( { type : "destroy" , what : trapOwner === 1 ? trapPc : trapPc . toLowerCase ( ) , where : trap } ) ;
925+ lastmove . push ( `x${ trapOwner === 1 ? trapPc : trapPc . toLowerCase ( ) } ${ trap } ` ) ;
926+ }
927+ }
928+ }
929+
909930 // update currplayer
910931 this . lastmove = lastmove . join ( "," ) ;
911932 let newplayer = ( this . currplayer as number ) + 1 ;
0 commit comments