"""求解器与棋盘模型的单元测试(不依赖 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"]))