当前位置: 首页 > 知识库问答 >
问题:

我怎么知道一个国王在棋盘上移动而不去对岸的所有有效位置

裴心思
2023-03-14

所以我有一个棋盘,表示为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是King当前所在的正方形的编号。

如果国王不在棋盘边缘,这一点就行了。

但是,如果国王位于右下角的方块上,即数字63,则函数会将数字56的左下角方块作为国王移动的有效位置。

有没有什么有效的方法可以知道国王正在走向另一个边缘,这不是一个有效的举动?

我几乎所有的作品都有同样的问题,功能允许作品放在棋盘的另一边,但我认为金的运动是最简单的问题。

共有2个答案

曾枫
2023-03-14

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

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]
庞安晏
2023-03-14

1D列表比2D 8x8列表快得多,所以我喜欢您使用这种方法。

处理此问题的方法是使用10x12板,其中底部和顶部有额外的2行,左侧和右侧有额外的列:

然后在生成移动函数中,您可以简单地检查您正在查看的方块是否在棋盘内。如果不是,您将跳到循环中的下一个方块。

请阅读更多关于它的https://www.chessprogramming.org/10x12_Board.它也是一个伟大的网站,一般关于国际象棋编程的信息。

 类似资料:
  • 好的,我在网上读了很多东西,大多数都是使用不带unsigned int的Java。我正在研究带有unsigned int的Objective-C。 让我们考虑以下场景。 董事会是这样的: 位于左下方,是最低有效位,位于右上角,是最高有效位。 我已经为棋盘上所有位置的所有棋子的移动构建了位掩码。 假设以下简单情况: 比赛就要开始了。所有部件都处于初始位置 用户试图将骑士从移动到 显然,这种移动是不可

  • 我正在尝试使用 Jolt 转换来转换 JSON,在这里寻找一些输入。我正在尝试将所有级别中的所有项目放入一个数组中。 我的目标是获得一个包含所有项目的数组,而不知道我在json中有多少个级别。 这是我的输入和预期输出: 如果我有三个等级: 输入: 预期产出: 如果我有两个级别: 输入: 预期产出: 我试着写下这样的话: 结果为空,如果我单独运行每个转换,我会在适用时得到结果。你能帮我写一个简单的规

  • 我正在做一个项目,在那里我采取一个象棋棋盘位置(FEN字符串转换成二进制)&它的评估分数,并将它馈送给一个神经网络。我的目的是让神经网络区分好的和坏的仓位。 我是如何编码位置的:国际象棋中有12个独特的棋子,即棋子,棋子,骑士,主教,王后和国王,白棋和黑棋一样。我使用4位编码每一个片段,其中0000表示一个空的正方形。所以64个方块被编码成256位,我用另外6位来表示游戏状态,比如轮到谁移动,国王

  • 问题内容: 我从java2s.com下载了servlet-api.jar的副本。我怎么知道它是什么版本?该网站上没有参考。 编辑 啊。道歉。当我双击得到的jar中的MANIFEST.MF文件时,我应该已经列出了写字板输出的内容: 如您所见,它没有告诉我版本,因此是问题所在。 问题答案: 您可以从META-INF中获取它,也可以使用Win rar或类似的归档工具来探索jar文件的内容。 我个人更喜欢

  • 我正在下国际象棋,除了一件事,我几乎得到了所有的东西:我需要使棋手不可能将棋子移动到棋盘上。我很难解决这个问题。 我现在用伪代码生成的有效移动是:类getMoveLocations(我定义了一个位置为国际象棋中的一个方块):如果这个位置在边界内,这个位置的棋子是敌人的棋子,并且模拟的移动不会导致棋盘被检查,然后将该位置添加到工件可以移动到的可能位置。 问题是我如何检查棋盘是否“在检查中”。在我的代