still fixing stuff on loserbracket management

multistore
Razmig Sarkissian 2 years ago
parent c0475025ab
commit e5086fac19
  1. 6
      PadelClub/Data/Match.swift
  2. 49
      PadelClub/Data/Round.swift
  3. 1
      PadelClub/Data/TeamRegistration.swift
  4. 75
      PadelClub/Data/Tournament.swift
  5. 9
      PadelClub/ViewModel/SeedInterval.swift
  6. 1
      PadelClub/Views/Match/PlayerBlockView.swift
  7. 14
      PadelClub/Views/Round/LoserRoundsView.swift
  8. 85
      PadelClub/Views/Round/RoundSettingsView.swift
  9. 11
      PadelClub/Views/Round/RoundView.swift

@ -126,19 +126,17 @@ class Match: ModelObject, Storable {
_toggleMatchDisableState(false)
}
func _toggleLoserMatchDisableState(_ state: Bool) {
private func _toggleLoserMatchDisableState(_ state: Bool) {
if isLoserBracket == false {
let indexInRound = RoundRule.matchIndexWithinRound(fromMatchIndex: index)
if let loserMatch = roundObject?.loserRounds().first?.getMatch(atMatchIndexInRound: indexInRound / 2) {
print("disabling first loserround", state, loserMatch.matchTitle(.wide))
loserMatch.disabled = state
try? DataStore.shared.matches.addOrUpdate(instance: loserMatch)
loserMatch._toggleLoserMatchDisableState(state)
}
} else {
roundObject?.loserRounds().forEach({ round in
print("disabling", state, round.roundTitle())
round.disableLoserRound(state)
round.handleLoserRoundState()
})
}
}

@ -140,10 +140,10 @@ class Round: ModelObject, Storable {
func getMatch(atMatchIndexInRound matchIndexInRound: Int) -> Match? {
_matches().first(where: {
Store.main.filter(isIncluded: {
let index = RoundRule.matchIndexWithinRound(fromMatchIndex: $0.index)
return index == matchIndexInRound
})
return $0.round == id && index == matchIndexInRound
}).first
}
func playedMatches() -> [Match] {
@ -176,32 +176,53 @@ class Round: ModelObject, Storable {
}
func enableRound() {
_toggleRound(disable: false)
}
func disableRound() {
_toggleRound(disable: true)
}
private func _toggleRound(disable: Bool) {
let _matches = _matches()
_matches.forEach { match in
match.disabled = false
match.disabled = disable
match.resetMatch()
try? DataStore.shared.teamScores.delete(contentOfs: match.teamScores)
}
try? DataStore.shared.matches.addOrUpdate(contentOfs: _matches)
}
func disableLoserRound(_ disable: Bool) {
func handleLoserRoundState() {
let _matches = _matches()
_matches.forEach { match in
if disable {
if upperBracketTopMatch(ofMatchIndex: match.index)?.disabled == true || upperBracketBottomMatch(ofMatchIndex: match.index)?.disabled == true {
match.disabled = true
}
} else {
if upperBracketTopMatch(ofMatchIndex: match.index)?.disabled == false && upperBracketBottomMatch(ofMatchIndex: match.index)?.disabled == false {
match.disabled = false
}
let previousRound = self.previousRound()
let indexInRound = RoundRule.matchIndexWithinRound(fromMatchIndex: match.index)
var parentMatches = [Match]()
if isLoserBracket(), previousRound == nil, let parentRound = parentRound {
let upperBracketTopMatch = parentRound.getMatch(atMatchIndexInRound: indexInRound * 2)
let upperBracketBottomMatch = parentRound.getMatch(atMatchIndexInRound: indexInRound * 2 + 1)
parentMatches = [upperBracketTopMatch, upperBracketBottomMatch].compactMap({ $0 })
} else if let previousRound {
let previousRoundTopMatch : Match? = Store.main.filter {
$0.round == previousRound.id && $0.index == match.topPreviousRoundMatchIndex()
}.first
let previousRoundBottomMatch : Match? = Store.main.filter {
$0.round == previousRound.id && $0.index == match.bottomPreviousRoundMatchIndex()
}.first
parentMatches = [previousRoundTopMatch, previousRoundBottomMatch].compactMap({ $0 })
}
if parentMatches.anySatisfy({ $0.disabled }) {
match.disabled = true
} else if parentMatches.allSatisfy({ $0.disabled == false }) {
match.disabled = false
}
}
try? DataStore.shared.matches.addOrUpdate(contentOfs: _matches)
loserRounds().forEach { round in
round.disableLoserRound(disable)
round.handleLoserRoundState()
}
}

@ -62,7 +62,6 @@ class TeamRegistration: ModelObject, Storable {
if opposingSeeding {
teamPosition = slot ?? (isUpper ? .two : .one)
}
match.enableMatch()
match.previousMatch(teamPosition)?.disableMatch()
bracketPosition = matchIndex * 2 + teamPosition.rawValue
}

@ -143,11 +143,11 @@ class Tournament : ModelObject, Storable {
return seeds().filter { $0.isSeedable() }
}
func lastSeedRound() -> Int? {
func lastSeedRound() -> Int {
if let last = seeds().filter({ $0.bracketPosition != nil }).last {
return RoundRule.roundIndex(fromMatchIndex: last.bracketPosition! / 2)
} else {
return nil
return 0
}
}
@ -213,24 +213,67 @@ class Tournament : ModelObject, Storable {
return availableSeeds
}
func setSeeds(inRoundIndex roundIndex: Int, inSeedGroup seedGroup: SeedInterval) {
let availableSeedSpot = availableSeedSpot(inRoundIndex: roundIndex)
let availableSeedOpponentSpot = availableSeedOpponentSpot(inRoundIndex: roundIndex)
let availableSeeds = seeds(inSeedGroup: seedGroup)
func seedGroupAvailable(atRoundIndex roundIndex: Int) -> SeedInterval? {
if let availableSeedGroup = availableSeedGroup() {
return seedGroupAvailable(atRoundIndex: roundIndex, availableSeedGroup: availableSeedGroup)
} else {
return nil
}
}
func seedGroupAvailable(atRoundIndex roundIndex: Int, availableSeedGroup: SeedInterval) -> SeedInterval? {
if availableSeeds().isEmpty == false && roundIndex >= lastSeedRound() {
if availableSeedGroup == SeedInterval(first: 1, last: 2) { return availableSeedGroup }
if availableSeeds.count <= availableSeedSpot.count {
let spots = availableSeedSpot.shuffled()
for (index, seed) in availableSeeds.enumerated() {
seed.setSeedPosition(inSpot: spots[index], slot: nil, opposingSeeding: false)
let availableSeeds = seeds(inSeedGroup: availableSeedGroup)
let availableSeedSpot = availableSeedSpot(inRoundIndex: roundIndex)
let availableSeedOpponentSpot = availableSeedOpponentSpot(inRoundIndex: roundIndex)
if availableSeeds.count == availableSeedSpot.count {
return availableSeedGroup
} else if (availableSeeds.count == availableSeedOpponentSpot.count && availableSeeds.count == self.availableSeeds().count) {
return availableSeedGroup
} else if let chunk = availableSeedGroup.chunk() {
return seedGroupAvailable(atRoundIndex: roundIndex, availableSeedGroup: chunk)
}
} else if (availableSeeds.count <= availableSeedOpponentSpot.count && availableSeeds.count <= self.availableSeeds().count) {
}
return nil
}
func setSeeds(inRoundIndex roundIndex: Int, inSeedGroup seedGroup: SeedInterval) {
if seedGroup == SeedInterval(first: 1, last: 2) {
let seeds = seeds()
if let matches = getRound(atRoundIndex: roundIndex)?.playedMatches() {
if let lastMatch = matches.last {
seeds.prefix(1).first?.setSeedPosition(inSpot: lastMatch, slot: .two, opposingSeeding: false)
}
if let firstMatch = matches.first {
seeds.prefix(2).dropFirst().first?.setSeedPosition(inSpot: firstMatch, slot: .one, opposingSeeding: false)
}
}
} else {
let spots = availableSeedOpponentSpot.shuffled()
for (index, seed) in availableSeeds.enumerated() {
seed.setSeedPosition(inSpot: spots[index], slot: nil, opposingSeeding: true)
let availableSeedSpot = availableSeedSpot(inRoundIndex: roundIndex)
let availableSeedOpponentSpot = availableSeedOpponentSpot(inRoundIndex: roundIndex)
let availableSeeds = seeds(inSeedGroup: seedGroup)
if availableSeeds.count <= availableSeedSpot.count {
let spots = availableSeedSpot.shuffled()
for (index, seed) in availableSeeds.enumerated() {
seed.setSeedPosition(inSpot: spots[index], slot: nil, opposingSeeding: false)
}
} else if (availableSeeds.count <= availableSeedOpponentSpot.count && availableSeeds.count <= self.availableSeeds().count) {
let spots = availableSeedOpponentSpot.shuffled()
for (index, seed) in availableSeeds.enumerated() {
seed.setSeedPosition(inSpot: spots[index], slot: nil, opposingSeeding: true)
}
} else if let chunk = seedGroup.chunk() {
setSeeds(inRoundIndex: roundIndex, inSeedGroup: chunk)
}
} else if let chunk = seedGroup.chunk() {
setSeeds(inRoundIndex: roundIndex, inSeedGroup: chunk)
}
}

@ -16,11 +16,12 @@ struct SeedInterval: Hashable, Comparable {
}
func chunk() -> SeedInterval? {
if last - (last - first) / 2 > first {
return SeedInterval(first: first, last: last - (last - first) / 2)
} else {
return nil
if (last - first) / 2 > 0 {
if last - (last - first) / 2 > first {
return SeedInterval(first: first, last: last - (last - first) / 2)
}
}
return nil
}
}

@ -46,7 +46,6 @@ struct PlayerBlockView: View {
if match.upperBracketMatch(teamPosition)?.disabled == true {
return "Bye"
}
return teamPosition.localizedLabel()
}

@ -81,22 +81,14 @@ struct LoserRoundView: View {
if _roundDisabled() {
RowButtonView("Jouer ce tour", role: .destructive) {
loserRounds.forEach { round in
let matches = round.playedMatches()
matches.forEach { match in
if round.upperBracketTopMatch(ofMatchIndex: match.index)?.disabled == false && round.upperBracketBottomMatch(ofMatchIndex: match.index)?.disabled == false {
match.disabled = false
}
}
try? dataStore.matches.addOrUpdate(contentOfs: matches)
round.enableRound()
round.handleLoserRoundState()
}
}
} else {
RowButtonView("Ne pas jouer ce tour", role: .destructive) {
loserRounds.forEach { round in
round.playedMatches().forEach { match in
match.disabled = true
}
round.disableRound()
}
}
}

@ -11,78 +11,9 @@ struct RoundSettingsView: View {
@EnvironmentObject var dataStore: DataStore
@Environment(\.editMode) private var editMode
@Environment(Tournament.self) var tournament: Tournament
@State private var roundIndex: Int?
var round: Round? {
guard let roundIndex else { return nil }
return tournament.rounds()[roundIndex]
}
var body: some View {
List {
if let availableSeedGroup = tournament.availableSeedGroup() {
Section {
Picker(selection: $roundIndex) {
Text("choisir de la manche").tag(nil as Int?)
ForEach(tournament.rounds()) { round in
Text(round.roundTitle()).tag(round.index as Int?)
}
} label: {
Text(availableSeedGroup.localizedLabel())
}
if let roundIndex {
RowButtonView("Valider") {
if availableSeedGroup == SeedInterval(first: 1, last: 2) {
let seeds = tournament.seeds()
// let startIndex = RoundRule.matchIndex(fromRoundIndex: roundIndex)
// let numberOfMatchInRound = RoundRule.numberOfMatches(forRoundIndex: roundIndex)
// let lastIndex = startIndex + numberOfMatchInRound - 1
// seeds.prefix(1).first?.bracketPosition = lastIndex * 2 + 1 //TS 1 branche du bas du dernier match
// seeds.prefix(2).dropFirst().first?.bracketPosition = startIndex * 2 //TS 2 branche du haut du premier match
if let matches = tournament.getRound(atRoundIndex: roundIndex)?.playedMatches() {
if let lastMatch = matches.last {
seeds.prefix(1).first?.setSeedPosition(inSpot: lastMatch, slot: .two, opposingSeeding: false)
}
if let firstMatch = matches.first {
seeds.prefix(2).dropFirst().first?.setSeedPosition(inSpot: firstMatch, slot: .one, opposingSeeding: false)
}
}
try? dataStore.teamRegistrations.addOrUpdate(contentOfs: seeds)
} else {
tournament.setSeeds(inRoundIndex: roundIndex, inSeedGroup: availableSeedGroup)
try? dataStore.teamRegistrations.addOrUpdate(contentOfs: tournament.seeds())
}
if tournament.availableSeeds().isEmpty {
editMode?.wrappedValue = .inactive
}
}
}
} header: {
Text("Placement des têtes de série")
}
}
//
// Section {
// RowButtonView("Effacer classement", role: .destructive) {
// tournament.rounds().forEach { round in
// try? dataStore.rounds.delete(contentOfs: round.loserRounds())
// }
// }
// }
//
// Section {
// RowButtonView("Match de classement") {
// tournament.rounds().forEach { round in
// round.buildLoserBracket()
// }
// }
// }
Section {
RowButtonView("Retirer toutes les têtes de séries", role: .destructive) {
tournament.unsortedTeams().forEach({ $0.bracketPosition = nil })
@ -90,14 +21,7 @@ struct RoundSettingsView: View {
tournament.allRounds().forEach({ round in
round.enableRound()
})
}
}
Section {
if let lastRound = tournament.rounds().first { // first is final, last round
RowButtonView("Supprimer " + lastRound.roundTitle(), role: .destructive) {
try? dataStore.rounds.delete(instance: lastRound)
}
editMode?.wrappedValue = .active
}
}
@ -116,6 +40,13 @@ struct RoundSettingsView: View {
}
}
Section {
if let lastRound = tournament.rounds().first { // first is final, last round
RowButtonView("Supprimer " + lastRound.roundTitle(), role: .destructive) {
try? dataStore.rounds.delete(instance: lastRound)
}
}
}
}
}
}

@ -10,6 +10,7 @@ import SwiftUI
struct RoundView: View {
@Environment(\.editMode) private var editMode
@Environment(Tournament.self) var tournament: Tournament
@EnvironmentObject var dataStore: DataStore
var round: Round
@ -29,6 +30,16 @@ struct RoundView: View {
}
}
}
} else if let availableSeedGroup = tournament.seedGroupAvailable(atRoundIndex: round.index) {
RowButtonView("Placer \(availableSeedGroup.localizedLabel())") {
tournament.setSeeds(inRoundIndex: round.index, inSeedGroup: availableSeedGroup)
try? dataStore.teamRegistrations.addOrUpdate(contentOfs: tournament.seeds())
if tournament.availableSeeds().isEmpty {
editMode?.wrappedValue = .inactive
}
}
}
ForEach(round.playedMatches()) { match in

Loading…
Cancel
Save