- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在制作游戏国际象棋,几乎得到了所有东西,但只有一件事:我需要制作它,这样玩家就不可能将棋子移动到检查中。我在解决这个问题时遇到了麻烦。
我现在用伪代码生成有效移动的是:getMoveLocations 类(我将位置定义为国际象棋中的那些方 block 之一):如果这个位置在边界内,并且这个位置的棋子是敌人的,并且模拟的移动不会导致棋盘被检查,那么将这个位置添加到棋子可以移动到的可能位置。
问题在于我如何检查棋盘是否“处于检查状态”。在我的代码中,它通过收集所有敌人的移动位置,并查看这些敌人的移动位置是否与国王的位置重叠,将棋盘视为处于“检查”状态。
不幸的是,这是无限循环开始的地方;为了收集所有敌人的电影位置,每个敌人可能的移动位置需要确保其移动不会导致其受到检查。为了确保没有敌人的位置在检查中,它必须收集所有盟友的潜在移动位置等。
我对如何获得有效算法感到困惑。尽管我的代码“理论上”具有逻辑意义,但它无法实现。我感兴趣的是 A) 一种更有效的方法来实现检查所有合法移动的方法,或 B) 一种修复此无限循环的方法
最佳答案
有一种更有效的方法来确定一方是否处于被检查状态:您只需从国王向外扫描,看看是否找到可以攻击它的棋子。例如,从国王的位置,检查是否有敌方主教沿着对角线等。您根本不需要生成移动列表,因此不需要递归。这是一些伪代码:
function leftInCheck(board, sideToCheck) {
// one of the four rays for bishop/queen attacks
d := 0
while (king rank + d, king file + d) is on the board
piece := board[king rank + d][king file + d]
if piece is an enemy bishop or queen
return true
if piece is not an empty square // a piece blocks any potential
break // attack behind it so we can stop
d := d + 1
// do this for all the other forms of attack
...
return false
}
如您所见,有一些代码重复,但您可以缩短它。我将其保留原样,因此很容易理解。您可以通过生成伪合法移动来生成合法移动,就像您现在所做的那样,制作每一个,并省略那些让您检查上述子例程的移动。这自然具有顺路的额外优势。这是一些伪代码:
function legalMoves(board, sideToMove) {
moveList := empty
for each move in pseudoLegalMoves()
make(move)
if not leftInCheck(board, sideToMove)
moveList.add(move)
unmake(move) // you may not need this
return moveList
}
对于易位,您仍然需要检查国王和车之间的方格是否受到攻击。幸运的是,这很容易,因为您可以扩展上面的子例程来处理国王以外的方格。
我假设您没有使用位板或 0x88,而是使用简单的数组表示。这使得合法移动生成(没有中间的伪合法移动)变得有点困难,因为它需要非常快速地生成攻击图来确定固定的棋子。如果你雄心勃勃,这是一种可能性。
作为附加说明,我对这里的其他答案有些失望。而且我什至不会向任何想要编写好的移动生成器的人推荐我自己的答案(它仅适用于那些不熟悉国际象棋编程的人)。这是一个已经过彻底检查并具有众所周知的解决方案的主题,但正在引发原创想法。这当然没有错,但为什么要重新发明轮子,甚至更糟呢?查看well established methods of move generation .
关于java - 国际象棋 : Getting All Legal Chess Moves,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16803893/
我经常听到有人这样说 All JavaScript code is legal TypeScript code 或 TypeScript is a superset of JavaScript 但是当
如果为对象预留内存(例如,通过 union )但构造函数尚未被调用,调用对象的非静态方法之一是否合法,假设该方法不依赖于值任何成员变量? 我做了一些研究,发现了一些关于“变体成员”的信息,但找不到与此
更新! 请参阅下面我对 C# 规范的一部分的剖析;我想我一定遗漏了什么,因为对我来说,我在这个问题中描述的行为实际上违反了规范。 更新2! 好的,经过进一步思考,并根据一些评论,我想我现在明白发生了什
我有代码: #include template class> struct Foo { enum { n = 77 }; }; template class C> struct Foo {
int ar[] = { 1, 2, 3, }; 这段代码合法吗? (我的意图是) int ar[] = { 1, 2, 3 }; 最佳答案 是的,C89 和 GNU89 中的初始化列表中都允许使用杂
我有一个 map View 被以下代码剪裁成一个圆圈。 roundMapView.layer.cornerRadius = roundMapView.frame.size.width/2
这个问题已经存在: Why sizeof(x++) does not increment the variable x value [duplicate] 关闭 9 年前。 给定以下代码,它在 C
在深入研究 MFC 时,我发现了这段代码: _AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL
我正在使用 MKMapSnapshotter 创建一个小型 MKMapView 的 UIImage 屏幕截图(并存储以备后用)。但我注意到的一件事是它从快照中删除了“合法”标签。 Here答案是删除“
在这个公认的人为设计的示例中,X 类型的右值在语句末尾按预期被销毁。但是,被销毁的对象仍然可以通过非常量引用“x”访问。这是合法的 C++ 吗?如果是这样,结果是未定义的还是未指定的?编译器不应该在这
这是一段显然不起作用的代码,因为在构造函数中向下转换“this”是非法的: #include class A { protected: virtual ~A() {} public:
考虑以下语句: int *pFarr, *pVarr; int farr[3] = {11,22,33}; int varr[3] = {7,8,9}; pFarr = &(farr
似乎只有向上滑动才能移除带动画的导航栏。我想让它褪色,就像在 Photos.app 中一样。 更改 alpha 最简单,但是 Apple's guidelines state : Prior to i
考虑一下这个相当无用的程序: #include int main(int argc, char* argv[]) { int a = 5; auto it = [&](auto self)
我添加了一个 MKMapView作为 XIB 中我的一个 ViewController 的 subview 。该 map 在显示方向方面工作正常。但是 Legal map 上的文字(左下)显示为 而不
这个问题在这里已经有了答案: JavaScript ternary operator example with functions (6 个答案) Ternary operators in Java
我有两个类如下。 class NeuroShield { public: NeuroShield(); uint16_t begin(); void setNcr(uint16
能够将传递给文字运算符的字符串转换为 MPL 序列会很有用,因为这样我们就可以根据字符串的内容控制代码生成。以前,我认为这是不可能的,因为 constexpr 函数的参数在函数体内不被视为常量表达式。
这是一个有点深奥的问题,但我很好奇以下类扩展模式在现代 C++ 中是否合法(例如,不构成 UB)(出于所有意图和目的,我可以将讨论限制在 C+ +17 及更高版本)。 template struct
我正在使用 MagicalRecord, 这就是我设置 coreData 堆栈的方式 - (BOOL)application:(UIApplication *)application didFinis
我是一名优秀的程序员,十分优秀!