コード例 #1
0
ファイル: mate.go プロジェクト: jmptrader/go-chess
func doesMate(logger *logger.Logger, board *core.Board, depth int) core.Moves {
	if depth < 0 {
		return nil
	}
	logger = logger.Push()

	// If every move leads to a mate, we are good. Return longest chain.
	longest := make(core.Moves, 0, 10)
	possible_moves := board.ListMoves()
	if len(possible_moves) == 0 {
		// We are either mated or in stalemate. We might have found a solution
		if core.Is_in_check(board) {
			logger.Log(fmt.Sprintf("We are mated\n%s", board))
			return longest
		} else {
			return nil
		}
	}
	for _, m := range possible_moves {
		b := m.Perform_move(board)
		more_moves := Find(logger, b, depth-1)
		if more_moves == nil {
			return nil
		}
		more_moves = append(more_moves, m)
		if len(longest) < len(more_moves) {
			longest = more_moves
		}
	}
	logger.Log(fmt.Sprintf("all moves lead to mate, board=\n%s", board))
	return longest
}
コード例 #2
0
ファイル: selfmate.go プロジェクト: jmptrader/go-chess
func Find(logger *logger.Logger, board *core.Board, depth int) core.Moves {
	if depth < 0 {
		return nil
	}
	logger = logger.Push()
	possible_moves := board.ListMoves()

	logger.Log(fmt.Sprintf("Entering Find, depth=%d, board=\n%s, possible=%d\n", depth, board, len(possible_moves)))

	// the goal is to force ourselves into a mating position
	if len(possible_moves) == 0 {
		if core.Is_in_check(board) {
			logger.Log(fmt.Sprintf("We are mated\n%s", board))
			return make(core.Moves, 0, 10)
		} else {
			return nil
		}
	}
	for _, m := range possible_moves {
		// if all moves leads to a selfmate, we are good.
		// todo: keep shortest chain
		b := m.Perform_move(board)
		logger.Log(fmt.Sprintf("played %s, board=\n%s\n", m, b))

		more_moves := doesSelfMate(logger, b, depth-1)
		if more_moves != nil {
			logger.Log(fmt.Sprintf("all moves lead to selfmate, board=\n%s", board))
			more_moves = append(more_moves, m)
			return more_moves
		}
	}
	return nil
}
コード例 #3
0
ファイル: selfmate.go プロジェクト: jmptrader/go-chess
func doesSelfMate(logger *logger.Logger, board *core.Board, depth int) core.Moves {
	if depth < 0 {
		return nil
	}
	logger = logger.Push()
	var longest core.Moves = nil
	// If every move leads to a selfmate, we are good. Return longest chain.
	possible_moves := board.ListMoves()
	logger.Log(fmt.Sprintf("Entering doesSelfMate, depth=%d, board=\n%s\npossible=%d\n", depth, board, len(possible_moves)))
	for _, m := range possible_moves {
		b := m.Perform_move(board)
		logger.Log(fmt.Sprintf("played %s, board=\n%s", m, b))

		more_moves := Find(logger, b, depth-1)
		if more_moves == nil {
			return nil
		}
		more_moves = append(more_moves, m)
		if longest == nil || (len(longest) < len(more_moves)) {
			longest = more_moves
		}
	}
	logger.Log(fmt.Sprintf("all moves lead to selfmate, board=\n%s", board))
	return longest
}
コード例 #4
0
ファイル: mate.go プロジェクト: jmptrader/go-chess
/**
 * Quickly hacked together AI.
 *
 * I could do a bunch of things better: better debugging, better
 * code re-use, avoid re-computing if a board position is in check or not, etc.
 */
func Find(logger *logger.Logger, board *core.Board, depth int) core.Moves {
	if depth < 0 {
		return nil
	}
	logger = logger.Push()
	possible_moves := board.ListMoves()
	for _, m := range possible_moves {
		// if any move leads to a mate, we are good.
		// TODO: keep shortest chain?
		b := m.Perform_move(board)

		more_moves := doesMate(logger, b, depth-1)
		if more_moves != nil {
			logger.Log(fmt.Sprintf("found mate: played %s, board=\n%s", m, b))
			more_moves = append(more_moves, m)
			return more_moves
		}
	}
	// If there are no more moves, the current board is either a mate or stalemate
	return nil
}