我正在写一个程序,应该能够读取和解析国际象棋的动作(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
)...我还如何标记正则表达式的一部分,以便在检测到它时,我得到所有的信息?我试图阅读关于它的文档,但没有弄清楚。
有什么建议吗?
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
等等
/^([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();
});
}
});
});
表示法中的是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...)这应该能证明这次行动是正确的。语法类似于: 目前,我可以移动任何白色树懒或树懒上有一个黑色的部分(但我不能吃我自己),反之亦然。 我想我使用的是而不是列表列表这一事实使事情变得更加困难。我真的迷路了。这将是惊人的,如果你可以帮助我