abstract class GreedyPlayer[N <: Node[N]] extends Player[N] { override def play(ply: Int, node: N, last: Move): Move = { val moves = node.possibleMoves() var bestMove = List[Move]() var maxS = Int.MinValue for (m <- moves) { val n = node.play(m).get val s = score(n) if (s > maxS) { bestMove = List(m) maxS = s } else if (s == maxS) { bestMove = m :: bestMove } } bestMove(Random.nextInt(bestMove.length)) } def score(node: N): Int }
実は、GreedyPlayer自体はreversiに特化されていなくて、単純にscoreがもっともよくなる次の手を打つというものである。ここで、scoreはゲームによって異なるのでabstractにしてある。単純にコマの数の差をスコアにすると、次のようになる。
trait MarkersScore { var marker: Marker /** * Returns a score for the marker */ def score(node: ReversiNode): Int = { val nums = node.board.numOfMarkers if (marker == Dark) nums(Dark) - nums(Light) else nums(Light) - nums(Dark) } }
RandomPlayerと1000番勝負をしてみると、Greedyが先手(D)で
D: 616, L: 349, -: 35
後手(L)で
D: 398, L: 567, -: 35
と、ちょっと強い程度。
2011/06/25: コード更新
0 件のコメント:
コメントを投稿