/** * A GridStage tweeked to more closely mimic the game XOR. * The original XOR didn't animate the game objects, they instantly moved from one square to another. * I want my version to look better than that, but this adds some trickyness. * * Firstly, we never want player to do "Repton Shuffles", where speed is important. * So if any non-players are moving, then the Players cannot move. * * Secondly, the order that the grid is scanned is different, so that XORChickens get priority over * XORFish. So from the point of view of an empty square, the item to the RIGHT get first dibs. * So we scan bottom to top and right to left. */ class XORGridStage : GridStage { var somethingIsMoving = false /** * The order is different to normal. * We go from bottom to top, and from right to left. */ override fun buildLists() { for ( y in 0 until down ) { for ( x in 0 until across ) { addSquare( squares[x][y] ) } } } override fun tickPlayerList() { val wasMoving = somethingIsMoving for ( role in playerList ) { if ( ! wasMoving || role.isMoving() ) { tickRole(role) } } } override fun tickLists() { somethingIsMoving = false for ( item in roleList ) { if (item.isMoving()) { somethingIsMoving = true break } } tickRoleList() for ( item in roleList ) { if (item.isMoving()) { somethingIsMoving = true break } } tickPlayerList() } override fun willMissExtra( item : Item, sameDirection : boolean, speed : int ) : int { val gs = item.gridSize() if ( item.isPlayer() ) { // If player is running out of a square, then give priority to those moving // in at a right angle val foo : int = if (sameDirection) { ( gs ~/ speed ) } else { (gs ~/ 2 ~/ speed) } return foo } else { // Allow rows/columns of the same object move nose to tail without a gap. return if (sameDirection ) 0 else (gs/2 ~/ speed) } } }