now we can see rank of player

dev_vm_saveHistorique
Rayhân HASSOU 10 months ago
parent 780488deac
commit d5baa35e50

@ -69,6 +69,8 @@
ECF3FD242C25B83000F5E62B /* SelectFighterSound.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = ECF3FD232C25B83000F5E62B /* SelectFighterSound.mp3 */; }; ECF3FD242C25B83000F5E62B /* SelectFighterSound.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = ECF3FD232C25B83000F5E62B /* SelectFighterSound.mp3 */; };
ECF3FD262C25BDCF00F5E62B /* Start.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = ECF3FD252C25BDCF00F5E62B /* Start.mp3 */; }; ECF3FD262C25BDCF00F5E62B /* Start.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = ECF3FD252C25BDCF00F5E62B /* Start.mp3 */; };
ECF3FD282C25C83100F5E62B /* Fight.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = ECF3FD272C25C83100F5E62B /* Fight.mp3 */; }; ECF3FD282C25C83100F5E62B /* Fight.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = ECF3FD272C25C83100F5E62B /* Fight.mp3 */; };
ECF3FD312C2722C600F5E62B /* CDHistoriqueExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF3FD302C2722C600F5E62B /* CDHistoriqueExtension.swift */; };
ECF3FD332C27238F00F5E62B /* Historique.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF3FD322C27238F00F5E62B /* Historique.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -163,6 +165,8 @@
ECF3FD232C25B83000F5E62B /* SelectFighterSound.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = SelectFighterSound.mp3; path = ../../../../../../Downloads/SelectFighterSound.mp3; sourceTree = "<group>"; }; ECF3FD232C25B83000F5E62B /* SelectFighterSound.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = SelectFighterSound.mp3; path = ../../../../../../Downloads/SelectFighterSound.mp3; sourceTree = "<group>"; };
ECF3FD252C25BDCF00F5E62B /* Start.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = Start.mp3; path = ../../../../../../Downloads/Start.mp3; sourceTree = "<group>"; }; ECF3FD252C25BDCF00F5E62B /* Start.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = Start.mp3; path = ../../../../../../Downloads/Start.mp3; sourceTree = "<group>"; };
ECF3FD272C25C83100F5E62B /* Fight.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = Fight.mp3; path = ../../../../../../Downloads/Fight.mp3; sourceTree = "<group>"; }; ECF3FD272C25C83100F5E62B /* Fight.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = Fight.mp3; path = ../../../../../../Downloads/Fight.mp3; sourceTree = "<group>"; };
ECF3FD302C2722C600F5E62B /* CDHistoriqueExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CDHistoriqueExtension.swift; sourceTree = "<group>"; };
ECF3FD322C27238F00F5E62B /* Historique.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Historique.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -450,6 +454,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
EC62C53E2C1C6D1A0048CD0B /* CDPlayerExtension.swift */, EC62C53E2C1C6D1A0048CD0B /* CDPlayerExtension.swift */,
ECF3FD302C2722C600F5E62B /* CDHistoriqueExtension.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -469,6 +474,7 @@
children = ( children = (
ECE7770E2C1C6FB200D354B0 /* CoreData */, ECE7770E2C1C6FB200D354B0 /* CoreData */,
EC62C52C2C197ED10048CD0B /* Player.swift */, EC62C52C2C197ED10048CD0B /* Player.swift */,
ECF3FD322C27238F00F5E62B /* Historique.swift */,
); );
path = Class; path = Class;
sourceTree = "<group>"; sourceTree = "<group>";
@ -672,6 +678,7 @@
649B59A42BF64574002BAE38 /* TitlePageFrame.swift in Sources */, 649B59A42BF64574002BAE38 /* TitlePageFrame.swift in Sources */,
EC0540C42C08A13E0032E9EF /* GameView.swift in Sources */, EC0540C42C08A13E0032E9EF /* GameView.swift in Sources */,
EC05BFC42C04C3C4000F7B19 /* SettingsView.swift in Sources */, EC05BFC42C04C3C4000F7B19 /* SettingsView.swift in Sources */,
ECF3FD312C2722C600F5E62B /* CDHistoriqueExtension.swift in Sources */,
EC62C53D2C1C69200048CD0B /* DouShouQi_App.xcdatamodeld in Sources */, EC62C53D2C1C69200048CD0B /* DouShouQi_App.xcdatamodeld in Sources */,
EC62C50F2C05D06A0048CD0B /* AddPlayerView.swift in Sources */, EC62C50F2C05D06A0048CD0B /* AddPlayerView.swift in Sources */,
EC62C53F2C1C6D1A0048CD0B /* CDPlayerExtension.swift in Sources */, EC62C53F2C1C6D1A0048CD0B /* CDPlayerExtension.swift in Sources */,
@ -684,6 +691,7 @@
ECE777142C2068F400D354B0 /* EditPlayerView.swift in Sources */, ECE777142C2068F400D354B0 /* EditPlayerView.swift in Sources */,
EC62C5382C1C64EE0048CD0B /* CoreManager.swift in Sources */, EC62C5382C1C64EE0048CD0B /* CoreManager.swift in Sources */,
EC62C5252C0F68830048CD0B /* PlayerVM.swift in Sources */, EC62C5252C0F68830048CD0B /* PlayerVM.swift in Sources */,
ECF3FD332C27238F00F5E62B /* Historique.swift in Sources */,
EC62C51B2C09D1790048CD0B /* PlayerStatView.swift in Sources */, EC62C51B2C09D1790048CD0B /* PlayerStatView.swift in Sources */,
649B59B22BF65392002BAE38 /* TextStyles.swift in Sources */, 649B59B22BF65392002BAE38 /* TextStyles.swift in Sources */,
EC62C5092C0467240048CD0B /* SplashScreenView.swift in Sources */, EC62C5092C0467240048CD0B /* SplashScreenView.swift in Sources */,

@ -72,22 +72,83 @@ class CoreDataManager {
print("Failed to fetch player for deletion: \(error)") print("Failed to fetch player for deletion: \(error)")
} }
} }
func updatePlayer(playerVM: PlayerVM) { func updatePlayer(playerVM: PlayerVM) {
let fetchRequest: NSFetchRequest<CDPlayer> = CDPlayer.fetchRequest() let fetchRequest: NSFetchRequest<CDPlayer> = CDPlayer.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "name == %@", playerVM.player.name) fetchRequest.predicate = NSPredicate(format: "name == %@", playerVM.player.name)
do { do {
let players = try context.fetch(fetchRequest) let players = try context.fetch(fetchRequest)
if let playerToUpdate = players.first { if let playerToUpdate = players.first {
playerToUpdate.name = playerVM.player.name playerToUpdate.name = playerVM.player.name
playerToUpdate.photo = playerVM.player.photo playerToUpdate.photo = playerVM.player.photo
saveContext() saveContext()
} else { } else {
print("Player not found") print("Player not found")
}
} catch {
print("Failed to fetch player for update: \(error)")
} }
} catch {
print("Failed to fetch player for update: \(error)")
} }
}
func saveHistorique(historique: Historique) {
let historiqueEntity = CDHistorique(context: context)
historiqueEntity.player1_name = historique.player1_name
historiqueEntity.player2_name = historique.player2_name
historiqueEntity.time = historique.time
historiqueEntity.result = historique.result
saveContext()
}
func fetchHistoriques() -> [CDHistorique] {
let fetchRequest: NSFetchRequest<CDHistorique> = CDHistorique.fetchRequest()
do {
return try context.fetch(fetchRequest)
} catch {
print("Failed to fetch historiques: \(error)")
return []
}
}
func deleteHistorique(historique: Historique) {
let fetchRequest: NSFetchRequest<CDHistorique> = CDHistorique.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "player1_name == %@ AND player2_name == %@ AND time == %@", historique.player1_name, historique.player2_name, historique.time)
do {
let historiques = try context.fetch(fetchRequest)
if let historiqueToDelete = historiques.first {
context.delete(historiqueToDelete)
saveContext()
} else {
print("Historique not found")
}
} catch {
print("Failed to fetch historique for deletion: \(error)")
}
}
func countVictories(for player: String) -> Int {
let fetchRequest: NSFetchRequest<CDHistorique> = CDHistorique.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "(player1_name == %@ AND result == 'win') OR (player2_name == %@ AND result == 'lose')", player, player)
do {
return try context.fetch(fetchRequest).count
} catch {
print("Failed to fetch victories for player: \(error)")
return 0
}
}
func countDefeats(for player: String) -> Int {
let fetchRequest: NSFetchRequest<CDHistorique> = CDHistorique.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "(player1_name == %@ AND result == 'lose') OR (player2_name == %@ AND result == 'win')", player, player)
do {
return try context.fetch(fetchRequest).count
} catch {
print("Failed to fetch defeats for player: \(error)")
return 0
}
}
} }

@ -0,0 +1,22 @@
//
// Historique.swift
// DouShouQi_App
//
// Created by étudiant on 22/06/2024.
//
import Foundation
public class Historique{
var player1_name: String
var player2_name: String
var time: String
var result: String
init(player1_name: String, player2_name: String, time: String, result: String){
self.player1_name = player1_name
self.player2_name = player2_name
self.result = result
self.time = time
}
}

@ -0,0 +1,28 @@
//
// CDHistoriqueExtension.swift
// DouShouQi_App
//
// Created by étudiant on 22/06/2024.
//
import Foundation
import CoreData
extension CDHistorique {
func toModel() -> Historique {
return Historique(
player1_name: self.player1_name ?? "",
player2_name: self.player2_name ?? "",
time: self.time ?? "",
result: self.result ?? ""
)
}
convenience init(player1_name: String, player2_name: String, time: String, result: String, context: NSManagedObjectContext) {
self.init(context: context)
self.player1_name = player1_name
self.player2_name = player2_name
self.time = time
self.result = result
}
}

@ -47,7 +47,7 @@ struct GameResumeFrame_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
do { do {
let game = try Game(withRules: VerySimpleRules(), andPlayer1: HumanPlayer(withName: "Rémi", andId: .player1)!, andPlayer2: HumanPlayer(withName: "Nathan", andId: .player2)!) 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))) return AnyView(GameResumeFrame(gameVM: GameVM(withGame: game, time: "11:01")))
} catch { } catch {
return AnyView(Text("Erreur lors de la création du jeu : \(error.localizedDescription)")) return AnyView(Text("Erreur lors de la création du jeu : \(error.localizedDescription)"))
} }

@ -48,12 +48,12 @@ struct PlayerStatView: View {
} }
HStack { HStack {
Image(systemName: "chart.line.uptrend.xyaxis") Image(systemName: "chart.line.uptrend.xyaxis")
Text("Win Rate : \(String(format: "%.2f", Double(player.win) / Double(player.win + player.loose) * 100))%") Text("Win Rate : \(String(format: "%.2f", (Double(player.win) / Double(player.win + player.loose)) * 100))%")
.font(.title2) .font(.title2)
} }
HStack { HStack {
Image(systemName: "list.number") Image(systemName: "list.number")
Text("Rank : 3") Text("Rank : \(player.rank)")
.font(.title2) .font(.title2)
} }

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22G91" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22G91" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="CDHistorique" representedClassName="CDHistorique" syncable="YES" codeGenerationType="class">
<attribute name="player1_name" optional="YES" attributeType="String"/>
<attribute name="player2_name" optional="YES" attributeType="String"/>
<attribute name="result" optional="YES" attributeType="String"/>
<attribute name="time" optional="YES" attributeType="String"/>
</entity>
<entity name="CDPlayer" representedClassName="CDPlayer" syncable="YES" codeGenerationType="class"> <entity name="CDPlayer" representedClassName="CDPlayer" syncable="YES" codeGenerationType="class">
<attribute name="name" optional="YES" attributeType="String"/> <attribute name="name" optional="YES" attributeType="String"/>
<attribute name="photo" optional="YES" attributeType="String"/> <attribute name="photo" optional="YES" attributeType="String"/>

@ -44,7 +44,7 @@ class GameVM: ObservableObject, Identifiable {
} }
// Init // Init
init(withGame game: Game) { init(withGame game: Game, time: String) {
self.game = game self.game = game
} }
} }

@ -18,7 +18,7 @@ class HistoricVM: ObservableObject {
gameVMs = [] gameVMs = []
do { do {
let game = try Game(withRules: VerySimpleRules(), andPlayer1: HumanPlayer(withName: "Rémi", andId: .player1)!, andPlayer2: HumanPlayer(withName: "Nathan", andId: .player2)!) let game = try Game(withRules: VerySimpleRules(), andPlayer1: HumanPlayer(withName: "Rémi", andId: .player1)!, andPlayer2: HumanPlayer(withName: "Nathan", andId: .player2)!)
gameVMs.append(GameVM(withGame: game)) gameVMs.append(GameVM(withGame: game, time: "11:01"))
} catch { } catch {
// Do nothing // Do nothing
} }

@ -10,21 +10,30 @@ import DouShouQiModel
public class PlayerVM: ObservableObject, Identifiable, Hashable{ public class PlayerVM: ObservableObject, Identifiable, Hashable{
public static func == (lhs: PlayerVM, rhs: PlayerVM) -> Bool { public static func == (lhs: PlayerVM, rhs: PlayerVM) -> Bool {
return lhs.id == rhs.id return lhs.id == rhs.id
} }
public func hash(into hasher: inout Hasher) { public func hash(into hasher: inout Hasher) {
hasher.combine(id) hasher.combine(id)
} }
@Published var player: Player @Published var player: Player
var loose: Int{ var loose: Int {
return 0 return CoreDataManager.shared.countDefeats(for: player.name)
} }
var win: Int{
return 0 var win: Int {
return CoreDataManager.shared.countVictories(for: player.name)
} }
var rank: Int{
var rank: Int {
let allPlayers = CoreDataManager.shared.fetchPlayers()
let allPlayerVMs = allPlayers.map { PlayerVM(player: $0.toModel()) }
let sortedPlayers = allPlayerVMs.sorted { $0.win > $1.win }
if let rankIndex = sortedPlayers.firstIndex(where: { $0.player.name == self.player.name }) {
return rankIndex + 1
}
return 0 return 0
} }
@ -39,6 +48,6 @@ public class PlayerVM: ObservableObject, Identifiable, Hashable{
convenience init() { convenience init() {
self.init(player: Player(name: "IA", photo: "")) self.init(player: Player(name: "IA", photo: ""))
} }
} }

Loading…
Cancel
Save