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

国际象棋移动的正则表达式帮助(SAN)

戚良弼
2023-03-14

我正在写一个程序,应该能够读取和解析国际象棋的动作(SAN)。

下面是一个可能被接受的动作的例子:

e4
Nf3
Nbd2
Nb1c3
R1a3
d8=Q
exd5
Nbxd2
...

我首先编写了NFA,然后将其转换为语法,然后将其转换为正则表达式。

按照我的惯例,情况就是这样

pln + plxln + plnxln + plnln + plln + pxln + lxln=(B+R+Q+N) + lxln + lnxln=(B+R+Q+N) + lnxln + lnln=(B+R+Q+N) + lnln + ln=(B+R+Q+N) + ln + pnxln + pnln

哪里:

p是set{B, R, Q, N, K}的字符(或者认为是(B R Q N K)=[BRQNK]

l[a-h]间隔中的一个字符(区分大小写)

n[1-8]间隔中的一个数字

表示联合操作。。。如果我没弄错的话,(BRQN)在regex的编程语言中是[BRQN]

=只是一个普通字符。。。在国际象棋中,它用于提升(例如e8=Q)

x也是一个普通字符。。。当你在那个位置移动你的棋子时,你正在拿对手的棋子。

/:比如数学

我试图解析第一部分pln为:[BRQN][a-h][1-8]在一个在线java正则表达式测试器中,并为像Nf3这样的移动而工作。我不知道如何为复合表达式做联合的事情(如pln plxln)...我还如何标记正则表达式的一部分,以便在检测到它时,我得到所有的信息?我试图阅读关于它的文档,但没有弄清楚。

有什么建议吗?

共有3个答案

殳越
2023-03-14
Re: /^([NBRQK])?([a-h])?([1-8])?(x)?([a-h][1-8])(=[NBRQK])?(\+|#)?$|^O-O(-O)?$/

这既有包容性不足,也有包容性过高。

它排除了可能的合法移动O-O,O-O-O,O-O#和O-O-O#。

它包含许多永远不合法的字符串:e8=K、Kaa4、Nf5=B、Qa1xb7

等等

支铭晨
2023-03-14

/^([NBRQK])?([a-h])?([1-8])?(x) ??([a-h][1-8])(=[NBRQK])?(\ |#)?$|^O-O(-O)$/

.

.

.

.

这是对2599例进行的单元测试。单元测试见下文

describe('Importer/Game', function() {
    let Importer, Game;
    beforeEach(function() {
        Importer = require(`${moduleDir}/import`).Importer;
        Game = require(`${moduleDir}/import`).Game;
    });
    describe('moveRegex', function() {
        describe('non-castling', function() {
            //  ([NBRQK])?  ([a-h])?   ([1-8])?   (x)?     ([a-h][1-8]) (=[NBRQK])? (+|#)?/
            //  unitType?   startFile? startRank? capture? end          promotion?  checkState?
            for(let unitType of ['', 'N', 'B', 'R', 'Q', 'K']) {
                for(let startFile of ['', 'b']) {
                    for(let startRank of ['', '3']) {
                        for(let capture of ['', 'x']) {
                            for(let promotion of ['', '=Q']) {
                                for(let checkState of ['', '+', '#']) {
                                    //TODO: castling
                                    const dest = 'e4';
                                    const san = unitType + startFile + startRank + capture + dest + promotion + checkState;
                                    testPositive(san);
                                    //TODO: negative substitutions here.
                                    testNagative('Y'      + startFile + startRank + capture + dest + promotion + checkState);
                                    testNagative(unitType + 'i'       + startRank + capture + dest + promotion + checkState);
                                    testNagative(unitType + startFile + '9'       + capture + dest + promotion + checkState);
                                    testNagative(unitType + startFile + startRank + 'X'     + dest + promotion + checkState);
                                    testNagative(unitType + startFile + startRank + capture + 'i9' + promotion + checkState);
                                    // testNagative(unitType + startFile + startRank + capture + ''   + promotion + checkState);
                                    testNagative(unitType + startFile + startRank + capture + dest + '='       + checkState);
                                    testNagative(unitType + startFile + startRank + capture + dest + 'Q'       + checkState);
                                    testNagative(unitType + startFile + startRank + capture + dest + promotion + '++');
                                }
                            }
                        }
                    }
                }
            }
        });
        describe('castling', function() {
            testPositive('O-O');
            testPositive('O-O-O');
            testNagative('OOO');
            testNagative('OO');
            testNagative('O-O-');
            testNagative('O-O-O-O');
            testNagative('O');
        });
        function testPositive(san) {
            it(`should handle this san: ${san}`, function(done) {
                const matches = san.match(Importer.moveRegex);
                assert(matches);
                done();
            });
        }
        function testNagative(san) {
            it(`should not match this: ${san}`, function(done) {
                const matches = san.match(Importer.moveRegex);
                assert(!matches);
                done();
            });
        }
    });
});

施利
2023-03-14

表示法中的是regex中的|。所以你可以用正则表达式

[BRQNK][a-h][1-8]|[BRQNK][a-h]x[a-h][1-8]|[BRQNK][a-h][1-8]x[a-h][1-8]|[BRQNK][a-h][1-8][a-h][1-8]|[BRQNK][a-h][a-h][1-8]|[BRQNK]x[a-h][1-8]|[a-h]x[a-h][1-8]=(B+R+Q+N)|[a-h]x[a-h][1-8]|[a-h][1-8]x[a-h][1-8]=(B+R+Q+N)|[a-h][1-8]x[a-h][1-8]|[a-h][1-8][a-h][1-8]=(B+R+Q+N)|[a-h][1-8][a-h][1-8]|[a-h][1-8]=(B+R+Q+N)|[a-h][1-8]|[BRQNK][1-8]x[a-h][1-8]|[BRQNK][1-8][a-h][1-8]

这显然有点丑陋。我能想到两种可能的方法让它变得更好:

  • 使用COMMENTS标志,可以添加空白。
  • 以更好的方式将这些可能性结合在一起。例如,[BRQNK][a-h]x[a-h][1-8]|[BRQNK][a-h][1-8]x[a-h][1-8]可以重写为[BRQNK][a-h][1-8]?x[a-h][1-8].

我还知道java中没有的另一个改进。(可能不是很多语言,但可以用Perl实现。)子表达式(?1)(同样地(?2),等等)有点像\1,只是它没有匹配匹配第一个捕获组的确切字符串,而是匹配可能匹配该捕获组的任何字符串。换句话说,这相当于再次写出捕获组。因此,您可以(在Perl中)将第一个[BRQNK]替换为([BRQNK]),然后将所有后续出现的内容替换为(?1)

 类似资料:
  • 上面的代码显示了一个可以上下移动的部分的示例。这不是一个有效的棋步。所以,如果我要移动一个皇后,我该怎么做呢?我们只是假设我们已经有了一个矩阵(x,y)8×8的板。

  • 我已经有一个Board对象,包含一个碎片列表。Piece是一个抽象类,有一个位置(x,y)和一个颜色(黑色或白色)。然后是King、Queen、Knight这三个类,实现了Piece类。 谢谢

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

  • DreamChess 是一款开放源码、跨平台(可在 Windows、Mac OS X 及 Linux 上运行)的 3D 国际象棋游戏。该游戏包含自身的引擎 Dreamer,提供各种国际象棋棋盘,并具有背景音乐及声效等其他附属功能。

  • 问题内容: 我有以下示例字符串 我只对 test6IAmInterestedIn 感兴趣,它位于第四个斜杠之后,可以包含3个字符,多个字母并以3个数字结尾,即。 我想在上述正则表达式中添加的内容是,我总是在匹配的第四个斜杠之后选择字符串。我该怎么办? 问题答案: 你可以试试这个演示 哪里 匹配包含正斜杠的4个块 捕捉您想要的图案

  • 我是编程的新手,我正在尝试实现一个小的象棋游戏。 我目前正在为每件作品的验证移动而挣扎。 字典是: 我在每个子类中都创建了一个函数(Pawn,Rook,Queen...)这应该能证明这次行动是正确的。语法类似于: 目前,我可以移动任何白色树懒或树懒上有一个黑色的部分(但我不能吃我自己),反之亦然。 我想我使用的是而不是列表列表这一事实使事情变得更加困难。我真的迷路了。这将是惊人的,如果你可以帮助我