Files
goon-game/app/src/test/java/com/projectsacrifice/game/LevelPlaytestBotTest.java
T

187 lines
6.3 KiB
Java

package com.projectsacrifice.game;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public final class LevelPlaytestBotTest {
@Test
public void scenarioProgressesThroughNamedSteps() {
ScriptedDriver driver = new ScriptedDriver();
LevelPlaytestBot.Scenario scenario = LevelPlaytestBot.Scenario
.builder(7, "Reusable scenario")
.step("Create a corpse", 1_000L, LevelPlaytestBot.Input.right(),
snapshot -> snapshot.deaths() >= 1)
.step("Reach the goal", 1_000L, LevelPlaytestBot.Input.left(),
GameView.AutomationSnapshot::completed)
.build();
LevelPlaytestBot.Result result = new LevelPlaytestBot().run(driver, scenario, 5_000L);
assertTrue(result.diagnostic(), result.completed());
assertEquals(7, driver.startedLevel);
assertEquals("Reach the goal", result.lastStep());
}
@Test
public void stepTimeoutReportsItsNameAndObservableSnapshot() {
ScriptedDriver driver = new ScriptedDriver(false);
LevelPlaytestBot.Scenario scenario = LevelPlaytestBot.Scenario
.builder(5, "Diagnostic scenario")
.step("Keep the plate pressed", 64L, LevelPlaytestBot.Input.right(),
GameView.AutomationSnapshot::allDoorsOpen)
.build();
LevelPlaytestBot.Result result = new LevelPlaytestBot().run(driver, scenario, 5_000L);
assertFalse(result.completed());
assertEquals("Keep the plate pressed", result.lastStep());
assertTrue(result.diagnostic(), result.diagnostic().contains("step=Keep the plate pressed"));
assertTrue(result.diagnostic(), result.diagnostic().contains("x=100.0"));
assertTrue(result.diagnostic(), result.diagnostic().contains("y=760.0"));
assertTrue(result.diagnostic(), result.diagnostic().contains("alive=true"));
assertTrue(result.diagnostic(), result.diagnostic().contains("deaths=0"));
assertTrue(result.diagnostic(), result.diagnostic().contains("corpses=0"));
assertTrue(result.diagnostic(), result.diagnostic().contains("allDoorsOpen=false"));
}
@Test
public void levelFiveUsesTheGenericNamedScenario() {
LevelFiveDriver driver = new LevelFiveDriver();
LevelPlaytestBot.Result result = new LevelPlaytestBot().proveLevelFive(driver, 25_000L);
assertTrue(result.diagnostic(), result.completed());
assertEquals(5, driver.startedLevel);
assertEquals("Reach the relic", result.lastStep());
assertEquals(1, result.deaths());
assertEquals(1, result.corpseCount());
assertTrue(result.doorOpened());
}
private static final class ScriptedDriver implements LevelPlaytestBot.Driver {
private int startedLevel;
private long nowMillis;
private boolean moveLeft;
private boolean moveRight;
private int deaths;
private boolean completed;
private final boolean progresses;
ScriptedDriver() {
this(true);
}
ScriptedDriver(boolean progresses) {
this.progresses = progresses;
}
@Override
public void startLevel(int oneBasedLevelNumber) {
startedLevel = oneBasedLevelNumber;
}
@Override
public void setInput(boolean moveLeft, boolean moveRight, boolean jump) {
this.moveLeft = moveLeft;
this.moveRight = moveRight;
}
@Override
public GameView.AutomationSnapshot snapshot() {
return new GameView.AutomationSnapshot(
completed,
true,
false,
false,
moveLeft || moveRight,
startedLevel,
nowMillis,
100f,
760f,
deaths,
deaths
);
}
@Override
public void waitForNextDecision(long millis) {
nowMillis += millis;
if (progresses && moveRight && deaths == 0) {
deaths = 1;
} else if (progresses && moveLeft && deaths == 1) {
completed = true;
}
}
@Override
public long currentTimeMillis() {
return nowMillis;
}
}
private static final class LevelFiveDriver implements LevelPlaytestBot.Driver {
private int startedLevel;
private long nowMillis;
private boolean moveRight;
private boolean jump;
private boolean alive = true;
private boolean doorOpen;
private boolean completed;
private int deaths;
private int corpses;
private float x = 130f;
@Override
public void startLevel(int oneBasedLevelNumber) {
startedLevel = oneBasedLevelNumber;
}
@Override
public void setInput(boolean moveLeft, boolean moveRight, boolean jump) {
this.moveRight = moveRight;
this.jump = jump;
}
@Override
public GameView.AutomationSnapshot snapshot() {
return new GameView.AutomationSnapshot(
completed, alive, doorOpen, false, moveRight || jump,
startedLevel, nowMillis, x, 760f, deaths, corpses);
}
@Override
public void waitForNextDecision(long millis) {
nowMillis += millis;
if (!alive) {
alive = true;
x = 130f;
} else if (deaths == 0 && moveRight && !jump) {
deaths = 1;
corpses = 1;
alive = false;
doorOpen = true;
x = 570f;
} else if (moveRight && jump) {
x += 60f;
} else if (moveRight && x < 390f) {
x = 400f;
} else if (moveRight && x < 750f) {
x = 760f;
} else if (moveRight && x < 1_390f) {
x = 1_500f;
} else if (moveRight) {
x = 2_080f;
completed = true;
}
}
@Override
public long currentTimeMillis() {
return nowMillis;
}
}
}