You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

游戏棋盘当前状态保存与下一步可行状态生成技术求助

棋盘状态保存与可行状态生成方案

一、先优化棋盘的存储方式

你现在把棋盘拆成单独的row1~row5列表,后续操作会很麻烦。建议直接用二维列表存储整个棋盘,不管是保存状态还是遍历操作都更方便。

优化后的初始化代码

def initialize(lines):
    board = []
    for line in lines:
        # 去掉每行首尾的换行、空格,再转成列表
        cleaned_line = line.strip()
        board.append(list(cleaned_line))
    return board

调用后会得到一个5行4列的二维列表,比如初始状态就是:

[
 ['3', '1', '1', '3'],
 ['3', '1', '1', '3'],
 ['3', '2', '2', '3'],
 ['3', '4', '4', '3'],
 ['4', '0', '0', '4']
]

要保存当前状态,必须用深拷贝,因为直接赋值是引用传递,修改新列表会影响原状态。用copy模块的deepcopy就行:

import copy

current_state = initialize(Lines)
saved_state = copy.deepcopy(current_state)

二、生成所有可行的下一步状态

核心逻辑是:先找到所有空白格(0),然后检查空白格四周的棋子是否符合移动规则,符合的话就生成新的棋盘状态。

先明确各棋子的移动规则

  • 棋子1:2x2大棋子,需整体移动,移动方向上要有足够的空白区域容纳它
  • 棋子2:水平1x2,只能左右移动,移动时两个格子整体移动
  • 棋子3:垂直1x2,只能上下移动,移动时两个格子整体移动
  • 棋子4:单格,可上下左右移动,只要相邻是空白格就能交换位置

实现代码示例

import copy

def get_all_next_states(current_board):
    next_states = []
    rows = len(current_board)
    cols = len(current_board[0]) if rows else 0
    
    # 先找到所有空白格的坐标
    empty_pos = [(i, j) for i in range(rows) for j in range(cols) if current_board[i][j] == '0']
    
    for empty_i, empty_j in empty_pos:
        # 检查空白格的上下左右四个方向
        directions = [(-1,0), (1,0), (0,-1), (0,1)]
        for di, dj in directions:
            piece_i = empty_i + di
            piece_j = empty_j + dj
            # 确保棋子坐标在棋盘范围内
            if not (0 <= piece_i < rows and 0 <= piece_j < cols):
                continue
            piece_type = current_board[piece_i][piece_j]
            if piece_type == '0':
                continue  # 跳过空白格
            
            new_board = copy.deepcopy(current_board)
            can_move = False
            
            # 处理单格棋子4
            if piece_type == '4':
                # 直接和空白格交换位置
                new_board[empty_i][empty_j] = '4'
                new_board[piece_i][piece_j] = '0'
                can_move = True
            
            # 处理2x2的大棋子1
            elif piece_type == '1':
                # 先定位大棋子的左上角坐标(它占据4个格子)
                ones = [(x,y) for x in range(rows) for y in range(cols) if current_board[x][y] == '1']
                min_i = min(x for x,y in ones)
                min_j = min(y for x,y in ones)
                # 尝试向下移动:需要下方两行对应列是空白
                if di == 1:
                    if min_i + 2 < rows and current_board[min_i+2][min_j] == '0' and current_board[min_i+2][min_j+1] == '0':
                        # 清除原位置的1,设置新位置的1
                        for x,y in ones:
                            new_board[x][y] = '0'
                        new_board[min_i+1][min_j] = '1'
                        new_board[min_i+1][min_j+1] = '1'
                        new_board[min_i+2][min_j] = '1'
                        new_board[min_i+2][min_j+1] = '1'
                        can_move = True
                # 同理可实现向上、向左、向右的移动逻辑
            
            # 处理水平双格棋子2
            elif piece_type == '2':
                # 找到同个棋子的另一个格子(水平方向)
                other_j = piece_j + 1 if dj == -1 else piece_j - 1
                if 0 <= other_j < cols and current_board[piece_i][other_j] == '2':
                    # 向左移动:空白格在棋子左侧,且相邻位置也是空白
                    if dj == 1 and current_board[piece_i][piece_j-1] == '0':
                        new_board[piece_i][piece_j-1] = '2'
                        new_board[piece_i][other_j-1] = '2'
                        new_board[piece_i][piece_j] = '0'
                        new_board[piece_i][other_j] = '0'
                        can_move = True
                    # 向右移动:空白格在棋子右侧,且相邻位置也是空白
                    elif dj == -1 and current_board[piece_i][other_j+1] == '0':
                        new_board[piece_i][piece_j+1] = '2'
                        new_board[piece_i][other_j+1] = '2'
                        new_board[piece_i][piece_j] = '0'
                        new_board[piece_i][other_j] = '0'
                        can_move = True
            
            # 处理垂直双格棋子3
            elif piece_type == '3':
                # 找到同个棋子的另一个格子(垂直方向)
                other_i = piece_i + 1 if di == -1 else piece_i - 1
                if 0 <= other_i < rows and current_board[other_i][piece_j] == '3':
                    # 向上移动:空白格在棋子上方,且相邻位置也是空白
                    if di == 1 and current_board[piece_i-1][piece_j] == '0':
                        new_board[piece_i-1][piece_j] = '3'
                        new_board[other_i-1][piece_j] = '3'
                        new_board[piece_i][piece_j] = '0'
                        new_board[other_i][piece_j] = '0'
                        can_move = True
                    # 向下移动:空白格在棋子下方,且相邻位置也是空白
                    elif di == -1 and current_board[other_i+1][piece_j] == '0':
                        new_board[piece_i+1][piece_j] = '3'
                        new_board[other_i+1][piece_j] = '3'
                        new_board[piece_i][piece_j] = '0'
                        new_board[other_i][piece_j] = '0'
                        can_move = True
            
            # 避免重复状态,添加到列表
            if can_move and new_board not in next_states:
                next_states.append(new_board)
    
    return next_states

调用示例

# 从文件读取初始棋盘
with open('board.txt', 'r') as f:
    Lines = f.readlines()

current_board = initialize(Lines)
next_states = get_all_next_states(current_board)

# 打印所有可行状态
for idx, state in enumerate(next_states):
    print(f"可行状态 {idx+1}:")
    for row in state:
        print(''.join(row))
    print("---")

调试建议

  1. 先测试单格棋子4的移动逻辑,确认能正确生成新状态
  2. 再逐步完善大棋子1和双格棋子2、3的移动逻辑,每写一部分就调试一次
  3. 可以打印中间过程的坐标,帮助排查移动逻辑的问题

内容的提问来源于stack exchange,提问作者new_to_python

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:20:20