From 3fb4770608a6a56018766658ff789dc8d537a13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Regnault?= Date: Wed, 29 May 2024 11:55:13 +0200 Subject: [PATCH] :construction: adding GameVM and HistoricVM to wrap DouShouQiModel properties --- .../DouShouQi_App.xcodeproj/project.pbxproj | 16 ++++++ .../Components/Game/GameResumeFrame.swift | 20 +++++--- .../Components/MainMenuButton.swift | 2 +- .../DouShouQi_App/ViewModel/Game/GameVM.swift | 50 +++++++++++++++++++ .../ViewModel/Game/HistoricVM.swift | 26 ++++++++++ .../Views/Game/HistoricView.swift | 15 ++++-- .../Views/Menu/MainMenuView.swift | 2 +- 7 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 DouShouQi_App/DouShouQi_App/ViewModel/Game/GameVM.swift create mode 100644 DouShouQi_App/DouShouQi_App/ViewModel/Game/HistoricVM.swift diff --git a/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj b/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj index 6a65f56..593898a 100644 --- a/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj +++ b/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj @@ -20,6 +20,8 @@ 645834892BF5FEA000E18321 /* DSQ.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 645834872BF5FEA000E18321 /* DSQ.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 645B4C202BFCCA0500FD658A /* PlayerResumeFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645B4C1F2BFCCA0500FD658A /* PlayerResumeFrame.swift */; }; 645B4C252BFCD3C600FD658A /* ScoreBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645B4C242BFCD3C600FD658A /* ScoreBoardView.swift */; }; + 646FA83E2C072340001466BA /* GameVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646FA83D2C072340001466BA /* GameVM.swift */; }; + 646FA8432C0730D6001466BA /* HistoricVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646FA8422C0730D6001466BA /* HistoricVM.swift */; }; 6493C1C02C046BF900B5121D /* samurai.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6493C1BF2C046BF900B5121D /* samurai.ttf */; }; 6493C1C22C046E5E00B5121D /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6493C1C12C046E5E00B5121D /* Fonts.swift */; }; 649ABF5B2BF60D78002E8894 /* MainMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649ABF5A2BF60D78002E8894 /* MainMenuView.swift */; }; @@ -94,6 +96,8 @@ 645834872BF5FEA000E18321 /* DSQ.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = DSQ.xcframework; sourceTree = ""; }; 645B4C1F2BFCCA0500FD658A /* PlayerResumeFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerResumeFrame.swift; sourceTree = ""; }; 645B4C242BFCD3C600FD658A /* ScoreBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScoreBoardView.swift; sourceTree = ""; }; + 646FA83D2C072340001466BA /* GameVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameVM.swift; sourceTree = ""; }; + 646FA8422C0730D6001466BA /* HistoricVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoricVM.swift; sourceTree = ""; }; 6493C1BF2C046BF900B5121D /* samurai.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = samurai.ttf; sourceTree = ""; }; 6493C1C12C046E5E00B5121D /* Fonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = ""; }; 649ABF5A2BF60D78002E8894 /* MainMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuView.swift; sourceTree = ""; }; @@ -255,10 +259,20 @@ 646FA83C2C072284001466BA /* ViewModel */ = { isa = PBXGroup; children = ( + 646FA83F2C0730B4001466BA /* Game */, ); path = ViewModel; sourceTree = ""; }; + 646FA83F2C0730B4001466BA /* Game */ = { + isa = PBXGroup; + children = ( + 646FA83D2C072340001466BA /* GameVM.swift */, + 646FA8422C0730D6001466BA /* HistoricVM.swift */, + ); + path = Game; + sourceTree = ""; + }; 6493C1BE2C04650200B5121D /* Menu */ = { isa = PBXGroup; children = ( @@ -510,7 +524,9 @@ 643AB69B2BFCFB5C0018DA73 /* HistoricView.swift in Sources */, EC62C50F2C05D06A0048CD0B /* AddPlayerView.swift in Sources */, 6458345E2BF5F92300E18321 /* ContentView.swift in Sources */, + 646FA83E2C072340001466BA /* GameVM.swift in Sources */, 649B59A92BF64C6A002BAE38 /* Colors.swift in Sources */, + 646FA8432C0730D6001466BA /* HistoricVM.swift in Sources */, 649B59B42BF653E1002BAE38 /* ViewTitleTextStyle.swift in Sources */, EC62C5012C045B590048CD0B /* SoundPlayer.swift in Sources */, EC05BFC82C04D832000F7B19 /* CustomSwitchButton.swift in Sources */, diff --git a/DouShouQi_App/DouShouQi_App/Components/Game/GameResumeFrame.swift b/DouShouQi_App/DouShouQi_App/Components/Game/GameResumeFrame.swift index dade4f8..56d49cc 100644 --- a/DouShouQi_App/DouShouQi_App/Components/Game/GameResumeFrame.swift +++ b/DouShouQi_App/DouShouQi_App/Components/Game/GameResumeFrame.swift @@ -6,24 +6,23 @@ // import SwiftUI +#if DEBUG +import DouShouQiModel +#endif struct GameResumeFrame: View { // Players Params - let Player1Name: String - let Player2Name: String - - // Game Params - let Status: String + let gameVM: GameVM var body: some View { ZStack { HStack(alignment: .center) { VStack(alignment: .leading) { - Text("\(Player1Name) vs \(Player2Name)") + Text("\(gameVM.player1Name) vs \(gameVM.player2Name)") .font(.headline) - Text(Status) + Text(gameVM.gameStatus) .font(.subheadline) .foregroundColor(.gray) } @@ -46,6 +45,11 @@ struct GameResumeFrame: View { struct GameResumeFrame_Previews: PreviewProvider { static var previews: some View { - GameResumeFrame(Player1Name: "Rayhan", Player2Name: "Remi", Status: "Winner: Remi") + do { + let game = try Game(withRules: VerySimpleRules(), andPlayer1: HumanPlayer(withName: "Rémi", andId: .player1)!, andPlayer2: HumanPlayer(withName: "Nathan", andId: .player2)!) + return AnyView(GameResumeFrame(gameVM: GameVM(withGame: game))) + } catch { + return AnyView(Text("Erreur lors de la création du jeu : \(error.localizedDescription)")) + } } } diff --git a/DouShouQi_App/DouShouQi_App/Components/MainMenuButton.swift b/DouShouQi_App/DouShouQi_App/Components/MainMenuButton.swift index b421b74..0817a21 100644 --- a/DouShouQi_App/DouShouQi_App/Components/MainMenuButton.swift +++ b/DouShouQi_App/DouShouQi_App/Components/MainMenuButton.swift @@ -92,6 +92,6 @@ struct RoundedCornersShape: Shape { struct MainMenuButton_Previews: PreviewProvider { static var previews: some View { - MainMenuButton(text: "test", destination: HistoricView(), sound: "TitleScreenButtonSound", horizontalAlignment: .leading, topRightCorner: 10, bottomRightCorner: 10) + MainMenuButton(text: "test", destination: HistoricView(historicVM: HistoricVM()), sound: "TitleScreenButtonSound", horizontalAlignment: .leading, topRightCorner: 10, bottomRightCorner: 10) } } diff --git a/DouShouQi_App/DouShouQi_App/ViewModel/Game/GameVM.swift b/DouShouQi_App/DouShouQi_App/ViewModel/Game/GameVM.swift new file mode 100644 index 0000000..ed4cd14 --- /dev/null +++ b/DouShouQi_App/DouShouQi_App/ViewModel/Game/GameVM.swift @@ -0,0 +1,50 @@ +// +// GameVM.swift +// DouShouQi_App +// +// Created by Rémi REGNAULT on 29/05/2024. +// + +import Foundation +import SwiftUI +import DouShouQiModel + +class GameVM: ObservableObject, Identifiable { + // Properties + var game: Game + + // Computed Properties + public var player1Name: String { + return game.players[.player1]?.name ?? "P1" + } + + public var player2Name: String { + return game.players[.player2]?.name ?? "P2" + } + + public var gameStatus: String { + if let lastMove = game.rules.historic.last { + let (_, result) = game.rules.isGameOver(withBoard: game.board, + andLastRowPlayed: lastMove.rowDestination, + andLastColumnPlayer: lastMove.columnDestination) + switch result { + case .notFinished: + return "Not Finished" + case .even: + return "Draw" + case .winner(let winningPlayer, _): + return "Winner: \(winningPlayer)" + + @unknown default: + return "Not Started" + } + } else { + return "Not Started" + } + } + + // Init + init(withGame game: Game) { + self.game = game + } +} diff --git a/DouShouQi_App/DouShouQi_App/ViewModel/Game/HistoricVM.swift b/DouShouQi_App/DouShouQi_App/ViewModel/Game/HistoricVM.swift new file mode 100644 index 0000000..31a862a --- /dev/null +++ b/DouShouQi_App/DouShouQi_App/ViewModel/Game/HistoricVM.swift @@ -0,0 +1,26 @@ +// +// HistoricVM.swift +// DouShouQi_App +// +// Created by Rémi REGNAULT on 29/05/2024. +// + +import Foundation +import SwiftUI +import DouShouQiModel + +class HistoricVM: ObservableObject { + // Properties + public var gameVMs: [GameVM] + + // Init + init() { + gameVMs = [] + do { + let game = try Game(withRules: VerySimpleRules(), andPlayer1: HumanPlayer(withName: "Rémi", andId: .player1)!, andPlayer2: HumanPlayer(withName: "Nathan", andId: .player2)!) + gameVMs.append(GameVM(withGame: game)) + } catch { + // Do nothing + } + } +} diff --git a/DouShouQi_App/DouShouQi_App/Views/Game/HistoricView.swift b/DouShouQi_App/DouShouQi_App/Views/Game/HistoricView.swift index ece39a7..f32ea59 100644 --- a/DouShouQi_App/DouShouQi_App/Views/Game/HistoricView.swift +++ b/DouShouQi_App/DouShouQi_App/Views/Game/HistoricView.swift @@ -6,16 +6,23 @@ // import SwiftUI +#if DEBUG +import DouShouQiModel +#endif struct HistoricView: View { + + // GameVMs + var historicVM: HistoricVM + var body: some View { VStack { TitlePageFrame(Text: "Historic", ImageWidth: 200, ImageHeight: 200) VStack { - GameResumeFrame(Player1Name: "Remi", Player2Name: "Nathan", Status: "Winner: Nathan") - GameResumeFrame(Player1Name: "Rayhan", Player2Name: "Nathan", Status: "Winner: Nathan") - GameResumeFrame(Player1Name: "Rayhan", Player2Name: "Rémi", Status: "Draw") + List(historicVM.gameVMs) { gameVM in + GameResumeFrame(gameVM: gameVM) + } } .padding(.horizontal, 10) @@ -27,6 +34,6 @@ struct HistoricView: View { struct HistoricView_Previews: PreviewProvider { static var previews: some View { - HistoricView() + HistoricView(historicVM: HistoricVM()) } } diff --git a/DouShouQi_App/DouShouQi_App/Views/Menu/MainMenuView.swift b/DouShouQi_App/DouShouQi_App/Views/Menu/MainMenuView.swift index 57d1be8..133218e 100644 --- a/DouShouQi_App/DouShouQi_App/Views/Menu/MainMenuView.swift +++ b/DouShouQi_App/DouShouQi_App/Views/Menu/MainMenuView.swift @@ -33,7 +33,7 @@ struct MainMenuView: View { HStack { VStack(spacing: 25) { MainMenuButton(text: "Play", destination: ScoreBoardView(), sound: "TitleScreenButtonSound", topRightCorner: 10, bottomRightCorner: 10) - MainMenuButton(text: "Historique", destination: HistoricView(), sound: "TitleScreenButtonSound", topRightCorner: 10, bottomRightCorner: 10) + MainMenuButton(text: "Historique", destination: HistoricView(historicVM: HistoricVM()), sound: "TitleScreenButtonSound", topRightCorner: 10, bottomRightCorner: 10) MainMenuButton(text: "Best Scores", destination: ScoreBoardView(), sound: "TitleScreenButtonSound", topRightCorner: 10, bottomRightCorner: 10) MainMenuButton(text: "Players", destination: PlayersView(), sound: "TitleScreenButtonSound", topRightCorner: 10, bottomRightCorner: 10) MainMenuButton(text: "Settings", destination: SettingsView(), sound: "TitleScreenButtonSound", topRightCorner: 10, bottomRightCorner: 10)