From 0d20cc6716e4b46ea78bc8c509665d17a009e61e Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Sun, 31 May 2020 14:45:57 +0200 Subject: [PATCH 1/7] Collect baseSpecificMoves in separate function --- .../GoldWars/RoundCalculatorService.swift | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index 8e61759..d495681 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -13,8 +13,6 @@ class RoundCalculatorService { static let sharedInstance = RoundCalculatorService() static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService") - var allPlayerMoves: [String: [PlayerMove]] = [:] - var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:] var entityManager = EntityManager.gameEMInstance var isCalculating = false @@ -27,21 +25,10 @@ class RoundCalculatorService { isCalculating = true let currentSnapshotModel = DataService.sharedInstance.snapshotModel - for playerMove in DataService.sharedInstance.remotePlayerMoves { - addPlayerMove(playerName: playerMove.key, playerMoves: playerMove.value) - } - addPlayerMove(playerName: GKLocalPlayer.local.displayName, playerMoves: DataService.sharedInstance.localPlayerMoves) - - for playerMove in allPlayerMoves { - for move in playerMove.value { - mapPlayerMoveToAttackedBase(playerName: playerMove.key, playerMove: move) - } - } + var baseSpecificMoves = collectBaseSpecificMoves() // TODO: Refactor to a less complex way - for (key, value) in baseSpecificMoves { - let baseId = key - var playerMovesByBase = value + for (baseId, var playerMovesByBase) in baseSpecificMoves { let targetBase = currentSnapshotModel?.baseEntites.filter { $0.baseId == baseId }[0] let possiblyOwnershipMoves = playerMovesByBase.filter { $0.key == targetBase?.ownership} @@ -58,7 +45,7 @@ class RoundCalculatorService { } playerMovesByBase.removeValue(forKey: playerName) } - + for (_, playerMoves) in playerMovesByBase { for playerMove in playerMoves { for base in currentSnapshotModel!.baseEntites { @@ -110,7 +97,6 @@ class RoundCalculatorService { } baseSpecificMoves.removeValue(forKey: baseId) } - allPlayerMoves.removeAll() DataService.sharedInstance.localPlayerMoves.removeAll() MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers() DataService.sharedInstance.snapshotModel = currentSnapshotModel @@ -120,20 +106,35 @@ class RoundCalculatorService { os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info) } - func addPlayerMove(playerName: String, playerMoves: [PlayerMove]) { - self.allPlayerMoves[playerName] = playerMoves - } - - func mapPlayerMoveToAttackedBase(playerName: String, playerMove: PlayerMove) { - if self.baseSpecificMoves.keys.contains(playerMove.toBase) { - if (self.baseSpecificMoves[playerMove.toBase]?.keys.contains(playerName))!{ - self.baseSpecificMoves[playerMove.toBase]?[playerName]?.append(playerMove) - } else { - self.baseSpecificMoves[playerMove.toBase]?.merge([playerName: [playerMove]]){(current, _) in current} - } - } else { - self.baseSpecificMoves[playerMove.toBase] = [playerName: [playerMove]] + func collectBaseSpecificMoves() -> [Int: [String: [PlayerMove]]] { + + var allPlayerMoves: [String: [PlayerMove]] = [:] + + // collect moves from remote player + for playerMove in DataService.sharedInstance.remotePlayerMoves { + allPlayerMoves[playerMove.key] = playerMove.value } + + // collect moves from local player + allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localPlayerMoves + + var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:] + + for playerMove in allPlayerMoves { + for move in playerMove.value { + if baseSpecificMoves.keys.contains(move.toBase) { + if (baseSpecificMoves[move.toBase]?.keys.contains(playerMove.key))!{ + baseSpecificMoves[move.toBase]?[playerMove.key]?.append(move) + } else { + baseSpecificMoves[move.toBase]?.merge([playerMove.key: [move]]){(current, _) in current} + } + } else { + baseSpecificMoves[move.toBase] = [playerMove.key: [move]] + } + } + } + + return baseSpecificMoves } func resolvePlayerMove(playerMove: PlayerMove, unitCount: Int, ownership: String?, resolveType: String) { From 6b1d0eac1258ddbda4e379dca0e275b9ec2cf6dc Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Sun, 31 May 2020 19:04:58 +0200 Subject: [PATCH 2/7] Add atk and def boost to PlayerMove struct --- GoldWars/GoldWars/DataService.swift | 4 +++- GoldWars/GoldWars/Entities/Base.swift | 4 +++- GoldWars/GoldWars/RoundCalculatorService.swift | 15 +++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift index cba4f4d..f3a5591 100644 --- a/GoldWars/GoldWars/DataService.swift +++ b/GoldWars/GoldWars/DataService.swift @@ -6,10 +6,12 @@ // Copyright © 2020 SP2. All rights reserved. // -struct PlayerMove: Codable{ +struct PlayerMove: Codable { let fromBase: Int let toBase: Int var unitCount: Int + let hasDefenceBoost: Bool + let hasAttackBoost: Bool } class SnapshotModel: Codable { diff --git a/GoldWars/GoldWars/Entities/Base.swift b/GoldWars/GoldWars/Entities/Base.swift index 947a6c2..2611b78 100644 --- a/GoldWars/GoldWars/Entities/Base.swift +++ b/GoldWars/GoldWars/Entities/Base.swift @@ -53,7 +53,9 @@ class Base: GKEntity{ base.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(base.unitCount)" DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID, toBase: base.baseID, - unitCount: units * playerMoveType.rawValue)) + unitCount: units * playerMoveType.rawValue, + hasDefenceBoost: base.hasAttackBoost, + hasAttackBoost: base.hasDefenseBoost)) return [self, base] } diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index d495681..2a75942 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -59,11 +59,18 @@ class RoundCalculatorService { var combinePotentionalForces: [String: PlayerMove] = [:] for playerMoves in playerMovesByBase { - combinePotentionalForces[playerMoves.key] = PlayerMove(fromBase: playerMoves.value[0].fromBase, toBase: playerMoves.value[0].toBase, unitCount: 0) + combinePotentionalForces[playerMoves.key] = PlayerMove( + fromBase: playerMoves.value[0].fromBase, + toBase: playerMoves.value[0].toBase, + unitCount: 0, + hasDefenceBoost: playerMoves.value[0].hasDefenceBoost, + hasAttackBoost: playerMoves.value[0].hasDefenceBoost + ) for move in playerMoves.value { combinePotentionalForces[playerMoves.key]!.unitCount += move.unitCount } } + if(combinePotentionalForces.count > 0) { let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount } @@ -77,11 +84,7 @@ class RoundCalculatorService { if base.baseId == playerMoveWithMaxUnits.value.toBase { if base.ownership == nil { base.unitCount += playerMoveWithMaxUnits.value.unitCount - if playerMoveWithMaxUnits.value.unitCount == 0 { - base.ownership = nil - } else { - base.ownership = playerMoveWithMaxUnits.key - } + base.ownership = playerMoveWithMaxUnits.value.unitCount == 0 ? nil : playerMoveWithMaxUnits.key } else { if base.unitCount < playerMoveWithMaxUnits.value.unitCount { base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount From a4239421824b1fe91c8e1ff5654fb685b702ea05 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Sun, 31 May 2020 23:14:06 +0200 Subject: [PATCH 3/7] Send boosts with snapshot model, increase unit counts accordingly --- GoldWars/GoldWars/DataService.swift | 8 ++++--- GoldWars/GoldWars/Entities/Base.swift | 5 ++-- .../GoldWars/Entities/EntityManager.swift | 10 +++++++- .../GoldWars/RoundCalculatorService.swift | 24 +++++++++++-------- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift index f3a5591..93fba09 100644 --- a/GoldWars/GoldWars/DataService.swift +++ b/GoldWars/GoldWars/DataService.swift @@ -10,8 +10,6 @@ struct PlayerMove: Codable { let fromBase: Int let toBase: Int var unitCount: Int - let hasDefenceBoost: Bool - let hasAttackBoost: Bool } class SnapshotModel: Codable { @@ -26,11 +24,15 @@ class BaseEntityModel: Codable { let baseId: Int var unitCount: Int var ownership: String? + var hasAttackBoost: Bool + var hasDefenceBoost: Bool - init(baseId: Int, unitCount: Int, ownership: String?) { + init(baseId: Int, unitCount: Int, ownership: String?, hasAttackBoost: Bool, hasDefenceBoost: Bool) { self.baseId = baseId self.unitCount = unitCount self.ownership = ownership + self.hasAttackBoost = hasAttackBoost + self.hasDefenceBoost = hasDefenceBoost } } diff --git a/GoldWars/GoldWars/Entities/Base.swift b/GoldWars/GoldWars/Entities/Base.swift index 2611b78..1306885 100644 --- a/GoldWars/GoldWars/Entities/Base.swift +++ b/GoldWars/GoldWars/Entities/Base.swift @@ -53,9 +53,8 @@ class Base: GKEntity{ base.component(ofType: DefaultBaseComponent.self)?.labelNode.text = "\(base.unitCount)" DataService.sharedInstance.addMove(playerMove: PlayerMove(fromBase: self.baseID, toBase: base.baseID, - unitCount: units * playerMoveType.rawValue, - hasDefenceBoost: base.hasAttackBoost, - hasAttackBoost: base.hasDefenseBoost)) + unitCount: units * playerMoveType.rawValue) + ) return [self, base] } diff --git a/GoldWars/GoldWars/Entities/EntityManager.swift b/GoldWars/GoldWars/Entities/EntityManager.swift index 6bf1d5b..1e44273 100644 --- a/GoldWars/GoldWars/Entities/EntityManager.swift +++ b/GoldWars/GoldWars/Entities/EntityManager.swift @@ -249,7 +249,15 @@ class EntityManager { for entity in bases { let base = entity as! Base - snapBase.append(BaseEntityModel(baseId: base.baseID, unitCount: base.unitCount, ownership: base.ownershipPlayer?.displayName)) + snapBase.append( + BaseEntityModel( + baseId: base.baseID, + unitCount: base.unitCount, + ownership: base.ownershipPlayer?.displayName, + hasAttackBoost: base.hasAttackBoost, + hasDefenceBoost: base.hasDefenseBoost + ) + ) } return SnapshotModel(baseEntites: snapBase) diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index 2a75942..60894d4 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -13,6 +13,9 @@ class RoundCalculatorService { static let sharedInstance = RoundCalculatorService() static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService") + let ATK_BOOST_MULTIPLICATOR = 1.1 + let DEF_BOOST_MULTIPLICATOR = 1.1 + var entityManager = EntityManager.gameEMInstance var isCalculating = false @@ -62,37 +65,38 @@ class RoundCalculatorService { combinePotentionalForces[playerMoves.key] = PlayerMove( fromBase: playerMoves.value[0].fromBase, toBase: playerMoves.value[0].toBase, - unitCount: 0, - hasDefenceBoost: playerMoves.value[0].hasDefenceBoost, - hasAttackBoost: playerMoves.value[0].hasDefenceBoost + unitCount: 0 ) for move in playerMoves.value { combinePotentionalForces[playerMoves.key]!.unitCount += move.unitCount } } - if(combinePotentionalForces.count > 0) { + if combinePotentionalForces.count > 0 { let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount } var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0] + playerMoveWithMaxUnits.value.unitCount = Int(Double(playerMoveWithMaxUnits.value.unitCount) * ((currentSnapshotModel?.baseEntites[playerMoveWithMaxUnits.value.fromBase].hasAttackBoost)! ? ATK_BOOST_MULTIPLICATOR : 1)) if playerMovesByBase.count >= 2 { - let playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1] - playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount + var playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1] + playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ((currentSnapshotModel?.baseEntites[playerMoveWithSecMaxUnits.value.fromBase].hasAttackBoost)! ? ATK_BOOST_MULTIPLICATOR : 1)) + playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount // Apply Boost } for base in currentSnapshotModel!.baseEntites { if base.baseId == playerMoveWithMaxUnits.value.toBase { + base.unitCount = Int(Double(base.unitCount) * (base.hasDefenceBoost ? DEF_BOOST_MULTIPLICATOR : 1)) if base.ownership == nil { - base.unitCount += playerMoveWithMaxUnits.value.unitCount + base.unitCount += playerMoveWithMaxUnits.value.unitCount // Apply Boost base.ownership = playerMoveWithMaxUnits.value.unitCount == 0 ? nil : playerMoveWithMaxUnits.key } else { if base.unitCount < playerMoveWithMaxUnits.value.unitCount { - base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount + base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount // Apply Boost base.ownership = playerMoveWithMaxUnits.key } else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) { base.ownership = nil } else { - base.unitCount -= playerMoveWithMaxUnits.value.unitCount + base.unitCount -= playerMoveWithMaxUnits.value.unitCount // Apply Boost } } } @@ -126,7 +130,7 @@ class RoundCalculatorService { for playerMove in allPlayerMoves { for move in playerMove.value { if baseSpecificMoves.keys.contains(move.toBase) { - if (baseSpecificMoves[move.toBase]?.keys.contains(playerMove.key))!{ + if (baseSpecificMoves[move.toBase]?.keys.contains(playerMove.key))! { baseSpecificMoves[move.toBase]?[playerMove.key]?.append(move) } else { baseSpecificMoves[move.toBase]?.merge([playerMove.key: [move]]){(current, _) in current} From 4c9d83c7cb6dd05a674ca137fd2abe99414e6db6 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 1 Jun 2020 17:27:13 +0200 Subject: [PATCH 4/7] Add localRoundData Send boosts --- .../GoldWars/Components/TimerComponent.swift | 2 +- GoldWars/GoldWars/DataService.swift | 26 ++++++----- GoldWars/GoldWars/Entities/HUD.swift | 4 +- GoldWars/GoldWars/GameCenterManager.swift | 4 +- GoldWars/GoldWars/MultiplayerNetwork.swift | 8 ++-- .../GoldWars/RoundCalculatorService.swift | 45 ++++++++++++++----- 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/GoldWars/GoldWars/Components/TimerComponent.swift b/GoldWars/GoldWars/Components/TimerComponent.swift index fc6df85..a799b69 100644 --- a/GoldWars/GoldWars/Components/TimerComponent.swift +++ b/GoldWars/GoldWars/Components/TimerComponent.swift @@ -57,7 +57,7 @@ class TimerComponent: GKComponent { self.labelNode.text = "Synching" RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats() if !MultiplayerNetwork.sharedInstance.isSending { - MultiplayerNetwork.sharedInstance.sendPlayerMoves(playerMoves: DataService.sharedInstance.localPlayerMoves) + MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData!) } if !RoundCalculatorService.sharedInstance.isCalculating && DataService.sharedInstance.didReceiveAllData() diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift index 93fba09..910cb9e 100644 --- a/GoldWars/GoldWars/DataService.swift +++ b/GoldWars/GoldWars/DataService.swift @@ -12,6 +12,12 @@ struct PlayerMove: Codable { var unitCount: Int } +struct LocalRoundData: Codable { + var localPlayerMoves: [PlayerMove] + var hasAttackBoost: Bool + var hasDefenceBoost: Bool +} + class SnapshotModel: Codable { var baseEntites: [BaseEntityModel] @@ -24,22 +30,18 @@ class BaseEntityModel: Codable { let baseId: Int var unitCount: Int var ownership: String? - var hasAttackBoost: Bool - var hasDefenceBoost: Bool init(baseId: Int, unitCount: Int, ownership: String?, hasAttackBoost: Bool, hasDefenceBoost: Bool) { self.baseId = baseId self.unitCount = unitCount self.ownership = ownership - self.hasAttackBoost = hasAttackBoost - self.hasDefenceBoost = hasDefenceBoost } } class DataService { static let sharedInstance = DataService() - var localPlayerMoves: [PlayerMove] = [] - var remotePlayerMoves: [String: [PlayerMove]] = [:] + var localRoundData: LocalRoundData? + var remotePlayerMoves: [String: LocalRoundData] = [:] var snapshotModel: SnapshotModel? var hostingPlayer = GameCenterManager.sharedInstance.hostingPlayer @@ -47,18 +49,18 @@ class DataService { var entityManager = EntityManager.gameEMInstance func addMove(playerMove: PlayerMove) { - var equalMove = localPlayerMoves.filter { (ele) -> Bool in + var equalMove = localRoundData?.localPlayerMoves.filter { (ele) -> Bool in ele.fromBase == playerMove.fromBase && ele.toBase == playerMove.toBase } - if equalMove.count == 1 { - equalMove[0].unitCount = Int(equalMove[0].unitCount) + Int(playerMove.unitCount) + if equalMove!.count == 1 { + equalMove![0].unitCount = Int(equalMove![0].unitCount) + Int(playerMove.unitCount) } else { - self.localPlayerMoves.append(playerMove) + self.localRoundData?.localPlayerMoves.append(playerMove) } } - func addRemotePlayerMoves(playerName: String, playerMoves: [PlayerMove]) { - self.remotePlayerMoves[playerName] = playerMoves + func addRemotePlayerMoves(playerName: String, localRoundData: LocalRoundData) { + self.remotePlayerMoves[playerName] = localRoundData } func didReceiveAllData() -> Bool { diff --git a/GoldWars/GoldWars/Entities/HUD.swift b/GoldWars/GoldWars/Entities/HUD.swift index 3b71497..633b61b 100644 --- a/GoldWars/GoldWars/Entities/HUD.swift +++ b/GoldWars/GoldWars/Entities/HUD.swift @@ -44,14 +44,14 @@ class HUD: GKEntity { text: "Def", isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.85, y: EntityManager.gameEMInstance.scene.size.height * 0.1), - onButtonPress: {EntityManager.gameEMInstance.getBasesByTeam(for: .team2).forEach({base in base.hasDefenseBoost = true})} + onButtonPress: {DataService.sharedInstance.localRoundData?.hasDefenceBoost = true} ) atkSkill = SingeClickButtonNode( textureName: "yellow_circle", text: "Atk", isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.95, y: EntityManager.gameEMInstance.scene.size.height * 0.1), - onButtonPress: {EntityManager.gameEMInstance.getBasesByTeam(for: .team2).forEach({base in base.hasAttackBoost = true})} + onButtonPress: {DataService.sharedInstance.localRoundData?.hasAttackBoost = true} ) super.init() hostLabel.position = CGPoint(x: size.width * 0.02, y: size.height * 0.95) diff --git a/GoldWars/GoldWars/GameCenterManager.swift b/GoldWars/GoldWars/GameCenterManager.swift index 7571212..8b7ab1e 100644 --- a/GoldWars/GoldWars/GameCenterManager.swift +++ b/GoldWars/GoldWars/GameCenterManager.swift @@ -122,8 +122,8 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate ,GKM break } } - if let playerMoves = try? jsonDecoder.decode([PlayerMove].self, from: data) { - DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, playerMoves: playerMoves) + if let roundData = try? jsonDecoder.decode(LocalRoundData.self, from: data) { + DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, localRoundData: roundData) } if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) { DataService.sharedInstance.snapshotModel = snapshotModel diff --git a/GoldWars/GoldWars/MultiplayerNetwork.swift b/GoldWars/GoldWars/MultiplayerNetwork.swift index 89b1479..bd9f9eb 100644 --- a/GoldWars/GoldWars/MultiplayerNetwork.swift +++ b/GoldWars/GoldWars/MultiplayerNetwork.swift @@ -36,13 +36,15 @@ class MultiplayerNetwork{ } } - func sendPlayerMoves(playerMoves: [PlayerMove]) { + func sendPlayerMoves(localRoundData: LocalRoundData) { if GameCenterManager.sharedInstance.isServer == false { self.isSending = true let encoder = JSONEncoder() - let encoded = (try? encoder.encode(playerMoves))! + let encoded = (try? encoder.encode(localRoundData))! sendDataToHost(data: encoded) - DataService.sharedInstance.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData!.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData!.hasAttackBoost = false + DataService.sharedInstance.localRoundData!.hasDefenceBoost = false } } diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index 60894d4..337af11 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -16,6 +16,9 @@ class RoundCalculatorService { let ATK_BOOST_MULTIPLICATOR = 1.1 let DEF_BOOST_MULTIPLICATOR = 1.1 + // TODO: Better data structure + var boosts: [String: (Bool, Bool)] = [:] // First bool is atk boost, second is def boost + var entityManager = EntityManager.gameEMInstance var isCalculating = false @@ -76,27 +79,35 @@ class RoundCalculatorService { let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount } var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0] - playerMoveWithMaxUnits.value.unitCount = Int(Double(playerMoveWithMaxUnits.value.unitCount) * ((currentSnapshotModel?.baseEntites[playerMoveWithMaxUnits.value.fromBase].hasAttackBoost)! ? ATK_BOOST_MULTIPLICATOR : 1)) + if playerMovesByBase.count >= 2 { var playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1] - playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ((currentSnapshotModel?.baseEntites[playerMoveWithSecMaxUnits.value.fromBase].hasAttackBoost)! ? ATK_BOOST_MULTIPLICATOR : 1)) - playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount // Apply Boost + if boosts[playerMoveWithMaxUnits.key]!.0 { + playerMoveWithMaxUnits.value.unitCount = Int(Double(playerMoveWithMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR) + } + if boosts[playerMoveWithSecMaxUnits.key]!.0 { + playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR) + } + playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount } for base in currentSnapshotModel!.baseEntites { if base.baseId == playerMoveWithMaxUnits.value.toBase { - base.unitCount = Int(Double(base.unitCount) * (base.hasDefenceBoost ? DEF_BOOST_MULTIPLICATOR : 1)) if base.ownership == nil { - base.unitCount += playerMoveWithMaxUnits.value.unitCount // Apply Boost + base.unitCount += playerMoveWithMaxUnits.value.unitCount base.ownership = playerMoveWithMaxUnits.value.unitCount == 0 ? nil : playerMoveWithMaxUnits.key } else { + if boosts[base.ownership!]!.1 { + base.unitCount = Int(Double(base.unitCount) * DEF_BOOST_MULTIPLICATOR) + } if base.unitCount < playerMoveWithMaxUnits.value.unitCount { - base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount // Apply Boost + base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount base.ownership = playerMoveWithMaxUnits.key } else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) { base.ownership = nil + base.unitCount = 0 } else { - base.unitCount -= playerMoveWithMaxUnits.value.unitCount // Apply Boost + base.unitCount -= playerMoveWithMaxUnits.value.unitCount } } } @@ -104,7 +115,9 @@ class RoundCalculatorService { } baseSpecificMoves.removeValue(forKey: baseId) } - DataService.sharedInstance.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData?.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData?.hasAttackBoost = false + DataService.sharedInstance.localRoundData?.hasDefenceBoost = false MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers() DataService.sharedInstance.snapshotModel = currentSnapshotModel entityManager.updateSnapshotModel(snapshotModel: currentSnapshotModel!) @@ -119,11 +132,21 @@ class RoundCalculatorService { // collect moves from remote player for playerMove in DataService.sharedInstance.remotePlayerMoves { - allPlayerMoves[playerMove.key] = playerMove.value + allPlayerMoves[playerMove.key] = playerMove.value.localPlayerMoves } + boosts[GameCenterManager.sharedInstance.hostingPlayer!.displayName] = ( + DataService.sharedInstance.localRoundData!.hasAttackBoost, + DataService.sharedInstance.localRoundData!.hasDefenceBoost + ) + + boosts[GameCenterManager.sharedInstance.peerPlayer!.displayName] = ( + DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]!.hasAttackBoost, + DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]!.hasDefenceBoost + ) + // collect moves from local player - allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localPlayerMoves + allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localRoundData?.localPlayerMoves var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:] @@ -141,6 +164,8 @@ class RoundCalculatorService { } } + DataService.sharedInstance.remotePlayerMoves.removeAll() + return baseSpecificMoves } From 2820c7357a04488dcf4d544d1c5801b49949511a Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 1 Jun 2020 17:37:43 +0200 Subject: [PATCH 5/7] Remove optionals on localRoundData --- .../GoldWars/Components/TimerComponent.swift | 2 +- GoldWars/GoldWars/DataService.swift | 16 +++++++++++----- GoldWars/GoldWars/Entities/HUD.swift | 4 ++-- GoldWars/GoldWars/MultiplayerNetwork.swift | 6 +++--- GoldWars/GoldWars/RoundCalculatorService.swift | 12 ++++++------ 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/GoldWars/GoldWars/Components/TimerComponent.swift b/GoldWars/GoldWars/Components/TimerComponent.swift index a799b69..1a7e678 100644 --- a/GoldWars/GoldWars/Components/TimerComponent.swift +++ b/GoldWars/GoldWars/Components/TimerComponent.swift @@ -57,7 +57,7 @@ class TimerComponent: GKComponent { self.labelNode.text = "Synching" RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats() if !MultiplayerNetwork.sharedInstance.isSending { - MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData!) + MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData) } if !RoundCalculatorService.sharedInstance.isCalculating && DataService.sharedInstance.didReceiveAllData() diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift index 910cb9e..23fe5f2 100644 --- a/GoldWars/GoldWars/DataService.swift +++ b/GoldWars/GoldWars/DataService.swift @@ -16,6 +16,12 @@ struct LocalRoundData: Codable { var localPlayerMoves: [PlayerMove] var hasAttackBoost: Bool var hasDefenceBoost: Bool + + init() { + localPlayerMoves = [] + hasAttackBoost = false + hasDefenceBoost = false + } } class SnapshotModel: Codable { @@ -40,7 +46,7 @@ class BaseEntityModel: Codable { class DataService { static let sharedInstance = DataService() - var localRoundData: LocalRoundData? + var localRoundData: LocalRoundData = LocalRoundData() var remotePlayerMoves: [String: LocalRoundData] = [:] var snapshotModel: SnapshotModel? var hostingPlayer = GameCenterManager.sharedInstance.hostingPlayer @@ -49,13 +55,13 @@ class DataService { var entityManager = EntityManager.gameEMInstance func addMove(playerMove: PlayerMove) { - var equalMove = localRoundData?.localPlayerMoves.filter { (ele) -> Bool in + var equalMove = localRoundData.localPlayerMoves.filter { (ele) -> Bool in ele.fromBase == playerMove.fromBase && ele.toBase == playerMove.toBase } - if equalMove!.count == 1 { - equalMove![0].unitCount = Int(equalMove![0].unitCount) + Int(playerMove.unitCount) + if equalMove.count == 1 { + equalMove[0].unitCount = Int(equalMove[0].unitCount) + Int(playerMove.unitCount) } else { - self.localRoundData?.localPlayerMoves.append(playerMove) + self.localRoundData.localPlayerMoves.append(playerMove) } } diff --git a/GoldWars/GoldWars/Entities/HUD.swift b/GoldWars/GoldWars/Entities/HUD.swift index 633b61b..4229f3f 100644 --- a/GoldWars/GoldWars/Entities/HUD.swift +++ b/GoldWars/GoldWars/Entities/HUD.swift @@ -44,14 +44,14 @@ class HUD: GKEntity { text: "Def", isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.85, y: EntityManager.gameEMInstance.scene.size.height * 0.1), - onButtonPress: {DataService.sharedInstance.localRoundData?.hasDefenceBoost = true} + onButtonPress: {DataService.sharedInstance.localRoundData.hasDefenceBoost = true} ) atkSkill = SingeClickButtonNode( textureName: "yellow_circle", text: "Atk", isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.95, y: EntityManager.gameEMInstance.scene.size.height * 0.1), - onButtonPress: {DataService.sharedInstance.localRoundData?.hasAttackBoost = true} + onButtonPress: {DataService.sharedInstance.localRoundData.hasAttackBoost = true} ) super.init() hostLabel.position = CGPoint(x: size.width * 0.02, y: size.height * 0.95) diff --git a/GoldWars/GoldWars/MultiplayerNetwork.swift b/GoldWars/GoldWars/MultiplayerNetwork.swift index bd9f9eb..985ec14 100644 --- a/GoldWars/GoldWars/MultiplayerNetwork.swift +++ b/GoldWars/GoldWars/MultiplayerNetwork.swift @@ -42,9 +42,9 @@ class MultiplayerNetwork{ let encoder = JSONEncoder() let encoded = (try? encoder.encode(localRoundData))! sendDataToHost(data: encoded) - DataService.sharedInstance.localRoundData!.localPlayerMoves.removeAll() - DataService.sharedInstance.localRoundData!.hasAttackBoost = false - DataService.sharedInstance.localRoundData!.hasDefenceBoost = false + DataService.sharedInstance.localRoundData.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData.hasAttackBoost = false + DataService.sharedInstance.localRoundData.hasDefenceBoost = false } } diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index 337af11..5792e59 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -115,9 +115,9 @@ class RoundCalculatorService { } baseSpecificMoves.removeValue(forKey: baseId) } - DataService.sharedInstance.localRoundData?.localPlayerMoves.removeAll() - DataService.sharedInstance.localRoundData?.hasAttackBoost = false - DataService.sharedInstance.localRoundData?.hasDefenceBoost = false + DataService.sharedInstance.localRoundData.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData.hasAttackBoost = false + DataService.sharedInstance.localRoundData.hasDefenceBoost = false MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers() DataService.sharedInstance.snapshotModel = currentSnapshotModel entityManager.updateSnapshotModel(snapshotModel: currentSnapshotModel!) @@ -136,8 +136,8 @@ class RoundCalculatorService { } boosts[GameCenterManager.sharedInstance.hostingPlayer!.displayName] = ( - DataService.sharedInstance.localRoundData!.hasAttackBoost, - DataService.sharedInstance.localRoundData!.hasDefenceBoost + DataService.sharedInstance.localRoundData.hasAttackBoost, + DataService.sharedInstance.localRoundData.hasDefenceBoost ) boosts[GameCenterManager.sharedInstance.peerPlayer!.displayName] = ( @@ -146,7 +146,7 @@ class RoundCalculatorService { ) // collect moves from local player - allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localRoundData?.localPlayerMoves + allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localRoundData.localPlayerMoves var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:] From 64d2c04fcbda888533c646072ff5aee04491d692 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 1 Jun 2020 18:29:17 +0200 Subject: [PATCH 6/7] Swap playWithMaxUnits after applying boosts --- GoldWars/GoldWars/RoundCalculatorService.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index 5792e59..af824c4 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -88,6 +88,13 @@ class RoundCalculatorService { if boosts[playerMoveWithSecMaxUnits.key]!.0 { playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR) } + + if playerMoveWithMaxUnits.value.unitCount < playerMoveWithSecMaxUnits.value.unitCount { + let temp = playerMoveWithMaxUnits + playerMoveWithMaxUnits = playerMoveWithSecMaxUnits + playerMoveWithSecMaxUnits = temp + } + playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount } From dab98b92563cf36f7c6895654cf6f4b18e1cce1c Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 1 Jun 2020 19:12:47 +0200 Subject: [PATCH 7/7] Fix ownership after snapshotReveive --- GoldWars/GoldWars/Entities/EntityManager.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/GoldWars/GoldWars/Entities/EntityManager.swift b/GoldWars/GoldWars/Entities/EntityManager.swift index 1e44273..04e02fc 100644 --- a/GoldWars/GoldWars/Entities/EntityManager.swift +++ b/GoldWars/GoldWars/Entities/EntityManager.swift @@ -136,6 +136,7 @@ class EntityManager { getOwnerBySnapBase = GameCenterManager.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!) } else { entity.removeComponent(ofType: TeamComponent.self) + base.ownershipPlayer = nil } if getOwnerBySnapBase != nil { if getOwnerBySnapBase == GKLocalPlayer.local {