This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func negamax(position: Board, players: [Player], whoseTurn: Player, depth: Int, alpha: Int = Int.min, beta: Int = Int.max) -> (Int, Move?) { | |
| let moves = position.generateMoves(player: whoseTurn) | |
| if position.thereIsAWinner() != nil || (depth == 0) { | |
| return (position.evaluate(evaluationFlags: appState.evaluationFlags, board: position, whoseTurn: whoseTurn, nextPlayer: nextPlayer(player: whoseTurn)), nil) | |
| } | |
| var bestScore = Int.min | |
| var bestMove: Move? | |
| for move in moves { | |
| let clone = position.clone() | |
| let _ = clone.makeMove(move: move, depth: depth) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // avoiding error where -Int.max (and maybe -Int.min) result in numeric overflow | |
| // this could be more efficient with constants like let infinity = Int.max - 10 | |
| func negate(number: Int) -> Int { | |
| if number == Int.max { return Int.min } | |
| if number == Int.min { return Int.max } | |
| else { return -number } | |
| } | |
| func negateMaximum(_ a: Int, _ b:Int) -> Int { | |
| if a > b { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func miniMaxCore(position: Board, players: [Player], whoseTurn: Player, depth: Int) -> Int { | |
| var bestValue = Int.min | |
| let moves = position.generateMoves(player: whoseTurn) | |
| for move in moves { | |
| let clone = position.clone() | |
| let _ = clone.makeMove(move: move, depth: depth) | |
| if position.thereIsAWinner() != nil || (depth == 0) { | |
| move.score = position.evaluate(evaluationFlags: appState.evaluationFlags, board: clone, whoseTurn: whoseTurn, nextPlayer: nextPlayer(player: whoseTurn)) | |
| } | |
| else { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public func evaluate(evaluationFlags: EvaluationFlags, board: Board, whoseTurn: Player, nextPlayer: Player) -> Int { | |
| var score = 0 | |
| for rank in 0..<board.squaresHigh { | |
| for file in 0..<board.squaresWide { | |
| if let man = board.squares[file][rank].man { | |
| if man.player == whoseTurn { | |
| if evaluationFlags.material { | |
| score += man.value | |
| } | |
| if evaluationFlags.mobility { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func getBestMove(players: [Player], whoseTurn: Player, position: Board) async -> Move? { | |
| var best: Move? | |
| switch appState.game.aiType { | |
| case .random: | |
| best = getRandomMove(moves: position.generateMoves(player: whoseTurn)) | |
| case .kamikaze: | |
| best = miniMax(position: position, players: players, whoseTurn: players[1], depth: 0) | |
| case .minimax: | |
| best = miniMax(position: position, players: players, whoseTurn: players[1], depth: appState.searchDepth) | |
| case .pruner: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public func generateMoves(player: Player) -> [Move] | |
| { | |
| var moves = [Move]() | |
| for rank in 0..<squaresHigh { | |
| for file in 0..<squaresWide { | |
| if let man = squares[file][rank].man { | |
| if man.player == player { | |
| moves += (man.generateMoves(board: self, x: file, y: rank)) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| struct GhostModifier: ViewModifier { | |
| let hasGhost: Bool | |
| let isInAWall: Bool | |
| func body(content: Content) -> some View { | |
| if hasGhost { | |
| if isInAWall { | |
| content |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func blockedByWall(man: Man, targetSquare: Square) -> Bool { | |
| return targetSquare.squareType == .wall && !man.tools.contains(.ghost) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| squareView(file: file, rank: rank, color: viewModel.getBackgroundColor(file: file, rank: rank)) | |
| .artifactModifier(tool: viewModel.showTool(file: file, rank: rank), squareSize: viewModel.squareSize) | |
| .handoffableModifier(isHighlighted: viewModel.handOffable[file][rank]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| struct HandoffableModifier: ViewModifier { | |
| let isHighlighted: Bool | |
| func body(content: Content) -> some View { | |
| if isHighlighted { | |
| ZStack { | |
| GeometryReader { geometry in | |
| content |
NewerOlder