File size: 2,108 Bytes
4be6a52 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | from dataclasses import replace
import pytest
from stackcraft import engine
from stackcraft.engine import new_game, place
from stackcraft.expert import SearchExpert
from stackcraft.players import observe
def test_expert_never_queries_hidden_sequence(monkeypatch) -> None:
observation = observe(new_game(43))
def forbidden(*args, **kwargs):
raise AssertionError("expert queried hidden future")
monkeypatch.setattr(engine, "piece_at", forbidden)
monkeypatch.setattr(engine, "step", forbidden)
expert = SearchExpert()
values = expert.action_values(observation)
assert set(values) == {action.id for action in observation.legal_actions}
assert expert.choose(observation).action_id == max(values, key=lambda a: values[a])
def test_search_is_independent_of_real_seed_and_turn() -> None:
state = new_game(3)
alternate = replace(state, seed=654123, piece_index=999)
assert SearchExpert().action_values(observe(state)) == SearchExpert().action_values(
observe(alternate)
)
def test_unplaceable_preview_has_declared_penalty() -> None:
state = new_game(0)
board = ((1, 1, 1, 1, 0, 1, 1, 1, 1, 1),) + state.board[1:]
observation = observe(replace(state, board=board, current="I", next_piece="O"))
assert len(observation.legal_actions) == 1
action = observation.legal_actions[0]
_, cleared = place(board, "I", action)
assert cleared == 0
assert SearchExpert().action_values(observation) == {action.id: -10000}
def test_ties_follow_engine_order(monkeypatch) -> None:
observation = observe(new_game(0))
expert = SearchExpert()
monkeypatch.setattr(
expert, "action_values", lambda _: {a.id: 0 for a in observation.legal_actions}
)
assert expert.choose(observation).action_id == observation.legal_actions[0].id
def test_empty_actions_are_rejected() -> None:
observation = replace(observe(new_game(0)), legal_actions=())
assert SearchExpert().action_values(observation) == {}
with pytest.raises(ValueError, match="no legal actions"):
SearchExpert().choose(observation)
|