예제 #1
0
// First-level NegaScout search function.
// When called, alpha and beta should be set to the lowest and highest values possible.
func NegaScout(b *engine.Board, depth int, alpha, beta float64) *engine.Move {
	if b.IsOver() != 0 || depth == 0 {
		b.Lastmove.Score = EvalBoard(b)
		return &b.Lastmove
	}
	var move engine.Move

	// not indended for actual use
	orderedmoves := b.AllLegalMoves()

	var score float64
	for i, m := range orderedmoves {
		childboard := b.CopyBoard()
		childboard.Move(m)
		if i != 0 {
			score = -NegaScoutChild(childboard, depth-1, -alpha-1, -alpha)
			if alpha < score && score < beta {
				score = -NegaScoutChild(childboard, depth-1, -beta, -alpha)
			}
		} else {
			score = -NegaScoutChild(childboard, depth-1, -beta, -alpha)
		}
		alpha = math.Max(alpha, score)
		if alpha >= beta {
			move = *m.CopyMove()
			move.Score = alpha
			break
		}
	}
	return &move
}
예제 #2
0
// Child level NegaScout search function.
// Unlike its parent, only returns score and not full move
func NegaScoutChild(b *engine.Board, depth int, alpha, beta float64) float64 {
	if b.IsOver() != 0 || depth == 0 {
		return EvalBoard(b)
	}

	// not indended for actual use
	orderedmoves := b.AllLegalMoves()

	var score float64
	for i, m := range orderedmoves {
		childboard := b.CopyBoard()
		childboard.Move(m)
		if i != 0 {
			score = -NegaScoutChild(childboard, depth-1, -alpha-1, -alpha)
			if alpha < score && score < beta {
				score = -NegaScoutChild(childboard, depth-1, -beta, -alpha)
			}
		} else {
			score = -NegaScoutChild(childboard, depth-1, -beta, -alpha)
		}
		alpha = math.Max(alpha, score)
		if alpha >= beta {
			break
		}
	}
	return alpha
}
예제 #3
0
파일: negamax.go 프로젝트: jimmahoney/chess
// First-level negamax search function.
func NegaMax(b *engine.Board, depth int) *engine.Move {
	if b.IsOver() != 0 || depth == 0 {
		b.Lastmove.Score = EvalBoard(b)
		return &b.Lastmove
	}
	var move engine.Move
	move.Score = LOSS
	for _, m := range b.AllLegalMoves() {
		childboard := b.CopyBoard()
		childboard.Move(m)
		childscore := -NegaMaxChild(childboard, depth-1)
		if childscore > move.Score {
			move = *m.CopyMove()
			move.Score = childscore
			if move.Score == WIN {
				return &move
			}
		}
	}
	return &move
}