wip: current project state
This commit is contained in:
+158
-26
@@ -1,11 +1,17 @@
|
||||
use verbatim::ai::GameSession;
|
||||
use verbatim::ai::AiAction;
|
||||
use verbatim::ai::GameSession;
|
||||
|
||||
fn setup() -> GameSession {
|
||||
let mut s = GameSession::new_seeded(42);
|
||||
s.init_empty();
|
||||
s.clear_area(90, 90, 50, 50);
|
||||
s.perform_action(&AiAction::FillRect { x: 80, y: 130, w: 80, h: 15, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: 80,
|
||||
y: 130,
|
||||
w: 80,
|
||||
h: 15,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s
|
||||
}
|
||||
|
||||
@@ -15,11 +21,22 @@ fn player_blocked_by_left_wall() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let wall_x = (p.pos[0] as i32) - 6;
|
||||
s.perform_action(&AiAction::FillRect { x: wall_x, y: 125, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: wall_x,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::MoveLeft);
|
||||
s.step(20);
|
||||
let p2 = s.get_player().unwrap();
|
||||
assert!(p2.pos[0] > wall_x as f32, "player should not pass through left wall: wall={} player={}", wall_x, p2.pos[0]);
|
||||
assert!(
|
||||
p2.pos[0] > wall_x as f32,
|
||||
"player should not pass through left wall: wall={} player={}",
|
||||
wall_x,
|
||||
p2.pos[0]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -28,11 +45,22 @@ fn player_blocked_by_right_wall() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let wall_x = (p.pos[0] as i32) + 6;
|
||||
s.perform_action(&AiAction::FillRect { x: wall_x, y: 125, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: wall_x,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::MoveRight);
|
||||
s.step(20);
|
||||
let p2 = s.get_player().unwrap();
|
||||
assert!(p2.pos[0] < wall_x as f32, "player should not pass through right wall: wall={} player={}", wall_x, p2.pos[0]);
|
||||
assert!(
|
||||
p2.pos[0] < wall_x as f32,
|
||||
"player should not pass through right wall: wall={} player={}",
|
||||
wall_x,
|
||||
p2.pos[0]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -41,14 +69,24 @@ fn player_slides_along_wall() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let wall_x = (p.pos[0] as i32) + 6;
|
||||
s.perform_action(&AiAction::FillRect { x: wall_x, y: 125, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: wall_x,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::MoveRight);
|
||||
s.step(30);
|
||||
let p2 = s.get_player().unwrap();
|
||||
assert!(p2.pos[0] < wall_x as f32, "player should stay left of wall");
|
||||
assert!(p2.alive, "player should be alive");
|
||||
let y_diff = (p2.pos[1] - p.pos[1]).abs();
|
||||
assert!(y_diff < 5.0, "player should not fall through floor while sliding: dy={}", y_diff);
|
||||
assert!(
|
||||
y_diff < 5.0,
|
||||
"player should not fall through floor while sliding: dy={}",
|
||||
y_diff
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -57,11 +95,22 @@ fn player_blocked_by_ceiling() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let ceiling_y = (p.pos[1] as i32) - 8;
|
||||
s.perform_action(&AiAction::FillRect { x: p.pos[0] as i32 - 5, y: ceiling_y, w: 10, h: 1, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: p.pos[0] as i32 - 5,
|
||||
y: ceiling_y,
|
||||
w: 10,
|
||||
h: 1,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::Jump);
|
||||
s.step(10);
|
||||
let p2 = s.get_player().unwrap();
|
||||
assert!(p2.pos[1] > ceiling_y as f32, "player should not pass through ceiling: ceiling={} player={}", ceiling_y, p2.pos[1]);
|
||||
assert!(
|
||||
p2.pos[1] > ceiling_y as f32,
|
||||
"player should not pass through ceiling: ceiling={} player={}",
|
||||
ceiling_y,
|
||||
p2.pos[1]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -69,13 +118,40 @@ fn player_navigates_corridor() {
|
||||
let mut s = GameSession::new_seeded(42);
|
||||
s.init_empty();
|
||||
s.clear_area(100, 100, 40, 30);
|
||||
s.perform_action(&AiAction::FillRect { x: 95, y: 120, w: 50, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect { x: 115, y: 110, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect { x: 125, y: 110, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect { x: 115, y: 108, w: 11, h: 1, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: 95,
|
||||
y: 120,
|
||||
w: 50,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: 115,
|
||||
y: 110,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: 125,
|
||||
y: 110,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: 115,
|
||||
y: 108,
|
||||
w: 11,
|
||||
h: 1,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
assert!(p.pos[0] < 115.0 || p.pos[0] > 125.0, "player should be outside corridor initially");
|
||||
assert!(
|
||||
p.pos[0] < 115.0 || p.pos[0] > 125.0,
|
||||
"player should be outside corridor initially"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -84,7 +160,13 @@ fn player_does_not_stick_to_wall() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let wall_x = (p.pos[0] as i32) + 8;
|
||||
s.perform_action(&AiAction::FillRect { x: wall_x, y: 125, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: wall_x,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
for _ in 0..10 {
|
||||
s.perform_action(&AiAction::MoveRight);
|
||||
s.step(2);
|
||||
@@ -96,7 +178,12 @@ fn player_does_not_stick_to_wall() {
|
||||
s.step(2);
|
||||
}
|
||||
let p_away = s.get_player().unwrap();
|
||||
assert!(p_away.pos[0] < x_at_wall - 1.0, "player should move away from wall: {} -> {}", x_at_wall, p_away.pos[0]);
|
||||
assert!(
|
||||
p_away.pos[0] < x_at_wall - 1.0,
|
||||
"player should move away from wall: {} -> {}",
|
||||
x_at_wall,
|
||||
p_away.pos[0]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -105,8 +192,20 @@ fn player_squeezes_through_gap() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let px = p.pos[0] as i32;
|
||||
s.perform_action(&AiAction::FillRect { x: px + 8, y: 128, w: 1, h: 2, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect { x: px + 8, y: 122, w: 1, h: 2, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: px + 8,
|
||||
y: 128,
|
||||
w: 1,
|
||||
h: 2,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: px + 8,
|
||||
y: 122,
|
||||
w: 1,
|
||||
h: 2,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::MoveRight);
|
||||
s.step(20);
|
||||
let p2 = s.get_player().unwrap();
|
||||
@@ -119,8 +218,20 @@ fn player_blocked_by_two_walls_both_sides() {
|
||||
s.step(30);
|
||||
let p = s.get_player().unwrap();
|
||||
let px = p.pos[0] as i32;
|
||||
s.perform_action(&AiAction::FillRect { x: px - 6, y: 125, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect { x: px + 6, y: 125, w: 1, h: 10, material: "stone".into() });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: px - 6,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: px + 6,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 10,
|
||||
material: "stone".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::MoveRight);
|
||||
s.step(10);
|
||||
let p_right = s.get_player().unwrap();
|
||||
@@ -129,7 +240,10 @@ fn player_blocked_by_two_walls_both_sides() {
|
||||
let p_left = s.get_player().unwrap();
|
||||
assert!(p_right.pos[0] < (px + 6) as f32, "blocked right");
|
||||
assert!(p_left.pos[0] > (px - 6) as f32, "blocked left");
|
||||
assert!((p_left.pos[0] - p_right.pos[0]).abs() < 12.0, "player should stay between walls");
|
||||
assert!(
|
||||
(p_left.pos[0] - p_right.pos[0]).abs() < 12.0,
|
||||
"player should stay between walls"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -140,7 +254,11 @@ fn player_walks_up_slope() {
|
||||
for x in 100..130 {
|
||||
let h = ((x - 100) / 3).min(15);
|
||||
for y in 0..h {
|
||||
s.perform_action(&AiAction::SetCell { x, y: 135 - 1 - y, material: "stone".into() });
|
||||
s.perform_action(&AiAction::SetCell {
|
||||
x,
|
||||
y: 135 - 1 - y,
|
||||
material: "stone".into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
s.step(40);
|
||||
@@ -152,11 +270,25 @@ fn player_walks_up_slope() {
|
||||
#[test]
|
||||
fn entity_collision_with_dirt_wall() {
|
||||
let mut s = setup();
|
||||
s.perform_action(&AiAction::FillRect { x: 140, y: 125, w: 1, h: 5, material: "dirt".into() });
|
||||
s.perform_action(&AiAction::Spawn { kind: "goblin".into(), x: 135.0, y: 120.0 });
|
||||
s.perform_action(&AiAction::FillRect {
|
||||
x: 140,
|
||||
y: 125,
|
||||
w: 1,
|
||||
h: 5,
|
||||
material: "dirt".into(),
|
||||
});
|
||||
s.perform_action(&AiAction::Spawn {
|
||||
kind: "goblin".into(),
|
||||
x: 135.0,
|
||||
y: 120.0,
|
||||
});
|
||||
s.step(40);
|
||||
let entities = s.get_entities();
|
||||
if let Some(g) = entities.into_iter().find(|e| e.kind == "Goblin" && e.alive) {
|
||||
assert!(g.pos[0] < 140.0, "goblin should be blocked by dirt wall: x={}", g.pos[0]);
|
||||
assert!(
|
||||
g.pos[0] < 140.0,
|
||||
"goblin should be blocked by dirt wall: x={}",
|
||||
g.pos[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user