// // TtextView.swift // assign3 // // Created by Jason Kim on 4/7/22. // import SwiftUI struct mainView: View { @Environment(\.verticalSizeClass) var verticalSizeClass @Environment(\.horizontalSizeClass) var horizontalSizeClass @EnvironmentObject var triples: TTriples @State private var isRand = false private var yes = "Randomized" private var no = "Deterministic" @State private var score = 0 @State private var over = false @State var viewboard: [[Tileview]] = [[Tileview]](repeating: [Tileview](repeating: Tileview(tile: Tile(val:0, id:0,row: 0, col: 0)), count: 4), count: 4) @State private var final_score = 0 func update() { for i in 0..<4{ for j in 0..<4{ viewboard[i][j] = Tileview(tile: triples.board[i][j] ?? Tile(val: 0, id: 0, row: 0, col: 0)) } } } func spawns(){ triples.spawn() score = triples.score update() } func newGame(){ if final_score != 0{ triples.scores.append(Score(score: final_score, time: Date.now)) } triples.newgame(rand: isRand) score = triples.score spawns() spawns() spawns() spawns() } func newGame1(){ if final_score != 0 { over = true } final_score = score newGame() if final_score == 0 { final_score = score } } func isGameOver() -> Bool{ let copy = TTriples() copy.board = triples.board _ = copy.collapse(dir: Tdirection.left) if copy.board == triples.board{ _ = copy.collapse(dir: Tdirection.right) if copy.board == triples.board{ _ = copy.collapse(dir: Tdirection.up) if copy.board == triples.board{ _ = copy.collapse(dir: Tdirection.down) if copy.board == triples.board{ final_score = score newGame() return true } } } } final_score = score return false } func Left() { let copy = TTriples() copy.board = triples.board if triples.score == 0 { newGame1() } else { _ = triples.collapse(dir: Tdirection.left) if copy.board != triples.board{ spawns() } over = isGameOver() update() } } func Right() { let copy = TTriples() copy.board = triples.board if triples.score == 0 { newGame1() } else { _ = triples.collapse(dir: Tdirection.right) if copy.board != triples.board{ spawns() } over = isGameOver() update() } } func Up() { let copy = TTriples() copy.board = triples.board if triples.score == 0 { newGame1() } else { _ = triples.collapse(dir: Tdirection.up) if copy.board != triples.board{ spawns() } over = isGameOver() update() } } func Down() { let copy = TTriples() copy.board = triples.board if triples.score == 0 { newGame1() } else { _ = triples.collapse(dir: Tdirection.down) if copy.board != triples.board{ spawns() } over = isGameOver() update() } } var body: some View { if verticalSizeClass == .regular { VStack{ Text("Score: \(score)").font(.largeTitle) Toggle(isOn: $isRand){ Text("Randomize?") }.padding() VStack{ VStack { //board ForEach(0..<4, id:\.self) { i in HStack{ ForEach(0..<4, id:\.self){ j in viewboard[i][j].shadow(color: .cyan, radius: 3, x: 1, y: 1) .transition(AnyTransition.opacity.animation(.linear(duration: 0.2))) .zIndex(1) } } } }.padding() .gesture(DragGesture(minimumDistance: 40, coordinateSpace: .local) .onEnded({ val in if val.translation.width < 0 && val.translation.height > -20 && val.translation.height < 20 { withAnimation{Left()} } else if val.translation.width > 0 && val.translation.height > -20 && val.translation.height < 20{ Right() } else if val.translation.height < 0 && val.translation.width < 20 && val.translation.width > -20 { Up() } else if val.translation.height > 0 && val.translation.width < 20 && val.translation.width > -20 { Down() } else { print("not a gesture") } })) VStack{ Button(action: newGame1){ Text("New Game") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)") ) } .font(.title2) .padding() .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.red, lineWidth: 3)) .offset(x: 0, y: 10) .foregroundColor(.red) Button(action: withAnimation{Left}){ Text("Left") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .font(.title) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .offset(x: -75, y: 91) Button(action: withAnimation{Right}){ Text("Right") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .font(.title) .offset(x: 75, y: 33) Button(action: withAnimation{Up}){ Text("Up") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .font(.title) .offset(x: 0, y: -90) Button(action: withAnimation{Down}){ Text("Down") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .font(.title) .offset(x: 0, y: -19) } //171 } //148 } //136 } else { //horizontal view HStack{ VStack { ForEach(0..<4, id:\.self) { i in HStack{ ForEach(0..<4, id:\.self){ j in viewboard[i][j].shadow(color: .cyan, radius: 3, x: 1, y: 1) .transition(AnyTransition.opacity.animation(.linear(duration: 0.2))) .zIndex(1) } } } }.padding() .gesture(DragGesture(minimumDistance: 3, coordinateSpace: .local) .onEnded({ val in if val.translation.width < 0 && val.translation.height > -20 && val.translation.height < 20 { withAnimation{Left()} } else if val.translation.width > 0 && val.translation.height > -20 && val.translation.height < 20{ Right() } else if val.translation.height < 0 && val.translation.width < 20 && val.translation.width > -20 { Up() } else if val.translation.height > 0 && val.translation.width < 20 && val.translation.width > -20 { Down() } else { print("not a gesture") } })) VStack{ //buttons Text("Score: \(score)").font(.title) Toggle(isOn: $isRand){ Text("Randomize?") } HStack{ Button(action: newGame1){ Text("New Game") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)") ) }.font(.title2) .padding() .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.red, lineWidth: 3)) .offset(x: -100, y: -70) .foregroundColor(.red) VStack{ //direction buttons Button(action: withAnimation{Left}){ Text("Left") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .font(.title) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .offset(x: -75, y: 91) Button(action: withAnimation{Right}){ Text("Right") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .font(.title) .offset(x: 75, y: 33) Button(action: withAnimation{Up}){ Text("Up") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .font(.title) .offset(x: 0, y: -90) Button(action: withAnimation{Down}){ Text("Down") }.alert(isPresented: $over){ Alert( title: Text("Game Over!"), message: Text("Score: \(final_score)")) }.frame(width: 100, height: 50, alignment: .center) .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.blue, lineWidth: 3)) .font(.title) .offset(x: 0, y: -19) } } //hstack } //171 vstack } //148 hstack } //136 else }//135 (body) }