Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ComponentView:
- import SwiftUI
- import Combine
- struct ContentView: View {
- @Environment(\.colorScheme) var colorScheme
- @ObservedObject var ticTacToe = TicTacToeModel()
- @State var selection : Bool = false
- @State var move : Bool = false
- @State var gameOver : Bool = false
- func buttonAction(_ index : Int) {
- if self.ticTacToe.makeMove(index: index, gameType: selection) {
- self.gameOver = self.ticTacToe.gameOver.1
- }
- }
- var currPlayer: String {
- print("runned", self.ticTacToe.playerToMove)
- return self.ticTacToe.playerToMove == false ? "X" : "O"
- }
- var body: some View {
- VStack {
- Picker(selection: $selection, label: Text("Game")) {
- Text("AI").tag(false)
- Text("PVP").tag(true)
- }
- .pickerStyle(SegmentedPickerStyle())
- .padding(.horizontal, 89)
- .onReceive(Just(selection)) { _ in
- self.ticTacToe.resetGame()
- }
- Spacer()
- Text(self.selection == false ? "Tic Tac Toe - AI" : "Tic Tac Toe - PVP")
- .bold()
- .font(.title)
- //.padding(.bottom)
- .foregroundColor(colorScheme == .dark ? Color.white.opacity(0.7) : Color.black.opacity(0.7))
- Text(self.selection == true ? "\(currPlayer) to move" : " ")
- .bold()
- .font(.title2)
- .padding(.bottom)
- .foregroundColor(colorScheme == .dark ? Color.white.opacity(0.7) : Color.black.opacity(0.7))
- ForEach(0 ..< ticTacToe.squares.count / 3, id: \.self, content: { row in
- HStack {
- ForEach(0 ..< 3, content: { column in
- let index = row * 3 + column
- SquareView(dataSouce: ticTacToe.squares[index], action: { self.buttonAction(index) })
- })
- }
- })
- Spacer()
- Button(action: {
- self.ticTacToe.resetGame()
- }, label: {
- Text("Reset")
- .foregroundColor(Color.red.opacity(0.7))
- })
- }.alert(isPresented: self.$gameOver, content: {
- Alert(title: Text("Game Over"),
- message: Text(self.ticTacToe.gameOver.0 != .empty ?
- self.ticTacToe.gameOver.0 == .x ? "You Won!" : "AI Won!" : "Draw!"),
- dismissButton: Alert.Button.destructive(Text("Ok"), action: {
- self.ticTacToe.resetGame()
- }))
- })
- }
- }
- struct ContentView_Previews: PreviewProvider {
- static var previews: some View {
- ContentView()
- }
- }
- // ---------------------------------------------------------------------
- // TicTacToe:
- import Foundation
- class TicTacToeModel: ObservableObject {
- @Published var squares = [Square]()
- var playerToMove : Bool = false // App breaks when set to @Published
- init() {
- for _ in 0...8 {
- squares.append(Square(status: .empty))
- }
- }
- func resetGame() {
- for i in 0...8 {
- squares[i].squareStatus = .empty
- playerToMove = false
- }
- }
- var gameOver : (SquareStatus, Bool) {
- get {
- if winner != .empty {
- return (winner, true)
- } else {
- for i in 0...8 {
- if squares[i].squareStatus == .empty {
- return (.empty, false)
- }
- }
- return (.empty, true)
- }
- }
- }
- func makeMove(index: Int, gameType: Bool) -> Bool {
- var player: SquareStatus
- if playerToMove == false {
- player = .x
- } else {
- player = .o
- }
- if squares[index].squareStatus == .empty {
- squares[index].squareStatus = player
- if playerToMove == false && gameType == false {
- moveAI()
- playerToMove = true
- }
- playerToMove.toggle()
- return true
- }
- return false
- }
- private func moveAI() {
- var index = Int.random(in: 0...8)
- playerToMove = true
- while makeMove(index: index, gameType: true) == false && gameOver.1 == false {
- index = Int.random(in: 0...8)
- }
- }
- private var winner: SquareStatus {
- get {
- if let check = self.checkIndexes([0, 1, 2]) {
- return check
- } else if let check = self.checkIndexes([3, 4, 5]) {
- return check
- } else if let check = self.checkIndexes([6, 7, 8]) {
- return check
- } else if let check = self.checkIndexes([0, 3, 6]) {
- return check
- } else if let check = self.checkIndexes([1, 4, 7]) {
- return check
- } else if let check = self.checkIndexes([2, 5, 8]) {
- return check
- } else if let check = self.checkIndexes([0, 4, 8]) {
- return check
- } else if let check = self.checkIndexes([2, 4, 6]) {
- return check
- }
- return .empty
- }
- }
- private func checkIndexes(_ indexes : [Int]) -> SquareStatus? {
- var xCount : Int = 0
- var oCount : Int = 0
- for index in indexes {
- let square = squares[index]
- if square.squareStatus == .x {
- xCount += 1
- } else if square.squareStatus == .o {
- oCount += 1
- }
- }
- if xCount == 3 {
- return .x
- } else if oCount == 3 {
- return .o
- }
- return nil
- }
- }
- // ---------------------------------------------------------------------
- // SquareView:
- import Foundation
- import SwiftUI
- enum SquareStatus {
- case empty
- case x
- case o
- }
- class Square : ObservableObject {
- @Published var squareStatus : SquareStatus
- init(status: SquareStatus) {
- self.squareStatus = status
- }
- }
- struct SquareView : View {
- @Environment(\.colorScheme) var colorScheme
- @ObservedObject var dataSouce : Square
- var action: () -> Void
- var body: some View {
- Button(action: {
- self.action()
- }, label: {
- Text(self.dataSouce.squareStatus == .x ?
- "X" : self.dataSouce.squareStatus == .o ? "O" : " ")
- .font(.system(size: 60))
- .bold()
- .foregroundColor(colorScheme == .dark ? Color.white.opacity(0.9) : Color.black.opacity(0.9))
- .frame(width: 90, height: 90, alignment: .center)
- .background(colorScheme == .dark ? Color.white.opacity(0.3).cornerRadius(10) : Color.gray.opacity(0.3).cornerRadius(10))
- .padding(4)
- })
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement