64 lines
1.7 KiB
Swift
64 lines
1.7 KiB
Swift
|
//
|
||
|
// TTTView.swift
|
||
|
// Tusker
|
||
|
//
|
||
|
// Created by Shadowfacts on 12/21/22.
|
||
|
// Copyright © 2022 Shadowfacts. All rights reserved.
|
||
|
//
|
||
|
|
||
|
import SwiftUI
|
||
|
import TTTKit
|
||
|
import GameKit
|
||
|
import OSLog
|
||
|
|
||
|
@available(iOS 16.0, *)
|
||
|
struct TTTView: View {
|
||
|
static let aiQueue = DispatchQueue(label: "TTT AI Strategist", qos: .userInitiated)
|
||
|
|
||
|
@StateObject private var controller = GameController()
|
||
|
@State private var isAIThinking = false
|
||
|
@State private var strategist = {
|
||
|
let strategist = GKMinmaxStrategist()
|
||
|
strategist.maxLookAheadDepth = 5
|
||
|
return strategist
|
||
|
}()
|
||
|
|
||
|
var body: some View {
|
||
|
VStack(alignment: .center) {
|
||
|
GameView(controller: controller)
|
||
|
.frame(width: 256, height: 256)
|
||
|
|
||
|
if isAIThinking {
|
||
|
ProgressView()
|
||
|
.progressViewStyle(.circular)
|
||
|
} else {
|
||
|
Text(controller.state.displayName)
|
||
|
}
|
||
|
}
|
||
|
.onReceive(controller.$state) { newState in
|
||
|
switch newState {
|
||
|
case .playAnywhere(.o), .playSpecific(.o, column: _, row: _):
|
||
|
isAIThinking = true
|
||
|
TTTView.aiQueue.async {
|
||
|
let gameModel = GameModel(controller: controller)
|
||
|
strategist.gameModel = gameModel
|
||
|
let move = strategist.bestMoveForActivePlayer()!
|
||
|
DispatchQueue.main.async {
|
||
|
gameModel.apply(move)
|
||
|
isAIThinking = false
|
||
|
}
|
||
|
}
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@available(iOS 16.0, *)
|
||
|
struct TTTView_Previews: PreviewProvider {
|
||
|
static var previews: some View {
|
||
|
TTTView()
|
||
|
}
|
||
|
}
|