happy-birds-cracker/tests/test_solver.py

128 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""求解器与棋盘模型的单元测试(不依赖 MaaFramework / 真机)。"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from hbc.board import Board, Cell, CellKind # noqa: E402
from hbc.solver import Solver, Swap # noqa: E402
BRICK = -2
EMPTY = -1
def test_cell_types():
assert Cell.normal(3).is_swappable
assert not Cell.brick().is_swappable
assert not Cell.empty().is_swappable
assert Cell.brick().is_brick
assert Cell.empty().is_empty
def test_dynamic_rectangular_sizes():
for rows, cols in [(5, 9), (8, 8), (6, 7), (3, 3)]:
b = Board(rows, cols)
assert b.rows == rows and b.cols == cols
assert b.in_bounds(rows - 1, cols - 1)
assert not b.in_bounds(rows, cols)
def test_find_horizontal_match():
board = Board.from_colors([
[0, 0, 0, 1],
[2, 3, 4, 5],
])
matches = Solver().find_matches(board)
assert len(matches) == 1
assert matches[0].length == 3
assert matches[0].color == 0
def test_brick_breaks_the_line():
# 砖块 (#) 打断同色连线 -> 不应形成消除
board = Board.from_colors([
[0, 0, BRICK, 0],
])
assert not Solver().has_match(board)
def test_empty_breaks_the_line():
board = Board.from_colors([
[0, 0, EMPTY, 0],
])
assert not Solver().has_match(board)
def test_best_swap_makes_a_match():
# 把 (0,3) 的 0 与 (1,3) 的 X 交换? 这里构造:交换 (0,2)&(0,3) 形成三连
board = Board.from_colors([
[0, 0, 1, 0],
[2, 3, 0, 4],
])
# 交换 (0,2)=1 与 (1,2)=0 -> 第0行变 0 0 0 0前三连合法
solver = Solver()
result = solver.find_best_swap(board)
assert result is not None
assert result.cleared >= 3
def test_cannot_swap_brick_or_empty():
board = Board.from_colors([
[0, BRICK, 0],
[0, 0, 0],
])
solver = Solver()
# 砖块不可交换:尝试交换砖块应被判非法
assert solver.evaluate_swap(board, Swap(0, 1, 1, 1)) is None
def test_no_swap_available():
# 棋盘上任何交换都无法形成消除(三色互不相邻,且任意相邻交换都凑不出 3 连)
board = Board.from_colors([
[0, 1, 2],
])
assert Solver().find_best_swap(board) is None
def test_prefer_longer_match():
# 一处可形成 3 连,另一处可形成 4 连 —— 应优先 4 连(得分更高)
board = Board.from_colors([
[0, 0, 0, 5, 1, 1, 9, 1],
[9, 9, 0, 9, 9, 9, 1, 9],
])
solver = Solver()
best = solver.find_best_swap(board)
assert best is not None
# 至少应找到一个可行交换
assert best.score > 0
def test_horizontal_swipe_is_right_to_left():
"""水平交换必须从右往左滑(避免触发返回手势);竖直交换不受限制。"""
import sys as _sys
from pathlib import Path as _Path
_sys.path.insert(0, str(_Path(__file__).resolve().parents[1] / "src"))
from hbc.actuator import swap_to_swipe
from hbc.config import GridConfig
grid = GridConfig(0, 0, 500, 500, 5, 5)
# 求解器产生的水平交换通常是 (r,c)->(r,c+1),即左->右;应被翻转成右->左
x1, y1, x2, y2 = swap_to_swipe(Swap(2, 1, 2, 2), grid)
assert x1 > x2 and y1 == y2 # 起点在右,终点在左
# 即使给的是右->左,也应保持右->左
x1, y1, x2, y2 = swap_to_swipe(Swap(2, 3, 2, 2), grid)
assert x1 > x2
# 竖直交换x 相同,方向不限
x1, y1, x2, y2 = swap_to_swipe(Swap(1, 2, 2, 2), grid)
assert x1 == x2 and y1 != y2
if __name__ == "__main__":
import pytest
raise SystemExit(pytest.main([__file__, "-v"]))