From a20d6434a5e58290b07bebff84a2049122385698 Mon Sep 17 00:00:00 2001 From: compiler64 Date: Wed, 7 Jan 2026 17:47:33 -0500 Subject: [PATCH 01/10] fix canAttack bug --- .../battlecode/world/RobotControllerImpl.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 3c753c63..10ca5c95 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -950,12 +950,14 @@ private void assertCanAttackRat(MapLocation loc, int cheeseConsumed) throws Game assertIsActionReady(); // Attack is limited to vision radius assertCanActLocation(loc, this.getType().getVisionRadiusSquared()); + if (!this.getLocation().isAdjacentTo(loc)) { throw new GameActionException(CANT_DO_THAT, "Rats can only attack adjacent squares!"); } - if (!this.gameWorld.isPassable(loc)) + if (!this.gameWorld.isPassable(loc)) { throw new GameActionException(CANT_DO_THAT, "Rats cannot attack squares with walls or dirt on them!"); + } if (this.gameWorld.getTeamInfo().getCheese(this.getTeam()) + this.getAllCheese() < cheeseConsumed) { throw new GameActionException(CANT_DO_THAT, "Not enough cheese to bite!"); @@ -964,13 +966,23 @@ private void assertCanAttackRat(MapLocation loc, int cheeseConsumed) throws Game if (this.getType() == UnitType.CAT) { throw new GameActionException(CANT_DO_THAT, "Unit must be a baby rat or rat king to bite!"); } + + if (cheeseConsumed < 0) { + throw new GameActionException(CANT_DO_THAT, "Cheese consumed must be non-negative!"); + } + + if (this.gameWorld.getRobot(loc) == null) { + throw new GameActionException(CANT_DO_THAT, "No robot to attack at the specified location!"); + } } private void assertCanAttackCat(MapLocation loc) throws GameActionException { assertIsActionReady(); assertCanActLocation(loc, this.getType().getVisionRadiusSquared()); - if (!this.gameWorld.isPassable(loc)) + + if (!this.gameWorld.isPassable(loc)) { throw new GameActionException(CANT_DO_THAT, "Cats cannot attack squares with walls or dirt on them!"); + } } private void assertCanAttack(MapLocation loc, int cheeseConsumed) throws GameActionException { From 94db7271ca3d396cf626511c9117678f009f386e Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Wed, 7 Jan 2026 17:49:07 -0500 Subject: [PATCH 02/10] small fixes --- client/src/playback/Actions.ts | 7 +++---- client/src/playback/Map.ts | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/src/playback/Actions.ts b/client/src/playback/Actions.ts index ced8d666..7361470a 100644 --- a/client/src/playback/Actions.ts +++ b/client/src/playback/Actions.ts @@ -655,16 +655,15 @@ export const ACTION_DEFINITIONS: Record Date: Wed, 7 Jan 2026 18:07:58 -0500 Subject: [PATCH 03/10] call ratnap action when rat lands --- engine/src/main/battlecode/server/GameMaker.java | 4 ++-- engine/src/main/battlecode/world/InternalRobot.java | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/server/GameMaker.java b/engine/src/main/battlecode/server/GameMaker.java index 6a727920..9c342433 100644 --- a/engine/src/main/battlecode/server/GameMaker.java +++ b/engine/src/main/battlecode/server/GameMaker.java @@ -559,9 +559,9 @@ public void addDamageAction(int damagedRobotID, int damage) { }); } - public void addRatNapAction(int grabberRobotID) { + public void addRatNapAction(int nappedID) { applyToBuilders((builder) -> { - int action = RatNap.createRatNap(builder, grabberRobotID); + int action = RatNap.createRatNap(builder, nappedID); builder.addAction(action, Action.RatNap); }); } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index c1e8a4d4..a4a96c0c 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -617,7 +617,7 @@ public void scratch(MapLocation loc) { public void grabRobot(MapLocation loc) { this.robotBeingCarried = this.gameWorld.getRobot(loc); this.robotBeingCarried.getGrabbed(this); // Notify the grabbed robot that it has been picked up - this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); + this.gameWorld.getMatchMaker().addRatNapAction(this.robotBeingCarried.getID()); if (this.robotBeingCarried.getTeam() != this.getTeam()) { this.gameWorld.isCooperation = false; @@ -650,7 +650,8 @@ private void swapGrabber() { this.gameWorld.removeRobot(dropLoc); this.gameWorld.addRobot(dropLoc, this); - this.gameWorld.getMatchMaker().addRatNapAction(this.ID); + this.gameWorld.getMatchMaker().addRatNapAction(this.ID); // expand this rat + this.gameWorld.getMatchMaker().addRatNapAction(grabber.ID); // shrink carrier rat if (grabber.getTeam() != this.getTeam()) { grabber.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; @@ -714,6 +715,8 @@ public void getDropped(MapLocation loc) { this.grabbedByRobot = null; this.remainingCarriedDuration = 0; this.setInternalLocationOnly(loc); + + this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); if (this.getHealth() > 0) this.gameWorld.addRobot(this.getLocation(), this); @@ -729,6 +732,8 @@ public void hitGround() { this.addHealth(-damage); this.gameWorld.getMatchMaker().addDamageAction(this.ID, damage); + this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); + if (this.health > 0) { this.gameWorld.addRobot(this.location, this); @@ -760,6 +765,7 @@ public void hitTarget(boolean isSecondMove) { setActionCooldownTurns(this.actionCooldownTurns + GameConstants.HIT_TARGET_COOLDOWN); setTurningCooldownTurns(this.turningCooldownTurns + GameConstants.HIT_TARGET_COOLDOWN); this.gameWorld.getMatchMaker().addDamageAction(this.ID, damage); + this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); this.gameWorld.getMatchMaker().addStunAction(this.ID, GameConstants.HIT_TARGET_COOLDOWN); } From fc8aa7792601569a3de554062c0cb0a326f311e5 Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Wed, 7 Jan 2026 18:21:41 -0500 Subject: [PATCH 04/10] ratnap fix --- client/src/playback/Actions.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/client/src/playback/Actions.ts b/client/src/playback/Actions.ts index 7361470a..643df838 100644 --- a/client/src/playback/Actions.ts +++ b/client/src/playback/Actions.ts @@ -189,12 +189,19 @@ export const ACTION_DEFINITIONS: Record Date: Wed, 7 Jan 2026 19:27:46 -0500 Subject: [PATCH 05/10] cheese spawn 5 cheese showing up as 10 fix --- engine/src/main/battlecode/world/GameWorld.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 68351553..cfda5e5a 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -509,14 +509,15 @@ public void spawnCheese(CheeseMine mine) { // corresponding one if (spawn) { - addCheese(ogSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); - addCheese(pairedSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); mine.setLastRound(this.currentRound); pairedMine.setLastRound(this.currentRound); matchMaker.addCheeseSpawnAction(ogSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT + this.getCheeseAmount(ogSpawnLoc)); matchMaker.addCheeseSpawnAction(pairedSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT + this.getCheeseAmount(pairedSpawnLoc)); + + addCheese(ogSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); + addCheese(pairedSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); } } From ba42034b139fb01abd4924c8447d1863a3a3cda8 Mon Sep 17 00:00:00 2001 From: Hannah Date: Wed, 7 Jan 2026 19:46:27 -0500 Subject: [PATCH 06/10] decrease cat vision cone, increase cheese spawn amount, decrease rat king cheese consumption, change bite damage scaling to sqrt --- engine/src/main/battlecode/common/GameConstants.java | 4 ++-- engine/src/main/battlecode/common/UnitType.java | 2 +- engine/src/main/battlecode/world/InternalRobot.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/main/battlecode/common/GameConstants.java b/engine/src/main/battlecode/common/GameConstants.java index 6a235426..b1cb4ca9 100644 --- a/engine/src/main/battlecode/common/GameConstants.java +++ b/engine/src/main/battlecode/common/GameConstants.java @@ -89,7 +89,7 @@ public class GameConstants { public static final double CHEESE_COOLDOWN_PENALTY = 0.01; /** The amount of cheese the rat king consumes each round. */ - public static final int RAT_KING_CHEESE_CONSUMPTION = 3; + public static final int RAT_KING_CHEESE_CONSUMPTION = 2; /** The amount of health the rat king loses by not eating cheese. */ public static final int RAT_KING_HEALTH_LOSS = 10; @@ -101,7 +101,7 @@ public class GameConstants { public static final int SQ_CHEESE_SPAWN_RADIUS = 4; /** How much cheese each mine spawns at once */ - public static final int CHEESE_SPAWN_AMOUNT = 5; + public static final int CHEESE_SPAWN_AMOUNT = 20; /** The number of rat kings a player starts with. */ public static final int NUMBER_INITIAL_RAT_KINGS = 1; diff --git a/engine/src/main/battlecode/common/UnitType.java b/engine/src/main/battlecode/common/UnitType.java index ca5367be..f43bb06e 100644 --- a/engine/src/main/battlecode/common/UnitType.java +++ b/engine/src/main/battlecode/common/UnitType.java @@ -4,7 +4,7 @@ public enum UnitType { // health, size, speed, visionRadius, actionCooldown BABY_RAT(100, 1, 20, 90, 10, 10, 17500), RAT_KING(500, 3, 25, 360, 10, 40, 20000), - CAT(10_000, 2, 30, 180, 15, 10, 17500); + CAT(10_000, 2, 17, 180, 15, 10, 17500); // amount of health robot initially starts with public final int health; diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index a4a96c0c..3feb706b 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -585,7 +585,7 @@ public void bite(MapLocation loc, int cheeseConsumed) { if (cheeseConsumed > 0) { this.addCheese(-cheeseConsumed); - damage += (int) Math.ceil(Math.log(cheeseConsumed)); + damage += (int) Math.ceil(Math.sqrt(cheeseConsumed)); } targetRobot.addHealth(-damage); From d8b7776988ebc8cb5e06b4f141473398afc43dfd Mon Sep 17 00:00:00 2001 From: Hannah Date: Wed, 7 Jan 2026 20:52:09 -0500 Subject: [PATCH 07/10] changes to throwing/carrying --- .../main/battlecode/world/InternalRobot.java | 26 +++++-------------- .../battlecode/world/RobotControllerImpl.java | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index 3feb706b..2ab99aeb 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -653,9 +653,7 @@ private void swapGrabber() { this.gameWorld.getMatchMaker().addRatNapAction(this.ID); // expand this rat this.gameWorld.getMatchMaker().addRatNapAction(grabber.ID); // shrink carrier rat - if (grabber.getTeam() != this.getTeam()) { - grabber.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; - } + grabber.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; } private void getGrabbed(InternalRobot grabber) { @@ -669,9 +667,7 @@ private void getGrabbed(InternalRobot grabber) { this.setInternalLocationOnly(grabber.getLocation()); - if (grabber.getTeam() != this.getTeam()) { - this.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; - } + this.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; } @@ -689,18 +685,11 @@ private void getThrown(Direction dir) { this.thrownDir = dir; this.remainingThrowDuration = 4; - MapLocation nextLoc = this.getLocation().add(dir); + this.setInternalLocationOnly(this.getLocation()); + this.gameWorld.removeRobot(this.getLocation()); - // Cat feeding! - if (this.gameWorld.getRobot(nextLoc) != null) { // there's a cat here - this.addHealth(-this.getHealth()); // rat dies :( - // put cat to sleep - this.gameWorld.getRobot(nextLoc).sleepTimeRemaining = GameConstants.CAT_SLEEP_TIME; - this.gameWorld.getMatchMaker().addCatFeedAction(this.getID()); - } else { - this.setInternalLocationOnly(this.getLocation().add(dir)); - this.gameWorld.removeRobot(this.getLocation()); - } + this.travelFlying(true); + this.travelFlying(false); } public void getDropped(MapLocation loc) { @@ -1059,8 +1048,7 @@ public void processBeginningOfTurn() { this.gameWorld.runCheeseMines(); // if rat is being carried - if (this.getType() == UnitType.BABY_RAT && this.isGrabbedByRobot() - && this.getGrabbedByRobot().getTeam() != this.getTeam()) { + if (this.getType() == UnitType.BABY_RAT && this.isGrabbedByRobot()) { // check if grabber has died if (this.getGrabbedByRobot().getHealth() <= 0) { diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 10ca5c95..639192f4 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -1328,7 +1328,7 @@ public void assertCanCarryRat(MapLocation loc) throws GameActionException { } // adjacency - if (!loc.isAdjacentTo(this.getLocation())) { + if (!loc.isAdjacentTo(this.getLocation()) && !this.getLocation().equals(loc)) { throw new GameActionException(CANT_DO_THAT, "A rat can only grab adjacent robots!"); } From 2e8dce7164d69a290f06b25936e9414d0dcea76b Mon Sep 17 00:00:00 2001 From: Hannah Date: Wed, 7 Jan 2026 20:53:39 -0500 Subject: [PATCH 08/10] cat movement cooldown change 10 to 20 --- engine/src/main/battlecode/common/UnitType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/UnitType.java b/engine/src/main/battlecode/common/UnitType.java index f43bb06e..585bcf56 100644 --- a/engine/src/main/battlecode/common/UnitType.java +++ b/engine/src/main/battlecode/common/UnitType.java @@ -4,7 +4,7 @@ public enum UnitType { // health, size, speed, visionRadius, actionCooldown BABY_RAT(100, 1, 20, 90, 10, 10, 17500), RAT_KING(500, 3, 25, 360, 10, 40, 20000), - CAT(10_000, 2, 17, 180, 15, 10, 17500); + CAT(10_000, 2, 17, 180, 15, 20, 17500); // amount of health robot initially starts with public final int health; From eec67bfd57fd7651b63f486e415ba901b3d5e0f6 Mon Sep 17 00:00:00 2001 From: Hannah Date: Wed, 7 Jan 2026 21:14:51 -0500 Subject: [PATCH 09/10] cat can dig again --- engine/src/main/battlecode/world/RobotControllerImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 639192f4..07c7bc33 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -983,6 +983,12 @@ private void assertCanAttackCat(MapLocation loc) throws GameActionException { if (!this.gameWorld.isPassable(loc)) { throw new GameActionException(CANT_DO_THAT, "Cats cannot attack squares with walls or dirt on them!"); } + if (this.gameWorld.getRobot(loc) == null) { + throw new GameActionException(CANT_DO_THAT, "No robot to attack at the specified location!"); + } + if (this.gameWorld.getRobot(loc) != null && this.gameWorld.getRobot(loc).getID() == this.robot.getID()) { + throw new GameActionException(CANT_DO_THAT, "Cannot attack self"); + } } private void assertCanAttack(MapLocation loc, int cheeseConsumed) throws GameActionException { From cefe62ee08c8c14217a8cdfb1b4d271e417679cf Mon Sep 17 00:00:00 2001 From: Hannah Date: Wed, 7 Jan 2026 21:37:36 -0500 Subject: [PATCH 10/10] trap cost and cooldown to 30 and 15 --- engine/src/main/battlecode/common/TrapType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/battlecode/common/TrapType.java b/engine/src/main/battlecode/common/TrapType.java index 69a3d627..1e6c5edb 100644 --- a/engine/src/main/battlecode/common/TrapType.java +++ b/engine/src/main/battlecode/common/TrapType.java @@ -9,7 +9,7 @@ public enum TrapType { /** * Traps enemy rats */ - RAT_TRAP(5, 50, 20, 25, 5, 0, 25, 2), + RAT_TRAP(30, 50, 20, 25, 15, 0, 25, 2), /** * Traps the cat