Minecraft-Console-Client/tools/pathing_theory/simulator.py

187 lines
7.5 KiB
Python
Raw Normal View History

from tools.pathing_theory.models import TheoryCase
from tools.pathing_theory.primitives import (
PLAYER_WIDTH,
TARGET_BLOCK_WIDTH,
can_reach_gap,
can_reach_gap_with_side_wall,
get_apex,
get_landing,
)
MAX_MOMENTUM_TICKS = 12
def _float_token(value: float) -> str:
return f"{value:.1f}".replace("-", "m").replace(".", "p")
def build_theory_cases() -> list[TheoryCase]:
cases: list[TheoryCase] = []
for sprint, movement_mode in [
(False, "walk"),
(True, "sprint"),
]:
for momentum_ticks in range(0, MAX_MOMENTUM_TICKS + 1):
apex_y, _ = get_apex(sprint=sprint, momentum_ticks=momentum_ticks)
for gap in range(0, 8):
for delta_y in [0.0, 1.0, -1.0, -2.0]:
ok, landing_x, needed_x = can_reach_gap(
gap_blocks=gap,
dy=delta_y,
sprint=sprint,
momentum_ticks=momentum_ticks,
)
subfamily = (
"flat"
if delta_y == 0.0
else "ascend"
if delta_y > 0.0
else "descend"
)
cases.append(
TheoryCase(
case_id=(
f"linear-{subfamily}-{movement_mode}-mm{momentum_ticks}"
f"-gap{gap}-dy{_float_token(delta_y)}"
),
family="linear",
subfamily=subfamily,
movement_mode=movement_mode,
momentum_ticks=momentum_ticks,
gap_blocks=gap,
delta_y=delta_y,
ceiling_height=None,
wall_width=None,
wall_offset=None,
expected_reachable=ok,
landing_x=landing_x,
apex_y=apex_y,
margin=None if landing_x is None else landing_x - needed_x,
)
)
for sprint, movement_mode in [
(False, "walk"),
(True, "sprint"),
]:
for momentum_ticks in range(0, MAX_MOMENTUM_TICKS + 1):
apex_y, _ = get_apex(sprint=sprint, momentum_ticks=momentum_ticks)
landing = get_landing(
sprint=sprint,
target_y=0.0,
landing_x_start=0.0,
momentum_ticks=momentum_ticks,
)
for wall_width in [1, 2, 3, 4]:
landing_x = None if landing is None else landing[0]
needed_x = wall_width + PLAYER_WIDTH
margin = None if landing_x is None else landing_x - needed_x
cases.append(
TheoryCase(
case_id=f"neo-neo-{movement_mode}-mm{momentum_ticks}-wall{wall_width}",
family="neo",
subfamily="neo",
movement_mode=movement_mode,
momentum_ticks=momentum_ticks,
gap_blocks=None,
delta_y=0.0,
ceiling_height=None,
wall_width=wall_width,
wall_offset=None,
expected_reachable=margin is not None and margin >= 0.0,
landing_x=landing_x,
apex_y=apex_y,
margin=margin,
)
)
for momentum_ticks in range(0, MAX_MOMENTUM_TICKS + 1):
for ceiling_height in [4.0, 3.0, 2.5, 2.0, 1.8125]:
apex_y, _ = get_apex(
sprint=True,
momentum_ticks=momentum_ticks,
ceiling_y=ceiling_height,
)
for gap in [1, 2, 3, 4]:
landing = get_landing(
sprint=True,
target_y=0.0,
landing_x_start=0.5 + gap,
momentum_ticks=momentum_ticks,
ceiling_y=ceiling_height,
landing_width=TARGET_BLOCK_WIDTH,
)
landing_x = None if landing is None else landing[0]
needed_x = 0.5 + gap - (PLAYER_WIDTH / 2.0)
margin = None if landing_x is None else landing_x - needed_x
cases.append(
TheoryCase(
case_id=(
f"ceiling-headhitter-sprint-mm{momentum_ticks}-gap{gap}"
f"-ceil{str(ceiling_height).replace('.', 'p')}"
),
family="ceiling",
subfamily="headhitter",
movement_mode="sprint",
momentum_ticks=momentum_ticks,
gap_blocks=gap,
delta_y=0.0,
ceiling_height=ceiling_height,
wall_width=None,
wall_offset=None,
expected_reachable=margin is not None and margin >= 0.0,
landing_x=landing_x,
apex_y=apex_y,
margin=margin,
)
)
# --- Side-wall jump family ---
for sprint, movement_mode in [
(False, "walk"),
(True, "sprint"),
]:
for momentum_ticks in range(0, MAX_MOMENTUM_TICKS + 1):
apex_y, _ = get_apex(sprint=sprint, momentum_ticks=momentum_ticks)
for wall_offset in [0, 1]:
for gap in range(0, 8):
for delta_y in [0.0, 1.0, -1.0, -2.0]:
ok, landing_x, needed_x = can_reach_gap_with_side_wall(
gap_blocks=gap,
dy=delta_y,
wall_offset=wall_offset,
sprint=sprint,
momentum_ticks=momentum_ticks,
)
subfamily = (
"flat"
if delta_y == 0.0
else "ascend"
if delta_y > 0.0
else "descend"
)
cases.append(
TheoryCase(
case_id=(
f"sidewall-{subfamily}-{movement_mode}-mm{momentum_ticks}"
f"-gap{gap}-dy{_float_token(delta_y)}-wo{wall_offset}"
),
family="sidewall",
subfamily=subfamily,
movement_mode=movement_mode,
momentum_ticks=momentum_ticks,
gap_blocks=gap,
delta_y=delta_y,
ceiling_height=None,
wall_width=None,
wall_offset=wall_offset,
expected_reachable=ok,
landing_x=landing_x,
apex_y=apex_y,
margin=None if landing_x is None else landing_x - needed_x,
)
)
return cases