如何在Grundy的游戏中将堆分成两堆?
如何将堆分成任意数量的堆(其中没有两个是相同的)?
答案 0 :(得分:1)
在“Winning Ways for your Mathematical Plays”系列丛书中详细分析了此类游戏。您正在寻找的大部分内容可能都是第1卷。
您还可以查看以下链接:Nimbers (Wikipedia),Sprague-Grundy theorem (Wikipedia)或搜索“组合博弈论”。
我对此的了解非常生疏,所以我担心我无法帮助你解决这个具体问题。如果你已经知道我所关联的一切,那就是我的借口。
编辑:一般来说,解决这些类型游戏的方法是“建立”堆栈大小。所以从一堆1开始,决定谁以最佳游戏获胜。然后对于2的堆栈执行相同的操作,可以将其拆分为1& 1.转到3,可分为1& 2.同样的4(这里变得更加棘手):3& 1或2& 2,使用Spague-Grundy定理&对于nimbers的代数规则,你可以计算谁将获胜。继续前进,直到达到需要知道答案的堆栈大小。
编辑2:我在评论中谈论的网站似乎已经失效。以下是备份的链接:Wayback Machine - Introduction to Combinatorial Games。
答案 1 :(得分:0)
Grundy的游戏以及类似的许多游戏都可以通过以下算法解决:
//returns a Move object representing the current player's optimal move, or null if the player has no chance of winning
function bestMove(GameState g){
for each (move in g.possibleMoves()){
nextState = g.applyMove(move)
if (bestMove(nextState) == null){
//the next player's best move is null, so if we take this move,
//he has no chance of winning. This is good for us!
return move;
}
}
//none of our possible moves led to a winning strategy.
//We have no chance of winning. This is bad for us :-(
return null;
}
GameState和Move的实现取决于游戏。对于Grundy的游戏,两者都很简单。
GameState
存储一个整数列表,表示游戏中每个堆的大小。
Move
存储initialHeapSize
整数和resultingHeapSizes
整数列表。
GameState::possibleMoves
遍历其堆大小列表,并确定每个列的合法划分。
GameState::applyMove(Move)
返回GameState的副本,除了给它的移动应用于棋盘。
GameState::possibleMoves
可以像“经典”Grundy游戏一样实现:
function possibleMoves(GameState g){
moves = []
for each (heapSize in g.heapSizes){
for each (resultingHeaps in possibleDivisions(heapSize)){
Move m = new Move(heapSize, resultingHeaps)
moves.append(m)
}
}
return moves
}
function possibleDivisions(int heapSize){
divisions = []
for(int leftPileSize = 1; leftPileSize < heapSize; leftPileSize++){
int rightPileSize = heapSize - leftPileSize
if (leftPileSize != rightPileSize){
divisions.append([leftPileSize, rightPileSize])
}
}
return divisions
}
修改此项以使用“划分为任意数量的不等桩”规则只需更改possibleDivisions
的实施。
我还没有完全计算出来,但是未经优化的bestMove有一个非常疯狂的最坏情况运行时。一旦你开始给它一个大约12块石头的起始状态,你将会等待很长时间。因此,您应该实施memoization以提高效果。
为了获得最佳效果,请将每个GameState的堆大小列表排序,并丢弃任何大小为2或1的堆。