【问题标题】:How do I know all valid positions for a King to move on chess board without going to the opposite side我如何知道国王在棋盘上移动而不走到对面的所有有效位置
【发布时间】:2022-01-20 16:19:30
【问题描述】:

所以我有一个国际象棋棋盘,表示为一个大小为 64 的数组,左上角为 0,右下角为 63。我有这个函数,它给出了国王所有可能的移动。

current_pos = i
arr = np.array([i-9, i-8, i-7, i-1, i+1, i+7, i+8, 1+9])
return arr

.
.
.

if selected position is in arr:
    move king

其中 i 是国王当前所在方格的编号。

如果国王不在棋盘边缘,则此方法有效。

但如果国王在右下角,即 63 号,该函数将左下角 56 号作为国王移动的有效位置。

是否有任何有效的方法可以知道国王将走向另一边并且不是有效的举动?

我几乎所有的棋子都有同样的问题,该功能允许棋子在棋盘的另一侧移动,但我认为国王的移动是最简单的问题。

【问题讨论】:

  • 是否有理由使用单个长度为 64 的列表而不是 8x8 列表或 numpy 数组?
  • “我有这个功能”也许你可以把它包括在内,这样我们就可以看到它并提出建议......
  • @JonSG 前 3 行是函数 I,它返回国王的所有有效移动。下面是查看移动是否有效的伪代码
  • 另外,我正在考虑更改棋盘的表示并使用 (x, y) 坐标,因为我晚了一点才知道将棋盘表示为数字数组是没有好处的。我只是想看看是否有办法解决我没想过的问题

标签: python-3.x chess


【解决方案1】:

一维列表比二维 8x8 列表快得多,所以我喜欢您使用这种方法。

处理方法是使用 10x12 板,其中底部和顶部多出 2 行,左右多出一列:

然后在您的生成移动功能中,您只需检查您正在查看的方块是否在棋盘内。如果不是,则跳到循环中的下一个方块。

请在https://www.chessprogramming.org/10x12_Board 上阅读更多相关信息。它也是一个很好的网站,提供有关国际象棋编程的一般信息。

【讨论】:

    【解决方案2】:

    这是使用表查找的一种方法。

    代码

    piece_offsets = {
        'n': [-17, -15, -10, -6, 6, 10, 15, 17],
        'b': [ -9,  -7,  9, 7],
        'r': [ -8,  -1,  8, 1],
        'q': [ -9,  -8, -7, -1, 9,  8,  7,  1],
        'k': [ -9,  -8, -7, -1, 9,  8,  7,  1]
    }
    
    sqdist = [[0 for x in range(64)] for y in range(64)]
    
    pseudo_legal = {    
        'n': [[] for y in range(64)],
        'b': [[] for y in range(64)],
        'r': [[] for y in range(64)],    
        'q': [[] for y in range(64)],
        'k': [[] for y in range(64)],
    }
    
    
    def distance(sq1, sq2):
       file1 = sq1 & 7
       file2 = sq2 & 7
       rank1 = sq1 >> 3
       rank2 = sq2 >> 3
       rank_distance = abs(rank2 - rank1)
       file_distance = abs(file2 - file1)
       return max(rank_distance, file_distance)
    
    
    def print_board():
        for i in range(64):
            print(f'{i:02d} ', end='')
            if (i+1)%8 == 0:
                print()
    
    
    def on_board(s):
        return s >= 0 and s < 64
    
    
    def init_board():    
        for sq1 in range(64):
            for sq2 in range(64):
                sqdist[sq1][sq2] = distance(sq1, sq2)
                
        for pt in ['n', 'b', 'r', 'q', 'k']:
            for s in range(64):
                for offset in piece_offsets[pt]:
                    to = s + offset
                    if pt in ['k', 'n']:
                        if on_board(to) and sqdist[s][to] < 4:
                            pseudo_legal[pt][s].append(to)
                    else:  # sliders
                        s1 = s
                        while True:
                            to1 = s1 + offset
                            if on_board(to1) and sqdist[s1][to1] < 4:
                                pseudo_legal[pt][s].append(to1)
                                s1 = to1
                            else:
                                break
    
    
    def main():
        init_board()  # build sqdist and pseudo_legal_to tables
        
        print_board()
        print()  
        
        for pt in ['n', 'b', 'r', 'q', 'k']:
            for s in [0, 63, 36]:
                print(f'pt: {pt}, from: {s}: to: {pseudo_legal[pt][s]}')
            print()
            
        # pseudo_legal_sq = pseudo_legal['b'][61]
        # print(pseudo_legal_sq)
        
        
    main()
    

    输出

    00 01 02 03 04 05 06 07 
    08 09 10 11 12 13 14 15 
    16 17 18 19 20 21 22 23 
    24 25 26 27 28 29 30 31 
    32 33 34 35 36 37 38 39 
    40 41 42 43 44 45 46 47 
    48 49 50 51 52 53 54 55 
    56 57 58 59 60 61 62 63 
    
    pt: n, from: 0: to: [10, 17]
    pt: n, from: 63: to: [46, 53]
    pt: n, from: 36: to: [19, 21, 26, 30, 42, 46, 51, 53]
    
    pt: b, from: 0: to: [9, 18, 27, 36, 45, 54, 63]
    pt: b, from: 63: to: [54, 45, 36, 27, 18, 9, 0]
    pt: b, from: 36: to: [27, 18, 9, 0, 29, 22, 15, 45, 54, 63, 43, 50, 57]
    
    pt: r, from: 0: to: [8, 16, 24, 32, 40, 48, 56, 1, 2, 3, 4, 5, 6, 7]
    pt: r, from: 63: to: [55, 47, 39, 31, 23, 15, 7, 62, 61, 60, 59, 58, 57, 56]
    pt: r, from: 36: to: [28, 20, 12, 4, 35, 34, 33, 32, 44, 52, 60, 37, 38, 39]
    
    pt: q, from: 0: to: [9, 18, 27, 36, 45, 54, 63, 8, 16, 24, 32, 40, 48, 56, 1, 2, 3, 4, 5, 6, 7]
    pt: q, from: 63: to: [54, 45, 36, 27, 18, 9, 0, 55, 47, 39, 31, 23, 15, 7, 62, 61, 60, 59, 58, 57, 56]
    pt: q, from: 36: to: [27, 18, 9, 0, 28, 20, 12, 4, 29, 22, 15, 35, 34, 33, 32, 45, 54, 63, 44, 52, 60, 43, 50, 57, 37, 38, 39]
    
    pt: k, from: 0: to: [9, 8, 1]
    pt: k, from: 63: to: [54, 55, 62]
    pt: k, from: 36: to: [27, 28, 29, 35, 45, 44, 43, 37]
    

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      相关资源
      最近更新 更多