已经实现蒙特卡洛树算法的通用逻辑,只需要对应结构体实现相关接口就可以直接使用该算法。
优化算法主要优化GetActions
生成下一步动作,要尽可能少,去掉无意义的动作。
以及优化ActionPolicy
从众多动作挑选比较优秀的动作。对应五子棋就是执行该动作后当前局面评分最高。
package main
import (
"fmt"
"math"
"math/rand"
"strings"
"time"
)
func main() {
var (
board = NewQuZiQi(15)
x, y int
)
board.Print()
for board.IsTerminal() == 0 {
board = Search(time.Second*10, board).(*WuZiQi)
board.Print()
if board.IsTerminal() == 1 {
fmt.Println("电脑赢了")
return
}
for {
fmt.Print("轮到您执棋,请输入坐标: ")
_, _ = fmt.Scanln(&x, &y)
x--
y--
if x < 0 || y < 0 || x >= board.size || y >= board.size {
fmt.Println("您输入的数据超出棋盘范围")
} else if board.board[x][y] > 0 {
fmt.Println("该位置已有棋子")
} else {
board.board[x][y] = 2
board.player = 1 // 下一步该电脑下
break
}
}
board.Print()
if board.IsTerminal() == 2 {
fmt.Println("你赢了")
return
}
}
}
// WuZiQi 五子棋游戏
type WuZiQi struct {
size int // 棋盘大小
board [][]int // 棋盘状态
player int // 1: 电脑落子,2: 玩家落子
}
func NewQuZiQi(size int) *WuZiQi {
w := &WuZiQi{
size: size,
board: make([][]int, size),
player: 1,
}
for i := 0; i < size; i++ {
w.board[i] = make([]int, size)
}
size /= 2
// 默认中间落一个棋子
// 0: 表示没有落子,1: 表示电脑,2: 表示玩家
w.board[size][size] = 2
return w
}
func (w *WuZiQi) Print() {
var (
str strings.Builder
num = func(n int) {
a, b := n/10, n%10