function roboRally() { setUp(); while(!winner()) { dealCards(); placeCards(); actOnPowerDown(); for(let register = 1; register <= 5; register++) { revealCard(register); moveRobots(register); expressConveyorBelts(); conveyorBelts(); pushersPush(); gearsRotate(); fireLasers(); verifyCheckpoints(); } endOfTurnCleanUp(); } } function actOnPowerDown() { players.forEach((player) => { if (player.robot.powerDown) { player.robot.damage = 0; } if (player.decideRequestPowerDown()) { player.requestedPowerDown = true; } }); } function moveRobots(register: int) { players.map( (player) => { if (player.robot.dead) { return; } const card = player.getRegisterCard(register) if (player.robot.riskOfCollision(card.action)) { player.waitForPriority(card.priority); } player.robot.move(card.action); } ); } function conveyorBeltMoment(spot: Spot) { if (spot.nextSpot.robot) { return; } spot.robot.moveTo(spot.nextSpot); if (!spot.nextSpot.isBelt()) { return; } if (spot.nextSpot.turnCW) { spot.robot.turnCW(); } if (spot.nextSpot.turnCCW) { spot.robot.turnCCW(); } } function expressConveyorBelts() { board .filter((spot) => spot.type === 'expressBelt' && spot.robot) .map(conveyorBeltMoment); } function conveyorBelts() { board .filter((spot) => (spot.type === 'expressBelt' || spot.type === 'belt') && spot.robot) .map(conveyorBeltMoment); } function pushersPush() { board .filter((spot) => spot.type === 'pusher' && spot.robot) .map((spot) => spot.robot.moveTo(spot.nextSpot)); } function gearsRotate() { board .filter((spot) => spot.type === 'gear' && spot.robot) .map((spot) => spot.turnCW ? spot.robot.turnCW() : spot.robot.turnCCW()); } function dealCards() { for(const player of players) { player.getCards(9 - player.robot.damage) } } function fireLasers() { const lasers = [ ...board.filter((spot) => spot.type === 'laser').map((spot) => spot.laser), ...players.map((player) => player.robot.mainLaser) ] players.forEach((player) => { player.powerUps.filter((powerUp) => powerUp.type = 'laser').forEach((powerUp) => { lasers.push(powerUp.laser); }) }) lasers.forEach((laser) => laser.fire()) } function verifyCheckpoints() { players.forEach((player) => { if (player.robot.dead) { return; } const robotSpot = player.robot.spot; if (!robotSpot || robotSpot.type === 'pit') { player.robot.dead = true; return; } if (robotSpot.type !== 'repair' && robotSpot.type !== 'flag') { return; } if (player.robot.damage > 0) { player.robot.damage--; } player.robot.setSpawn(robotSpot); if (robotSpot.type === 'flag' && robotSpot.flagNr === player.targetFlag) { player.targetFlag++; } }) } function placeCards() { for(const player of players) { for(let registerIndex = 1; registerIndex <= 5; registerIndex++) { if (!player.registerIsLocked(registerIndex)) { player.putCard(registerIndex, player.cardDecision()); } } } } function winner() { const winners = players.filter((player) => player.targetFlag > game.lastFlag); if (winners.length < 1) { return null; } return winners[0]; } function endOfTurnCleanUp() { players.forEach((player) => { const robotSpot = player.robot.spot; if (robotSpot.type === 'repair' && robotSpot.dualWrench) { player.gainPowerUp(); } for(let register = 1; register <= 5; register++) { if (!player.cardIsLocked(register)) { player.discardCard(register); } } if (player.requestedPowerDown) { player.robot.powerDown = true; } else if (player.robot.powerDown && player.decidePowerDownDone()) { player.robot.powerDown = false; } if (player.robot.dead) { player.robot.dead = false; player.robot.moveTo(player.robot.spawnSpot, player.decideDirection()); player.robot.damage = 2; player.robot.powerDown = !player.decidePowerDownDone(); } }); }