我仍然在学习Scala,并决定实施一个黑白棋游戏。我使用Alpha Beta修剪,基于这个algorithm来实现AI组件。优化Scala代码片段
但是我意识到我的执行效率不高。如果我将算法的最大深度增加到5以上,我会开始注意性能问题。我意识到搜索空间是指数级的,所以我希望能够帮助我指出优化此代码的方法。
下面是如何实现的算法:
trait MaxMin
case class Max() extends MaxMin
case class Min() extends MaxMin
object AlphaBeta {
type Move = List[State]
type FitnessMove = Tuple2[Int, List[Move]]
def not(p: Player) = p match {
case _: Player2 => Player1()
case _: Player1 => Player2()
}
def max(x: FitnessMove, y: FitnessMove) = if (x._1 >= y._1) x else y
def min(x: FitnessMove, y: FitnessMove) = if (x._1 <= y._1) x else y
def terminal(turn: Int) = if (turn >= 64) true else false
def search(board: Board, player: Player, turn: Int, MAX_DEPTH: Int = 5): Move = {
def alphaBeta(node: Board, depth: Int, alpha: Int, beta: Int,
moveChoice: List[Move], player: Player, p: MaxMin, turn: Int): FitnessMove =
if (depth == 0 || terminal(turn))
(player.evalHeuristic(node, turn), moveChoice)
else
p match {
case _: Max =>
player.getPossibleMoves(node).
takeWhile(_ => beta > alpha). // Pruning
foldLeft((alpha, moveChoice)) { case ((alpha, moveChoice), move) =>
val simulate = player.simulateMove(node, move)
max((alpha, moveChoice),
alphaBeta(simulate, depth-1, alpha, beta,
move :: moveChoice, not(player), Min(), turn+1))
}
case _: Min =>
player.getPossibleMoves(node).
takeWhile(_ => beta > alpha). // Pruning
foldLeft((beta, moveChoice)) { case ((beta, moveChoice), move) =>
val simulate = player.simulateMove(node, move)
(
min((beta, moveChoice),
alphaBeta(simulate, depth-1, alpha, beta,
moveChoice, not(player), Max(), turn+1))._1,
moveChoice
)
}
}
val (_, moveChoice) = alphaBeta(board, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, List.empty[Move], player, Max(), turn)
if (!moveChoice.isEmpty) moveChoice.head
else player.getPossibleMoves(board).head
}
}
,如果我使用while循环和一个更加“势在必行”的做法,但我更愿意保持不变的代码,我大概可以得到更好的性能。我可以在代码上做出什么改进,或者你会以不同方式处理整个算法的实现?
这是game如果你想检查出来。谢谢!
只是如果你是感兴趣:前段时间我写了一个基于小控制台的Othello实现,没有AI:https://gist.github.com/sschaef/2472666 – sschaef 2013-03-17 01:04:33
你能否确保你附加一个测试,以便我可以自由地重构你的代码而不会中断其功能? – Edmondo1984 2013-03-17 02:45:24
嗨@ Edmondo1984是的,我会尝试尽快添加一些测试。 – 2013-03-17 19:49:54