如何计算棋盘游戏中每个移动的可逆id?

2024-04-23 17:39:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图建立一个6x6棋盘游戏使用pyhton。每个棋子可以上下左右四个方向移动。我使用的是为checker实现的遗留代码。你知道吗

------------------
6 |x x - - o o |
5 |x x - - o o |
4 |- - - - - - |
3 |- - - - - - |
2 |o o - - x x |
1 |o o - - x x |
------------------
   a b c d e f 

我必须写一个函数,能够计算uniqe和可逆id为每个运动。例如,如果一个工件可以向所有方向移动,那么每个移动都应该有不同的id

def calc_move_id(x0, x1, y0, y1):
    """ Calculates move_id. 
    """
    # directions = (1, 0), (0, 1), (-1, 0), (0, -1)
    # x0, y0 -> start point 
    # x1, y1 -> destination point
    dx, dy = x1 - x0, y1 y0
    direction = 0
    if dx > 0 and dy < 1:
        direction = 0
    elif dx < 1  and dy > 0:
        direction = 1
    elif dx < 0 and dy < 1:
        direction = 2
    else:
        direction = 3
    start = int((8 * self.y0 + self.x0) / 2)  # 1d-index of black squares
    length = abs(dx)
    vector = direction + (length - 1) * 4
    move_id = (vector << 5) | start
    return move_id

def parse_move(move_id):
    """ @see calc_move_id() """
    start = action & 31  # start/from
    action = action >> 5
    vector = action
    length = int(vector / 4) + 1
    direction_id = vector % 4
    direction = Move.__directions[direction_id]
    x0, y0 = (start % 4) * 2, int(start / 4)
    if y0 % 2 == 1:
        x0 += 1
    x1, y1 = x0 + direction[0] * length, y0 + direction[1] * length
    assert (
            0 <= x0
            and x0 < 6
            and 0 <= x1
            and x1 < 6
            and 0 <= y0
            and y0 < 6
            and 0 <= y1
            and y1 < 6
    ), ("Illegal action: " + str(action) + "=>" + str((x0, y0, x1, y1)))
    return (x0, x1, y0, y1)

上面的代码不起作用,因为parse\u move函数中的throw断言错误。 我怎样才能做到这一点?我应该用什么?(例如解码、编码、按位、位掩码实现)


Tags: andidmoveactionstartlengthintx1
2条回答

如果需要将x1,y1 -> x2,y2编码为可以反转的单个值,可以使用struct模块将4个字节编码为二进制字符串,然后可以将其转换为无符号int

import struct
def move_id(x1,y1,x2,y2):
    # encode the 4 bytes into a binary string eg '\x04\x05\x06\x05'
    encoded_bytes = struct.pack('bbbb',*[x1,y1,x2,y2])
    # then convert the string back into a single int
    return struct.unpack("I",encoded_bytes)[0]

def decode_move(encoded_move):
    return struct.unpack("bbbb",struct.pack("I",*[encoded_move,]))

print(move_id(1,2,3,4)) # 67305985
print(decode_move(67305985)) #[1,2,3,4]

您可以为x0保留三位,为y0保留三位,一位用于移动是水平还是垂直,另一位用于沿该轴移动是“向前”还是“向后”。你知道吗

def calc_move_id(x0, x1, y0, y1):
    return x0*32 + y0*4 + (x1-x0+y1-y0+1) + abs(x1-x0)

def parse_move(move_id):
    x0 = move_id//32
    y0 = (move_id//4) % 8
    delta = (move_id & 2) - 1
    return (x0, x0+delta, y0, y0) if move_id % 2 else (x0, x0, y0, y0+delta)

这是假设两个方法都是用有效参数调用的。你知道吗

相关问题 更多 >