From: JBM Date: Thu, 11 Jun 2020 14:38:43 +0000 (+0200) Subject: Leaguify cheating X-Git-Url: https://troll.desast.re/troll.git/commitdiff_plain/e9fb4b60ebdea1a383b0963aa71d0a3ffc1e3822?ds=inline Leaguify cheating --- diff --git a/PLAN.org b/PLAN.org index e31b52c..25d67cd 100644 --- a/PLAN.org +++ b/PLAN.org @@ -50,12 +50,18 @@ ** TODO Leagues (need multiround) ** TODO Multiround (need early termination) ** TODO Leaguification +- [X] Cheating +- [ ] Maps +- [ ] Trolls +- [ ] ** DONE Early termination (need time rationalization) ** DONE Time rationalization (need code reorg) ** TODO Code cleanup That one's probably never going to be DONE ^^' +- [ ] split GameManager + *** organize routines by functional area *** split out what can be diff --git a/src/main/java/com/codingame/game/LeagueManager.java b/src/main/java/com/codingame/game/LeagueManager.java index ed7d455..94a7f5f 100644 --- a/src/main/java/com/codingame/game/LeagueManager.java +++ b/src/main/java/com/codingame/game/LeagueManager.java @@ -18,6 +18,9 @@ class LeagueManager { @Inject LeagueManager(MultiplayerGameManager gameManager) { - cheatLevel = CheatLevel.FORBIDDEN; + int level = gameManager.getLeagueLevel(); + cheatLevel = level <= 1 ? CheatLevel.ALLOWED + : level <= 2 ? CheatLevel.TOLERATED + : CheatLevel.FORBIDDEN; } } diff --git a/src/main/java/com/codingame/game/Model.java b/src/main/java/com/codingame/game/Model.java index 108b5a6..217388a 100644 --- a/src/main/java/com/codingame/game/Model.java +++ b/src/main/java/com/codingame/game/Model.java @@ -26,6 +26,11 @@ class Model { hit = false; } + void loseRound() { + hit = true; + winner = 1 - index; + } + private int castlePosition; public int getCastlePosition() { return castlePosition; } public void setCastlePosition(int pos) { castlePosition = pos; } diff --git a/src/main/java/com/codingame/game/Referee.java b/src/main/java/com/codingame/game/Referee.java index 19ef894..fb99ef9 100644 --- a/src/main/java/com/codingame/game/Referee.java +++ b/src/main/java/com/codingame/game/Referee.java @@ -105,6 +105,7 @@ public class Referee extends AbstractReferee { } player.view.displayMessage(player.messageString); } + if (disqual) return; /* Update game model and view, stones' part. * @@ -123,9 +124,19 @@ public class Referee extends AbstractReferee { delta += player.model.getMultiplier() * player.stoneThrow; if (player.stoneThrow < 0) { - disqualify(player, "CHEAT", "cheated. Banning account."); - player.view.markCheat(); - disqual = true; + switch(league.cheatLevel) { + case ALLOWED: + break; + case TOLERATED: + player.view.markCheat(); + if (model.random.nextInt(2) == 0) player.model.loseRound(); + break; + case FORBIDDEN: + disqualify(player, "CHEAT", "cheated. Banning account."); + player.view.markCheat(); + disqual = true; + break; + } } if (player.stoneThrow != 0) { player.view.animateStones(player.stoneThrow); diff --git a/src/test/java/TrollTest.java b/src/test/java/TrollTest.java index e8dff3f..7b998b9 100644 --- a/src/test/java/TrollTest.java +++ b/src/test/java/TrollTest.java @@ -11,15 +11,24 @@ import org.junit.Test; import com.codingame.gameengine.runner.MultiplayerGameRunner; import com.codingame.gameengine.runner.dto.*; -public class TrollTest { - static GameResult runGame(String left, String right) { +public class TrollTest implements Cloneable { + Integer leagueLevel; + Long seed; + TrollTest branch() { + try { return (TrollTest) clone(); } + catch (CloneNotSupportedException e) { throw new InternalError(e); } + } + TrollTest setLeague(int league) { leagueLevel = league; return this; } + TrollTest setSeed(long seed) { this.seed = seed; return this; } + + GameResult runGame(String left, String right) { MultiplayerGameRunner gameRunner = new MultiplayerGameRunner(); Properties gameParameters = new Properties(); gameParameters.setProperty("roadLength", "6"); gameParameters.setProperty("initialStones", "15"); gameRunner.setGameParameters(gameParameters); - gameRunner.setSeed(0l); - gameRunner.setLeagueLevel(1); + if (seed != null) gameRunner.setSeed(seed); else gameRunner.setSeed(0l); + if (leagueLevel != null) gameRunner.setLeagueLevel(leagueLevel); gameRunner.addAgent(left); gameRunner.addAgent(right); @@ -48,8 +57,17 @@ public class TrollTest { // win despite fastforward after winner exhaustion // (harder to construct :-D ) - assertWinLose(agent(1,2,2,2,8), - agent(3,1,1,1,8)); + assertWinLose(agent(1,2,2,2,8), agent(3,1,1,1,8)); + } + + @Test + public void cheatingGames() { + // win by cheating (works in league 1, which is the default) + assertWinLose(agentCheat, agentTwo); + + // league 2 randomizes: we should be able to get a win and a loss + branch().setLeague(2).setSeed(0).assertWinLose(agentCheat, agentTwo); + branch().setLeague(2).setSeed(1).assertWinLose(agentTwo, agentCheat); } // great thanks to @dbdr for the intense moral support leading to @@ -58,6 +76,7 @@ public class TrollTest { static String agentTwo = "yes 2"; static String agentCrash = "false"; static String agentGarbage = "yes this_is_assuredly_not_an_int"; + static String agentCheat = agent(-100,25,25,25,25); static String agent(int... tosses) { String cmd = "echo -e "; @@ -113,25 +132,33 @@ public class TrollTest { p.println("[agent] " + agent.agentId + ": " + agent.avatar + " " + agent.index + " " + agent.name); } - static void assertWinLose(String winner, String loser) { + void assertWinLose(String winner, String loser) { assertLeftWin(runGame(winner, loser)); assertRightWin(runGame(loser, winner)); } static void assertLeftWin(GameResult gameResult) { + assertLeftWin(gameResult, false); + } + static void assertLeftWin(GameResult gameResult, boolean strict) { int[] scores = assertTwoScores(gameResult); if (scores == null) return; int s1 = scores[0], s2 = scores[1]; assertTrue("Left player has higher score than right player", s1 > s2); + if (strict) assertTrue("Right player isn't disqualified", s2 >= 0); } static void assertRightWin(GameResult gameResult) { + assertRightWin(gameResult, false); + } + static void assertRightWin(GameResult gameResult, boolean strict) { int[] scores = assertTwoScores(gameResult); if (scores == null) return; int s1 = scores[0], s2 = scores[1]; assertTrue("Right player has higher score than right player", s2 > s1); + if (strict) assertTrue("Left player isn't disqualified", s1 >= 0); } static void assertIsDraw(GameResult gameResult) {