Пример #1
0
def test_validate_place_tile_unnecessary_loop() -> None:
    rc = RuleChecker()
    bs = BoardState()

    bs = bs.with_live_players(
        bs.live_players.set("red", (BoardPosition(2, 0), Port.RightBottom))
    )
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 0))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 1))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(3, 1))
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(4), "red"))
    assert r.is_ok()
    assert r.value()
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(5), "red"))
    assert r.is_ok()
    assert r.value()
    r = rc.is_move_suicidal(bs, IntermediateMove(index_to_tile(5).rotate(), "red"))
    assert r.is_ok()
    assert not r.value()

    r2 = rc.validate_move(
        bs,
        [index_to_tile(5), index_to_tile(4)],
        IntermediateMove(index_to_tile(4), "red"),
    )
    assert r2.is_error()
    assert (
        r2.error()
        == "player chose a loopy move when this does not create a loop: Tile(idx=5, edges=[(0, 7), (1, 5), (2, 6), (3, 4)])"
    )
Пример #2
0
def test_validate_place_tile_loop_someone_else() -> None:
    rc = RuleChecker()
    bs = BoardState()

    bs = bs.with_live_players(
        bs.live_players.set("red", (BoardPosition(2, 0), Port.RightBottom))
    )
    bs = bs.with_live_players(
        bs.live_players.set("white", (BoardPosition(4, 0), Port.LeftTop))
    )
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 0))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 1))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(3, 1))
    bs = bs.with_tile(index_to_tile(2), BoardPosition(4, 0))

    # The move is suicidal for red but not for white
    r = rc.is_move_suicidal(bs, IntermediateMove(index_to_tile(13).rotate(), "white"))
    assert r.is_ok()
    assert not r.value()
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(13).rotate(), "red"))
    assert r.is_ok()
    assert r.value()
    # But it does create a loop no matter who places it
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(13).rotate(), "white"))
    assert r.is_ok()
    assert r.value()
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(13).rotate(), "red"))
    assert r.is_ok()
    assert r.value()
    # And thus it is illegal
    r = rc.is_move_illegal(bs, IntermediateMove(index_to_tile(13).rotate(), "white"))
    assert r.is_ok()
    assert r.value()
    r = rc.is_move_illegal(bs, IntermediateMove(index_to_tile(13).rotate(), "red"))
    assert r.is_ok()
    assert r.value()

    # Red and white are both not allowed to place the move since it causes a loop
    r2 = rc.validate_move(
        bs,
        [index_to_tile(13).rotate().rotate(), index_to_tile(6)],
        IntermediateMove(index_to_tile(13).rotate(), "white"),
    )
    assert r2.is_error()
    assert (
        r2.error()
        == "player chose a loopy move when this does not create a loop: Tile(idx=13, edges=[(0, 7), (1, 2), (3, 5), (4, 6)])"
    )
    r2 = rc.validate_move(
        bs,
        [index_to_tile(13).rotate().rotate(), index_to_tile(6)],
        IntermediateMove(index_to_tile(13).rotate(), "red"),
    )
    assert r2.is_error()
    assert (
        r2.error()
        == "player chose a loopy move when this does not create a loop: Tile(idx=13, edges=[(0, 7), (1, 2), (3, 5), (4, 6)])"
    )
Пример #3
0
def test_is_move_suicidal_loop() -> None:
    rc = RuleChecker()
    bs = BoardState()

    bs = bs.with_live_players(
        bs.live_players.set("red", (BoardPosition(2, 0), Port.RightBottom))
    )
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 0))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 1))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(3, 1))
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(4), "red"))
    assert r.is_ok()
    assert r.value()
Пример #4
0
def test_validate_place_tile_forced_loop_or_suicide() -> None:
    rc = RuleChecker()
    bs = BoardState()

    bs = bs.with_live_players(
        bs.live_players.set("red", (BoardPosition(2, 0), Port.RightBottom))
    )
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 0))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(2, 1))
    bs = bs.with_tile(index_to_tile(4), BoardPosition(3, 1))
    r = rc.move_creates_loop(bs, IntermediateMove(index_to_tile(4), "red"))
    assert r.is_ok()
    assert r.value()
    r = rc.is_move_suicidal(bs, IntermediateMove(index_to_tile(7), "red"))
    assert r.is_ok()
    assert r.value()

    r2 = rc.validate_move(
        bs,
        [index_to_tile(7), index_to_tile(4)],
        IntermediateMove(index_to_tile(4), "red"),
    )
    assert r2.is_error()
    assert (
        r2.error()
        == "player chose a loopy move when this does not create a loop: Tile(idx=7, edges=[(0, 3), (1, 6), (2, 5), (4, 7)])"
    )

    r3 = rc.validate_move(
        bs,
        [index_to_tile(7), index_to_tile(4)],
        IntermediateMove(index_to_tile(7), "red"),
    )
    assert r3.is_error()
    assert (
        r3.error()
        == "player chose a suicidal move when this does not cause a suicide: Tile(idx=4, edges=[(0, 7), (1, 2), (3, 4), (5, 6)])"
    )