Advertisement
Guest User

@Published doesn't work

a guest
Sep 5th, 2023
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 7.08 KB | Source Code | 0 0
  1. // ComponentView:
  2.  
  3. import SwiftUI
  4. import Combine
  5.  
  6. struct ContentView: View {
  7.     @Environment(\.colorScheme) var colorScheme
  8.     @ObservedObject var ticTacToe = TicTacToeModel()
  9.     @State var selection : Bool = false
  10.     @State var move : Bool = false
  11.     @State var gameOver : Bool = false
  12.    
  13.     func buttonAction(_ index : Int) {
  14.         if self.ticTacToe.makeMove(index: index, gameType: selection) {
  15.             self.gameOver = self.ticTacToe.gameOver.1
  16.         }
  17.     }
  18.    
  19.     var currPlayer: String {
  20.         print("runned", self.ticTacToe.playerToMove)
  21.         return self.ticTacToe.playerToMove == false ? "X" : "O"
  22.     }
  23.    
  24.     var body: some View {
  25.         VStack {
  26.             Picker(selection: $selection, label: Text("Game")) {
  27.                 Text("AI").tag(false)
  28.                 Text("PVP").tag(true)
  29.             }
  30.             .pickerStyle(SegmentedPickerStyle())
  31.             .padding(.horizontal, 89)
  32.             .onReceive(Just(selection)) { _ in
  33.                 self.ticTacToe.resetGame()
  34.             }
  35.            
  36.             Spacer()
  37.            
  38.             Text(self.selection == false ? "Tic Tac Toe - AI" : "Tic Tac Toe - PVP")
  39.                 .bold()
  40.                 .font(.title)
  41.                 //.padding(.bottom)
  42.                 .foregroundColor(colorScheme == .dark ? Color.white.opacity(0.7) : Color.black.opacity(0.7))
  43.            
  44.             Text(self.selection == true ? "\(currPlayer) to move" : " ")
  45.                 .bold()
  46.                 .font(.title2)
  47.                 .padding(.bottom)
  48.                 .foregroundColor(colorScheme == .dark ? Color.white.opacity(0.7) : Color.black.opacity(0.7))
  49.            
  50.             ForEach(0 ..< ticTacToe.squares.count / 3, id: \.self, content: { row in
  51.                 HStack {
  52.                     ForEach(0 ..< 3, content: { column in
  53.                         let index = row * 3 + column
  54.                         SquareView(dataSouce: ticTacToe.squares[index], action: { self.buttonAction(index) })
  55.                     })
  56.                 }
  57.             })
  58.            
  59.             Spacer()
  60.            
  61.             Button(action: {
  62.                 self.ticTacToe.resetGame()
  63.             }, label: {
  64.                 Text("Reset")
  65.                     .foregroundColor(Color.red.opacity(0.7))
  66.             })
  67.         }.alert(isPresented: self.$gameOver, content: {
  68.             Alert(title: Text("Game Over"),
  69.                   message: Text(self.ticTacToe.gameOver.0 != .empty ?
  70.                                 self.ticTacToe.gameOver.0 == .x ? "You Won!" : "AI Won!" : "Draw!"),
  71.                   dismissButton: Alert.Button.destructive(Text("Ok"), action: {
  72.                 self.ticTacToe.resetGame()
  73.             }))
  74.         })
  75.     }
  76. }
  77.  
  78. struct ContentView_Previews: PreviewProvider {
  79.     static var previews: some View {
  80.         ContentView()
  81.     }
  82. }
  83.  
  84. // ---------------------------------------------------------------------
  85. // TicTacToe:
  86.  
  87. import Foundation
  88.  
  89. class TicTacToeModel: ObservableObject {
  90.     @Published var squares = [Square]()
  91.     var playerToMove : Bool = false // App breaks when set to @Published
  92.    
  93.     init() {
  94.         for _ in 0...8 {
  95.             squares.append(Square(status: .empty))
  96.         }
  97.     }
  98.    
  99.     func resetGame() {
  100.         for i in 0...8 {
  101.             squares[i].squareStatus = .empty
  102.             playerToMove = false
  103.         }
  104.     }
  105.    
  106.     var gameOver : (SquareStatus, Bool) {
  107.         get {
  108.             if winner != .empty {
  109.                 return (winner, true)
  110.             } else {
  111.                 for i in 0...8 {
  112.                     if squares[i].squareStatus == .empty {
  113.                         return (.empty, false)
  114.                     }
  115.                 }
  116.                 return (.empty, true)
  117.             }
  118.         }
  119.     }
  120.    
  121.     func makeMove(index: Int, gameType: Bool) -> Bool {
  122.         var player: SquareStatus
  123.         if playerToMove == false {
  124.             player = .x
  125.         } else {
  126.             player = .o
  127.         }
  128.         if squares[index].squareStatus == .empty {
  129.             squares[index].squareStatus = player
  130.             if playerToMove == false && gameType == false {
  131.                 moveAI()
  132.                 playerToMove = true
  133.             }
  134.             playerToMove.toggle()
  135.             return true
  136.         }
  137.         return false
  138.     }
  139.    
  140.     private func moveAI() {
  141.         var index = Int.random(in: 0...8)
  142.         playerToMove = true
  143.         while makeMove(index: index, gameType: true) == false && gameOver.1 == false {
  144.             index = Int.random(in: 0...8)
  145.         }
  146.     }
  147.    
  148.     private var winner: SquareStatus {
  149.         get {
  150.             if let check = self.checkIndexes([0, 1, 2]) {
  151.                 return check
  152.             } else if let check = self.checkIndexes([3, 4, 5]) {
  153.                 return check
  154.             } else if let check = self.checkIndexes([6, 7, 8]) {
  155.                 return check
  156.             } else if let check = self.checkIndexes([0, 3, 6]) {
  157.                 return check
  158.             } else if let check = self.checkIndexes([1, 4, 7]) {
  159.                 return check
  160.             } else if let check = self.checkIndexes([2, 5, 8]) {
  161.                 return check
  162.             } else if let check = self.checkIndexes([0, 4, 8]) {
  163.                 return check
  164.             } else if let check = self.checkIndexes([2, 4, 6]) {
  165.                 return check
  166.             }
  167.             return .empty
  168.         }
  169.     }
  170.    
  171.     private func checkIndexes(_ indexes : [Int]) -> SquareStatus? {
  172.         var xCount : Int = 0
  173.         var oCount : Int = 0
  174.         for index in indexes {
  175.             let square = squares[index]
  176.             if square.squareStatus == .x {
  177.                 xCount += 1
  178.             } else if square.squareStatus == .o {
  179.                 oCount += 1
  180.             }
  181.         }
  182.         if xCount == 3 {
  183.             return .x
  184.         } else if oCount == 3 {
  185.             return .o
  186.         }
  187.         return nil
  188.     }
  189. }
  190.  
  191. // ---------------------------------------------------------------------
  192. // SquareView:
  193.  
  194. import Foundation
  195. import SwiftUI
  196.  
  197. enum SquareStatus {
  198.     case empty
  199.     case x
  200.     case o
  201. }
  202.  
  203. class Square : ObservableObject {
  204.     @Published var squareStatus : SquareStatus
  205.    
  206.     init(status: SquareStatus) {
  207.         self.squareStatus = status
  208.     }
  209. }
  210.  
  211. struct SquareView : View {
  212.     @Environment(\.colorScheme) var colorScheme
  213.     @ObservedObject var dataSouce : Square
  214.     var action: () -> Void
  215.     var body: some View {
  216.         Button(action: {
  217.             self.action()
  218.         }, label: {
  219.             Text(self.dataSouce.squareStatus == .x ?
  220.                  "X" : self.dataSouce.squareStatus == .o ? "O" : " ")
  221.             .font(.system(size: 60))
  222.             .bold()
  223.             .foregroundColor(colorScheme == .dark ? Color.white.opacity(0.9) : Color.black.opacity(0.9))
  224.             .frame(width: 90, height: 90, alignment: .center)
  225.             .background(colorScheme == .dark ? Color.white.opacity(0.3).cornerRadius(10) : Color.gray.opacity(0.3).cornerRadius(10))
  226.             .padding(4)
  227.         })
  228.     }
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement