func (game *gameMemo) sub(it int, p *plan.Plan, latestBestScore int) *plan.Plan { if it >= game.numStone { return p } if game.willBestScore(p, it) > latestBestScore { return p } var bestPositions []Position var bestScore = 0x8fffffff var bestIsolation = 0x8fffffff sBase := game.stoneBase[it] for x := 0; x < 32; x++ { for y := 0; y < 32; y++ { for _, stone := range sBase.GetVariations() { if !p.Put(x, y, stone) { continue } pScore := p.PartialScoreByExistStones() pIso := p.CountIsolation() if pScore < bestScore { bestPositions = []Position{{x: x, y: y, stone: stone}} bestScore = pScore bestIsolation = pIso } else if pScore == bestScore { if bestIsolation > pIso { bestPositions = []Position{{x: x, y: y, stone: stone}} bestIsolation = pIso } else if bestIsolation == pIso { bestPositions = append(bestPositions, Position{x: x, y: y, stone: stone}) } } p.Pop() } } } var bestPlan *plan.Plan if bestIsolation-p.CountIsolation() > 0 && bestIsolation != 0x8fffffff && it < 45 { if rand.Intn(3) == 0 { pp := p.Copy() bestPlan = game.sub(it+1, pp, latestBestScore) } } else if bestIsolation-p.CountIsolation() > 0 && bestIsolation != 0x8fffffff { if rand.Intn(15) == 0 { pp := p.Copy() bestPlan = game.sub(it+1, pp, latestBestScore) } } else { if rand.Intn(25) == 0 { pp := p.Copy() bestPlan = game.sub(it+1, pp, latestBestScore) } } for i, posNo := range rand.Perm(len(bestPositions)) { if game.numStone-it < 20 { if i >= 3 { break } } else if game.numStone-it < 25 { if i >= 2 { break } } else { if i >= 1 { break } } bestPosition := bestPositions[posNo] pp := p.Copy() pp.Put(bestPosition.x, bestPosition.y, bestPosition.stone) if candidatePlan := game.sub(it+1, pp, latestBestScore); comparePlan(candidatePlan, bestPlan) == '>' { bestPlan = candidatePlan } } if len(bestPositions) == 0 { pp := p.Copy() bestPlan = game.sub(it+1, pp, latestBestScore) } return bestPlan }