func minCc(nodes []TreeNode, depth int, depthLimit int, roundColor int) *TreeNode { var maxNodes []TreeNode var minNode TreeNode for _, node := range nodes { // 如果此展开的节点已吃了对方老帅,则直接返回 if boardHelper.GeneralBeTaken(node.Board, node.RoundColor) { node.Score = -SCORE_WIN_LIMIT return &node } maxNodes = append(maxNodes, *maxCc(expandNode(node, roundColor), depth+1, depthLimit, roundColor)) } // find the min node in the minNodes minScore := SCORE_WIN_LIMIT for _, node := range maxNodes { if node.Score <= minScore { minNode = node minScore = node.Score } } //fmt.Printf("\n\nscore of minnode is %d. with move %s\n and parent move: %s", // minNode.Score, minNode.Move, minNode.Parent.Parent.Move) minNode.Parent.Score = minScore return minNode.Parent }
func rivalUnderCheck(node TreeNode, roundColor int) bool { nodes := expandNode(node, roundColor) for _, nodeItem := range nodes { // 如果此展开的节点自己老帅被吃了,则直接返回最小值 if boardHelper.GeneralBeTaken(nodeItem.Board, roundColor) { return true } } return false }
func maxCc(nodes []TreeNode, depth int, depthLimit int, roundColor int) *TreeNode { // max 展开的节点,表明当前的评估分数,和要得出步骤的棋子颜色相同 var minNodes []TreeNode var maxNode TreeNode //fmt.Printf("total nodes are: %d with color:%d", len(nodes), nodes[0].RoundColor) for _, node := range nodes { // 如果此展开的节点已吃了对方老帅,则直接返回 if boardHelper.GeneralBeTaken(node.Board, node.RoundColor) { node.Score = SCORE_WIN_LIMIT return &node } else { // 如果展开的节点不带将,将忽略此节点,不再展开 if rivalUnderCheck(node, node.RoundColor) && depth != depthLimit { //fmt.Print("\n---->rival under check with move: %s \n", node.Move) minNodes = append(minNodes, *minCc(expandNode(node, -roundColor), depth+1, depthLimit, roundColor)) } } } // find the max node in the minNodes maxScore := -SCORE_WIN_LIMIT for _, node := range minNodes { if node.Score >= maxScore { maxNode = node maxScore = node.Score } } // 如果没有可展开结点,即被完全憋死了(如3aga3/3ShS3/4S4/9/9/9/9/9/9/4G4,如轮到黑,则完全没有可走之步) //另一局,7子: (9/3ShS3/3aga3/9/9/9/9/9/9/3G5) // TODO //maxNode.Parent.Score = maxNode.Score if maxNode.Parent == nil { //所有的红方招法都没将,找不到下级展开 //也可能是达到了深度 //fmt.Printf("\n --> Nil found, with maxScore = %d and move =%s "+ //"and minNodes count: %d and nodes.count=%d and depth is %d \n", //maxScore, maxNode.Move, len(minNodes), len(nodes), depth) nodes[0].Score = -SCORE_WIN_LIMIT return &nodes[0] // TODO,如果nodes的长度为0,如何处理? } return maxNode.Parent }
func max(nodes []TreeNode, depth int, depthLimit int, roundColor int) *TreeNode { //console.log("in max: , nodes are: ", nodes); // max 展开的节点,表明当前的评估分数,和要得出步骤的棋子颜色相同 var minNodes []TreeNode var maxNode TreeNode for _, node := range nodes { // 如果此展开的节点已吃了对方老帅,则直接返回 if boardHelper.GeneralBeTaken(node.Board, node.RoundColor) { return &node } if depth == depthLimit { node.Score = boardHelper.Evaluate(node.Board) * roundColor minNodes = append(minNodes, node) } else { minNodes = append(minNodes, *min(expandNode(node, roundColor*-1), depth+1, depthLimit, roundColor)) } } // find the max node in the minNodes maxScore := -SCORE_WIN_LIMIT for _, node := range minNodes { //fmt.Printf("\n++for each max, min score is: %d with move %s\n", node.Score, node.Parent.Move) if node.Score > maxScore { maxNode = node maxScore = node.Score } } //fmt.Printf("\n\n\n ____MaxScore is %d and MaxNode Parent Move is %s.\n", maxScore, maxNode.Parent.Move) // 如果没有可展开结点,即被完全憋死了(如3aga3/3ShS3/4S4/9/9/9/9/9/9/4G4,如轮到黑,则完全没有可走之步) //另一局,7子: (9/3ShS3/3aga3/9/9/9/9/9/9/3G5) // TODO //maxNode.Parent.Score = maxNode.Score if depth == 1 { return maxNode.Parent } return &maxNode }
func min(nodes []TreeNode, depth int, depthLimit int, roundColor int) *TreeNode { var maxNodes []TreeNode var minNode TreeNode for _, node := range nodes { // 如果此展开的节点自己老帅被吃了,则直接返回最小值 if boardHelper.GeneralBeTaken(node.Board, node.RoundColor) { node.Score = -SCORE_WIN_LIMIT return &node } if depth == depthLimit { node.Score = boardHelper.Evaluate(node.Board) * roundColor //fmt.Printf("======min node score is %d and board fen is %s=====", node.Score, boardHelper.Board2Fen(node.Board)) maxNodes = append(maxNodes, node) } else { maxNodes = append(maxNodes, *max(expandNode(node, roundColor), depth+1, depthLimit, roundColor)) } } // find the min node in the minNodes minScore := SCORE_WIN_LIMIT for _, node := range maxNodes { if node.Score < minScore { minNode = node minScore = node.Score } } //fmt.Printf("minNode is %q with score: %d.", minNode, minScore) // minNode.Parent.Score = minNode.Score //fmt.Printf("min node move is %s and score is %d.", minNode.Move, minNode.Score) //if depth == depthLimit { return &minNode //} else { // return minNode.Parent //} }