From 1a372b3691be09947caeec2b2257493b49166c20 Mon Sep 17 00:00:00 2001 From: Michael Virgo Date: Sun, 17 Mar 2024 20:26:53 -0500 Subject: [PATCH] feat: 2024 brackets (#6) * feat: Make round stepper more dynamic * feat: Improved initial bracket selection view * feat: Improved single game team selection * feat: Improve menu view spacing on small screens * feat: Add 14 new Division 1 teams * feat: Lengthen some team names * feat: Update probabilities post-2023 tourney * fix: Minor view improvements * feat: 2024 brackets * chore: Update version to 1.9 --- .../foam_madness_bracket_file_tests.swift | 12 +- foam-madness.xcodeproj/project.pbxproj | 40 ++-- .../Controller/Helpers/BracketHelper.swift | 33 ++- .../Controller/Helpers/GameHelper.swift | 4 +- .../LiveGameCollectionViewCell.swift | 18 -- .../LiveGameCollectionViewController.swift | 116 ---------- foam-madness/View/Game/GameScoreView.swift | 2 + foam-madness/View/Game/PlayGameView.swift | 4 +- foam-madness/View/Game/ShootModeView.swift | 1 + foam-madness/View/Live/LiveGamesCell.swift | 4 + foam-madness/View/Menu/MenuView.swift | 78 ++++--- foam-madness/View/Team/SearchBar.swift | 42 ++++ foam-madness/View/Team/SearchTeamView.swift | 71 ++++++ foam-madness/View/Team/SelectTeamsView.swift | 55 ++--- .../Tournament/SelectInitialBracketView.swift | 115 +++++++-- .../View/Tournament/TournamentGamesView.swift | 12 +- foam-madness/brackets/bracketIndex.plist | 166 +++++++++++-- foam-madness/brackets/mensBracket2024.plist | 218 ++++++++++++++++++ foam-madness/brackets/womensBracket2024.plist | 218 ++++++++++++++++++ .../historicalProbabilities.plist | 58 ++--- .../historicalProbabilitiesWomen.plist | 58 ++--- foam-madness/teams.plist | 218 +++++++++++++----- 22 files changed, 1149 insertions(+), 394 deletions(-) delete mode 100644 foam-madness/Controller/Live Games/LiveGameCollectionViewCell.swift delete mode 100644 foam-madness/Controller/Live Games/LiveGameCollectionViewController.swift create mode 100644 foam-madness/View/Team/SearchBar.swift create mode 100644 foam-madness/View/Team/SearchTeamView.swift create mode 100644 foam-madness/brackets/mensBracket2024.plist create mode 100644 foam-madness/brackets/womensBracket2024.plist diff --git a/foam-madness-tests/foam_madness_bracket_file_tests.swift b/foam-madness-tests/foam_madness_bracket_file_tests.swift index cd3ad64..288f058 100644 --- a/foam-madness-tests/foam_madness_bracket_file_tests.swift +++ b/foam-madness-tests/foam_madness_bracket_file_tests.swift @@ -7,11 +7,12 @@ // import XCTest +@testable import foam_madness final class foam_madness_bracket_file_tests: XCTestCase { let bracketIndexFile = "bracketIndex" - var brackets: [Dictionary] = [] + var brackets: [BracketItem] = [] var currentBracketName: String = "" var hasFirstFour = false var regions = [String: [String: Int16]]() @@ -24,13 +25,12 @@ final class foam_madness_bracket_file_tests: XCTestCase { func loadBrackets() { // Load the bracket index - let path = Bundle.main.path(forResource: bracketIndexFile, ofType: "plist")! - brackets = NSArray(contentsOfFile: path) as! [Dictionary] + brackets = BracketHelper.loadBrackets() } - func loadSingleBracket(bracket: Dictionary) { - currentBracketName = bracket.first!.value; - let bracketLocation = bracket.first!.key; + func loadSingleBracket(bracket: BracketItem) { + currentBracketName = bracket.name + let bracketLocation = bracket.file // Load the given bracket let bracketPath = Bundle.main.path(forResource: bracketLocation, ofType: "plist")! let bracketDict = NSDictionary(contentsOfFile: bracketPath)! diff --git a/foam-madness.xcodeproj/project.pbxproj b/foam-madness.xcodeproj/project.pbxproj index eceda2b..af94e0d 100644 --- a/foam-madness.xcodeproj/project.pbxproj +++ b/foam-madness.xcodeproj/project.pbxproj @@ -16,8 +16,6 @@ 7A2ECEF3242EDE930065E369 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7A2ECEF1242EDE930065E369 /* LaunchScreen.storyboard */; }; 7A494BC3243041C20042173A /* foam-madness.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7A494BC1243041C20042173A /* foam-madness.xcdatamodeld */; }; 7A494BC5243046A50042173A /* DataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A494BC4243046A50042173A /* DataController.swift */; }; - 7A771E5B250D9BDD009FE9EA /* LiveGameCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A771E5A250D9BDD009FE9EA /* LiveGameCollectionViewCell.swift */; }; - 7A771E5D250DA571009FE9EA /* LiveGameCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A771E5C250DA571009FE9EA /* LiveGameCollectionViewController.swift */; }; 7A916BD825EDE5D5007E8714 /* womensBracket2021.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A916BD625EDE5D4007E8714 /* womensBracket2021.plist */; }; 7A916BD925EDE5D5007E8714 /* mensBracket2021.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A916BD725EDE5D4007E8714 /* mensBracket2021.plist */; }; 7ACBCB37250EC73900EBA5B1 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACBCB36250EC73900EBA5B1 /* APIClient.swift */; }; @@ -29,6 +27,8 @@ 7AECF9C8245E779E0037E126 /* womensBracketology2020.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7AECF9C7245E779E0037E126 /* womensBracketology2020.plist */; }; 7AEFD6672514704E007BB16B /* ABOUT.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 7AEFD6662514704E007BB16B /* ABOUT.rtf */; }; 7AF31A862431267400DF1605 /* GameHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF31A852431267400DF1605 /* GameHelper.swift */; }; + D11E4F8F2BA7410100CA9FDD /* womensBracket2024.plist in Resources */ = {isa = PBXBuildFile; fileRef = D11E4F8D2BA7410100CA9FDD /* womensBracket2024.plist */; }; + D11E4F902BA7410100CA9FDD /* mensBracket2024.plist in Resources */ = {isa = PBXBuildFile; fileRef = D11E4F8E2BA7410100CA9FDD /* mensBracket2024.plist */; }; D1386BDE2B929752006C676C /* NavigationUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1386BDD2B929752006C676C /* NavigationUtil.swift */; }; D14720182B60D22500453304 /* PreviewDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D14720172B60D22500453304 /* PreviewDataController.swift */; }; D147201A2B60D6FC00453304 /* TeamHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D14720192B60D6FC00453304 /* TeamHelper.swift */; }; @@ -50,6 +50,8 @@ D15865922B5751CE009E486A /* TournamentStatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15865912B5751CE009E486A /* TournamentStatsView.swift */; }; D15865952B575ECE009E486A /* PrimaryButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15865942B575ECE009E486A /* PrimaryButtonStyle.swift */; }; D158B32D2B9A96720002D2F6 /* GameStatsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D158B32C2B9A96720002D2F6 /* GameStatsController.swift */; }; + D17FF6012BA140DA00149D63 /* SearchTeamView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D17FF6002BA140DA00149D63 /* SearchTeamView.swift */; }; + D17FF6052BA1454900149D63 /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D17FF6042BA1454900149D63 /* SearchBar.swift */; }; D18D756E29BEA5AC00DE609B /* mensBracket2023.plist in Resources */ = {isa = PBXBuildFile; fileRef = D18D756D29BEA5AC00DE609B /* mensBracket2023.plist */; }; D18D757029BEA5B500DE609B /* womensBracket2023.plist in Resources */ = {isa = PBXBuildFile; fileRef = D18D756F29BEA5B500DE609B /* womensBracket2023.plist */; }; D199087B2B996D6200A57746 /* ShootModeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D199087A2B996D6200A57746 /* ShootModeController.swift */; }; @@ -98,8 +100,6 @@ 7A494BC2243041C20042173A /* foam-madness.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "foam-madness.xcdatamodel"; sourceTree = ""; }; 7A494BC4243046A50042173A /* DataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataController.swift; sourceTree = ""; }; 7A73579E243ED4A800691B26 /* foam-madness-v2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "foam-madness-v2.xcdatamodel"; sourceTree = ""; }; - 7A771E5A250D9BDD009FE9EA /* LiveGameCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveGameCollectionViewCell.swift; sourceTree = ""; }; - 7A771E5C250DA571009FE9EA /* LiveGameCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveGameCollectionViewController.swift; sourceTree = ""; }; 7A916BD625EDE5D4007E8714 /* womensBracket2021.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = womensBracket2021.plist; sourceTree = ""; }; 7A916BD725EDE5D4007E8714 /* mensBracket2021.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = mensBracket2021.plist; sourceTree = ""; }; 7ABF40392456A55600A18B3F /* foam-madness-v3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "foam-madness-v3.xcdatamodel"; sourceTree = ""; }; @@ -112,6 +112,8 @@ 7AECF9C7245E779E0037E126 /* womensBracketology2020.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = womensBracketology2020.plist; sourceTree = ""; }; 7AEFD6662514704E007BB16B /* ABOUT.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = ABOUT.rtf; sourceTree = ""; }; 7AF31A852431267400DF1605 /* GameHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameHelper.swift; sourceTree = ""; }; + D11E4F8D2BA7410100CA9FDD /* womensBracket2024.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = womensBracket2024.plist; sourceTree = ""; }; + D11E4F8E2BA7410100CA9FDD /* mensBracket2024.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = mensBracket2024.plist; sourceTree = ""; }; D1386BDD2B929752006C676C /* NavigationUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationUtil.swift; sourceTree = ""; }; D14720172B60D22500453304 /* PreviewDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewDataController.swift; sourceTree = ""; }; D14720192B60D6FC00453304 /* TeamHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamHelper.swift; sourceTree = ""; }; @@ -133,6 +135,8 @@ D15865912B5751CE009E486A /* TournamentStatsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TournamentStatsView.swift; sourceTree = ""; }; D15865942B575ECE009E486A /* PrimaryButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryButtonStyle.swift; sourceTree = ""; }; D158B32C2B9A96720002D2F6 /* GameStatsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameStatsController.swift; sourceTree = ""; }; + D17FF6002BA140DA00149D63 /* SearchTeamView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTeamView.swift; sourceTree = ""; }; + D17FF6042BA1454900149D63 /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = ""; }; D18D756D29BEA5AC00DE609B /* mensBracket2023.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = mensBracket2023.plist; sourceTree = ""; }; D18D756F29BEA5B500DE609B /* womensBracket2023.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = womensBracket2023.plist; sourceTree = ""; }; D199087A2B996D6200A57746 /* ShootModeController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShootModeController.swift; sourceTree = ""; }; @@ -259,22 +263,12 @@ D199087A2B996D6200A57746 /* ShootModeController.swift */, D1C757A02B9A62C500817E1A /* TournamentStatsController.swift */, D158B32C2B9A96720002D2F6 /* GameStatsController.swift */, - 7A771E59250D9B81009FE9EA /* Live Games */, 7A2ECEE8242EDE920065E369 /* AppDelegate.swift */, 7A2D2E3C262E78A000AB5935 /* Helpers */, ); path = Controller; sourceTree = ""; }; - 7A771E59250D9B81009FE9EA /* Live Games */ = { - isa = PBXGroup; - children = ( - 7A771E5A250D9BDD009FE9EA /* LiveGameCollectionViewCell.swift */, - 7A771E5C250DA571009FE9EA /* LiveGameCollectionViewController.swift */, - ); - path = "Live Games"; - sourceTree = ""; - }; 7ACBCB35250EC71400EBA5B1 /* Live Games API */ = { isa = PBXGroup; children = ( @@ -305,6 +299,7 @@ 7A916BD725EDE5D4007E8714 /* mensBracket2021.plist */, D14C59E827DED2FE001378F1 /* mensBracket2022.plist */, D18D756D29BEA5AC00DE609B /* mensBracket2023.plist */, + D11E4F8E2BA7410100CA9FDD /* mensBracket2024.plist */, D1E16E16283354B0007280EC /* womensBracket2015.plist */, D1E16E1B283354B0007280EC /* womensBracket2016.plist */, D1E16E15283354B0007280EC /* womensBracket2017.plist */, @@ -314,6 +309,7 @@ 7A916BD625EDE5D4007E8714 /* womensBracket2021.plist */, D14C59EA27DED30F001378F1 /* womensBracket2022.plist */, D18D756F29BEA5B500DE609B /* womensBracket2023.plist */, + D11E4F8D2BA7410100CA9FDD /* womensBracket2024.plist */, D1E16E1028334BB0007280EC /* bracketIndex.plist */, ); path = brackets; @@ -341,6 +337,8 @@ isa = PBXGroup; children = ( D158657B2B574FB9009E486A /* SelectTeamsView.swift */, + D17FF6002BA140DA00149D63 /* SearchTeamView.swift */, + D17FF6042BA1454900149D63 /* SearchBar.swift */, ); path = Team; sourceTree = ""; @@ -490,6 +488,7 @@ D1E16E1128334BB0007280EC /* bracketIndex.plist in Resources */, 7AEAB80B2433086C009E7CC1 /* teams.plist in Resources */, 7AECF9C8245E779E0037E126 /* womensBracketology2020.plist in Resources */, + D11E4F8F2BA7410100CA9FDD /* womensBracket2024.plist in Resources */, 7A2ECEF3242EDE930065E369 /* LaunchScreen.storyboard in Resources */, D1E16E22283354B0007280EC /* mensBracket2015.plist in Resources */, D1E16E21283354B0007280EC /* womensBracket2018.plist in Resources */, @@ -507,6 +506,7 @@ D14C59E927DED2FE001378F1 /* mensBracket2022.plist in Resources */, D1E16E1F283354B0007280EC /* womensBracket2017.plist in Resources */, 7AEFD6672514704E007BB16B /* ABOUT.rtf in Resources */, + D11E4F902BA7410100CA9FDD /* mensBracket2024.plist in Resources */, D1E16E24283354B0007280EC /* mensBracket2018.plist in Resources */, 7A1B9C9D245A9A22005B40D3 /* historicalProbabilitiesWomen.plist in Resources */, 7A916BD825EDE5D5007E8714 /* womensBracket2021.plist in Resources */, @@ -538,12 +538,12 @@ D199087B2B996D6200A57746 /* ShootModeController.swift in Sources */, D1C757A12B9A62C500817E1A /* TournamentStatsController.swift in Sources */, D15865802B5750F9009E486A /* ShootModeView.swift in Sources */, + D17FF6012BA140DA00149D63 /* SearchTeamView.swift in Sources */, D158657A2B574F94009E486A /* LiveGamesCell.swift in Sources */, 7ACBCB3B250EC7FC00EBA5B1 /* ErrorResponse.swift in Sources */, D15865882B575176009E486A /* SelectInitialBracketView.swift in Sources */, D158B32D2B9A96720002D2F6 /* GameStatsController.swift in Sources */, 7ACBCB37250EC73900EBA5B1 /* APIClient.swift in Sources */, - 7A771E5D250DA571009FE9EA /* LiveGameCollectionViewController.swift in Sources */, D15865732B574D4D009E486A /* MenuView.swift in Sources */, D1A8B1A02B9FF03100354C9F /* TournamentGameCell.swift in Sources */, D15865902B5751BE009E486A /* SelectTournamentView.swift in Sources */, @@ -556,7 +556,6 @@ D147201A2B60D6FC00453304 /* TeamHelper.swift in Sources */, D199087D2B99703500A57746 /* SaveHelper.swift in Sources */, D1D4F9C32B97E4D0004B9C18 /* BracketCreationController.swift in Sources */, - 7A771E5B250D9BDD009FE9EA /* LiveGameCollectionViewCell.swift in Sources */, D158657E2B5750E7009E486A /* PlayGameView.swift in Sources */, 7AF31A862431267400DF1605 /* GameHelper.swift in Sources */, D15865842B575118009E486A /* GameStatsView.swift in Sources */, @@ -564,6 +563,7 @@ D15865952B575ECE009E486A /* PrimaryButtonStyle.swift in Sources */, 7A2ECEE9242EDE920065E369 /* AppDelegate.swift in Sources */, D158658C2B575197009E486A /* TournamentGamesView.swift in Sources */, + D17FF6052BA1454900149D63 /* SearchBar.swift in Sources */, 7A2D2E3F262E7FBE00AB5935 /* SimHelper.swift in Sources */, D15865822B57510D009E486A /* GameScoreView.swift in Sources */, ); @@ -728,7 +728,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 12; + CURRENT_PROJECT_VERSION = 13; DEVELOPMENT_TEAM = 5X3GA242G5; INFOPLIST_FILE = "foam-madness/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -736,7 +736,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.8; + MARKETING_VERSION = 1.9; PRODUCT_BUNDLE_IDENTIFIER = "com.mvirgo.foam-madness"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -749,7 +749,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 12; + CURRENT_PROJECT_VERSION = 13; DEVELOPMENT_TEAM = 5X3GA242G5; INFOPLIST_FILE = "foam-madness/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -757,7 +757,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.8; + MARKETING_VERSION = 1.9; PRODUCT_BUNDLE_IDENTIFIER = "com.mvirgo.foam-madness"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/foam-madness/Controller/Helpers/BracketHelper.swift b/foam-madness/Controller/Helpers/BracketHelper.swift index 3ac5ba8..9ddc779 100644 --- a/foam-madness/Controller/Helpers/BracketHelper.swift +++ b/foam-madness/Controller/Helpers/BracketHelper.swift @@ -8,9 +8,38 @@ import Foundation +struct BracketItem { + let file: String + let name: String + let isWomens: Bool + let year: Int + + init?(dictionary: [String: Any]) { + guard let file = dictionary["File"] as? String, + let name = dictionary["Name"] as? String, + let isWomens = dictionary["IsWomens"] as? Bool, + let year = dictionary["Year"] as? Int else { + return nil + } + self.file = file + self.name = name + self.isWomens = isWomens + self.year = year + } +} + class BracketHelper { - static func loadBrackets() -> [Dictionary] { + static func loadBrackets() -> [BracketItem] { let path = Bundle.main.path(forResource: "bracketIndex", ofType: "plist")! - return NSArray(contentsOfFile: path) as! [Dictionary] + let bracketArray = NSArray(contentsOfFile: path) as! [[String: Any]] + + var bracketItems = [BracketItem]() + for dict in bracketArray { + if let bracketItem = BracketItem(dictionary: dict) { + bracketItems.append(bracketItem) + } + } + + return bracketItems } } diff --git a/foam-madness/Controller/Helpers/GameHelper.swift b/foam-madness/Controller/Helpers/GameHelper.swift index 5b9311b..fe5dd3a 100644 --- a/foam-madness/Controller/Helpers/GameHelper.swift +++ b/foam-madness/Controller/Helpers/GameHelper.swift @@ -26,9 +26,9 @@ class GameHelper { case 0: out = "First Four" case 1: - out = "First Round" + out = "Round of 64" case 2: - out = "Second Round" + out = "Round of 32" case 3: out = "Sweet Sixteen" case 4: diff --git a/foam-madness/Controller/Live Games/LiveGameCollectionViewCell.swift b/foam-madness/Controller/Live Games/LiveGameCollectionViewCell.swift deleted file mode 100644 index f69cabe..0000000 --- a/foam-madness/Controller/Live Games/LiveGameCollectionViewCell.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// LiveGameCollectionViewCell.swift -// foam-madness -// -// Created by Michael Virgo on 9/12/20. -// Copyright © 2020 mvirgo. All rights reserved. -// - -import UIKit - -class LiveGameCollectionViewCell: UICollectionViewCell { - @IBOutlet weak var sportLabel: UILabel! - @IBOutlet weak var team1Label: UILabel! - @IBOutlet weak var score1Label: UILabel! - @IBOutlet weak var team2Label: UILabel! - @IBOutlet weak var score2Label: UILabel! - @IBOutlet weak var timeLabel: UILabel! -} diff --git a/foam-madness/Controller/Live Games/LiveGameCollectionViewController.swift b/foam-madness/Controller/Live Games/LiveGameCollectionViewController.swift deleted file mode 100644 index 60dd16b..0000000 --- a/foam-madness/Controller/Live Games/LiveGameCollectionViewController.swift +++ /dev/null @@ -1,116 +0,0 @@ -// -// LiveGameCollectionViewController.swift -// foam-madness -// -// Created by Michael Virgo on 9/12/20. -// Copyright © 2020 mvirgo. All rights reserved. -// - -import UIKit - -class LiveGameCollectionViewController: UICollectionViewController { - // MARK: Outlets - @IBOutlet weak var flowLayout: UICollectionViewFlowLayout! - - // MARK: Other variables - var liveGames = [Event]() - - // MARK: Lifecycle - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - // Make sure view respects the safe area - if #available(iOS 11.0, *) { - collectionView?.contentInsetAdjustmentBehavior = .always - } - loadGames() - setFlowLayout() - } - - // MARK: Collection View functions - override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return liveGames.count - } - - override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "liveGames", for: indexPath) as! LiveGameCollectionViewCell - - // Add game data to cell - let indexInt = (indexPath as NSIndexPath).row - // Note: all arrays except `competitors` have only 1 item - let game = liveGames[indexInt] - let teams = game.competitions[0].competitors - cell.sportLabel.text = game.league - cell.team1Label.text = teams[0].team.abbreviation - cell.score1Label.text = teams[0].score - cell.team2Label.text = teams[1].team.abbreviation - cell.score2Label.text = teams[1].score - cell.timeLabel.text = game.status.type.shortDetail - - return cell - } - - // MARK: Function to handle flow layout - func setFlowLayout() { - let space: CGFloat = 3.0 - let divisor: CGFloat = UIDevice.current.orientation.isPortrait ? 3.0 : 4.0 - let dimension = (view.safeAreaLayoutGuide.layoutFrame.width - (2 * space)) / divisor - - flowLayout.minimumInteritemSpacing = space - flowLayout.minimumLineSpacing = space - flowLayout.itemSize = CGSize(width: dimension, height: dimension) - } - - // MARK: Background messaging while loading/empty - func handleBackgroundMessage(loading: Bool) { - if liveGames.count > 0 { - self.collectionView.backgroundView = nil - } else { - // Add a label to the background - // Based on https://stackoverflow.com/questions/43772984/how-to-show-a-message-when-collection-view-is-empty - let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.safeAreaLayoutGuide.layoutFrame.width, height: self.view.safeAreaLayoutGuide.layoutFrame.height)) - messageLabel.textColor = .label - messageLabel.numberOfLines = 0 - messageLabel.textAlignment = .center - messageLabel.font = UIFont.systemFont(ofSize: 30) - messageLabel.sizeToFit() - - if loading { - // Show load label - messageLabel.text = "Loading games..." - } else { - // Show empty label - messageLabel.text = "No games found." - } - - self.collectionView.backgroundView = messageLabel - self.collectionView.backgroundView?.isHidden = false - } - } - - // MARK: API processing - func loadGames() { - handleBackgroundMessage(loading: true) - APIClient.getScores(url: APIClient.Endpoints.getNCAAMScores.url, completion: handleLiveGameScores(response:error:)) - APIClient.getScores(url: APIClient.Endpoints.getNCAAWScores.url, completion: handleLiveGameScores(response:error:)) - APIClient.getScores(url: APIClient.Endpoints.getNBAScores.url, completion: handleLiveGameScores(response:error:)) - APIClient.getScores(url: APIClient.Endpoints.getWNBAScores.url, completion: handleLiveGameScores(response:error:)) - } - - func handleLiveGameScores(response: LiveGamesResponse?, error: Error?) { - if let error = error { - print(error.localizedDescription) - } else if let response = response { - // Add events to liveGames array - for (_, var game) in response.events.enumerated() { - // Note that there will only be one league in NCAA or (W)NBA APIs - // Add game - game.league = response.leagues[0].abbreviation - liveGames.append(game) - } - DispatchQueue.main.async { - self.collectionView.reloadData() - } - } - handleBackgroundMessage(loading: false) - } -} diff --git a/foam-madness/View/Game/GameScoreView.swift b/foam-madness/View/Game/GameScoreView.swift index e8dec3b..c56b8e0 100644 --- a/foam-madness/View/Game/GameScoreView.swift +++ b/foam-madness/View/Game/GameScoreView.swift @@ -24,6 +24,7 @@ struct GameScoreView: View { Text(team1Name) .font(.largeTitle) .minimumScaleFactor(0.5) + .lineLimit(1) Spacer() Text(team1Score).font(.largeTitle) } @@ -31,6 +32,7 @@ struct GameScoreView: View { Text(team2Name) .font(.largeTitle) .minimumScaleFactor(0.5) + .lineLimit(1) Spacer() Text(team2Score).font(.largeTitle) } diff --git a/foam-madness/View/Game/PlayGameView.swift b/foam-madness/View/Game/PlayGameView.swift index 09237d9..38e9134 100644 --- a/foam-madness/View/Game/PlayGameView.swift +++ b/foam-madness/View/Game/PlayGameView.swift @@ -22,11 +22,13 @@ struct PlayGameView: View { Text(team1 ?? "") .font(.largeTitle) .minimumScaleFactor(0.5) + .multilineTextAlignment(.center) Text("VS") Text(team2 ?? "") .font(.largeTitle) .minimumScaleFactor(0.5) - } + .multilineTextAlignment(.center) + }.padding([.leading, .trailing]) NavigationLink(destination: ShootModeView(game: game, isSimulated: false)) { Text("Play Game") diff --git a/foam-madness/View/Game/ShootModeView.swift b/foam-madness/View/Game/ShootModeView.swift index f6fd4ef..d808ebf 100644 --- a/foam-madness/View/Game/ShootModeView.swift +++ b/foam-madness/View/Game/ShootModeView.swift @@ -36,6 +36,7 @@ struct ShootModeView: View { .font(.largeTitle) .fontWeight(.bold) .minimumScaleFactor(0.5) + .multilineTextAlignment(.center) Text(shotType ?? "").font(.title) Text(hand ?? "").font(.title2) } diff --git a/foam-madness/View/Live/LiveGamesCell.swift b/foam-madness/View/Live/LiveGamesCell.swift index ab23bbe..f42197b 100644 --- a/foam-madness/View/Live/LiveGamesCell.swift +++ b/foam-madness/View/Live/LiveGamesCell.swift @@ -16,6 +16,7 @@ struct LiveGamesCell: View { VStack { let teams = game.competitions[0].competitors Text(game.league) + .padding(2) HStack() { Text(teams[0].team.abbreviation) Spacer() @@ -27,6 +28,9 @@ struct LiveGamesCell: View { Text(teams[1].score) }.padding([.leading, .trailing]) Text(game.status.type.shortDetail).lineLimit(1) + .padding(2) + .minimumScaleFactor(0.5) + .lineLimit(1) }.minimumScaleFactor(0.5) ) } diff --git a/foam-madness/View/Menu/MenuView.swift b/foam-madness/View/Menu/MenuView.swift index e1398ff..803cfa0 100644 --- a/foam-madness/View/Menu/MenuView.swift +++ b/foam-madness/View/Menu/MenuView.swift @@ -13,51 +13,53 @@ struct MenuView: View { private var tournaments: FetchedResults var body: some View { - NavigationView { - VStack(spacing: 20) { - VStack(spacing: 10) { - Text("Tournament Mode") + GeometryReader { geometry in + NavigationView { + VStack(spacing: geometry.size.height * 0.02) { + VStack(spacing: 10) { + Text("Tournament Mode") + + if (hasCurrentTournaments()) { + NavigationLink(destination: SelectTournamentView(completedTournaments: false, tournaments: Array(tournaments))) { + Text("Resume Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) + } + NavigationLink(destination: SelectInitialBracketView(isSimulated: false)) { + Text("New Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) + NavigationLink(destination: SelectInitialBracketView(isSimulated: true)) { + Text("Quick Sim Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) + if (hasCompletedTournaments()) { + NavigationLink(destination: SelectTournamentView(completedTournaments: true, tournaments: Array(tournaments))) { + Text("View Finished Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) + } + }.fixedSize(horizontal: true, vertical: false) - if (hasCurrentTournaments()) { - NavigationLink(destination: SelectTournamentView(completedTournaments: false, tournaments: Array(tournaments))) { - Text("Resume Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) + VStack(spacing: geometry.size.height * 0.01) { + Text("Single Game") + NavigationLink(destination: SelectTeamsView()) { + Text("Play Game")}.buttonStyle(PrimaryButtonStyle()) } - NavigationLink(destination: SelectInitialBracketView(isSimulated: false)) { - Text("New Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) - NavigationLink(destination: SelectInitialBracketView(isSimulated: true)) { - Text("Quick Sim Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) - if (hasCompletedTournaments()) { - NavigationLink(destination: SelectTournamentView(completedTournaments: true, tournaments: Array(tournaments))) { - Text("View Finished Tournament") }.buttonStyle(PrimaryButtonFullWidthStyle()) + + VStack(spacing: geometry.size.height * 0.01) { + Text("Live Scores") + NavigationLink(destination: LiveGamesView()) { + Text("View Live Scores")}.buttonStyle(PrimaryButtonStyle()) } - }.fixedSize(horizontal: true, vertical: false) - - VStack(spacing: 10) { - Text("Single Game") - NavigationLink(destination: SelectTeamsView()) { - Text("Play Game")}.buttonStyle(PrimaryButtonStyle()) - } - - VStack(spacing: 10) { - Text("Live Scores") - NavigationLink(destination: LiveGamesView()) { - Text("View Live Scores")}.buttonStyle(PrimaryButtonStyle()) } - } - .font(.system(size: 36)) - .navigationTitle("Menu") - .navigationBarTitleDisplayMode(.inline) - .toolbar { - ToolbarItem(placement: .principal) { - Text("Main Menu").font(.system(size: 24)).fontWeight(.bold) - } - ToolbarItem(placement: .topBarTrailing) { NavigationLink("About", destination: AboutView()).font(.system(size: 24)) + .font(.system(size: 36)) + .navigationTitle("Menu") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .principal) { + Text("Main Menu").font(.system(size: 24)).fontWeight(.bold) + } + ToolbarItem(placement: .topBarTrailing) { NavigationLink("About", destination: AboutView()).font(.system(size: 24)) + } } + .minimumScaleFactor(0.8) + .padding([.bottom], 20) } - .minimumScaleFactor(0.8) - .padding([.bottom], 40) + .navigationViewStyle(StackNavigationViewStyle()) } - .navigationViewStyle(StackNavigationViewStyle()) } private func hasCurrentTournaments() -> Bool { diff --git a/foam-madness/View/Team/SearchBar.swift b/foam-madness/View/Team/SearchBar.swift new file mode 100644 index 0000000..73a27aa --- /dev/null +++ b/foam-madness/View/Team/SearchBar.swift @@ -0,0 +1,42 @@ +// +// SearchBar.swift +// foam-madness +// +// Created by Michael Virgo on 3/12/24. +// Copyright © 2024 mvirgo. All rights reserved. +// + +import SwiftUI + +// Based on https://stackoverflow.com/a/57738103, since still on iOS 14 +struct SearchBar: UIViewRepresentable { + @Binding var text: String + var filteredData: [String] + + class Coordinator: NSObject, UISearchBarDelegate { + @Binding var text: String + + init(text: Binding) { + _text = text + } + + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + text = searchText + } + } + + func makeCoordinator() -> SearchBar.Coordinator { + return Coordinator(text: $text) + } + + func makeUIView(context: UIViewRepresentableContext) -> UISearchBar { + let searchBar = UISearchBar(frame: .zero) + searchBar.delegate = context.coordinator + searchBar.autocapitalizationType = .none + return searchBar + } + + func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext) { + uiView.text = text + } +} diff --git a/foam-madness/View/Team/SearchTeamView.swift b/foam-madness/View/Team/SearchTeamView.swift new file mode 100644 index 0000000..1ef73c6 --- /dev/null +++ b/foam-madness/View/Team/SearchTeamView.swift @@ -0,0 +1,71 @@ +// +// SearchTeamView.swift +// foam-madness +// +// Created by Michael Virgo on 3/12/24. +// Copyright © 2024 mvirgo. All rights reserved. +// + +import SwiftUI + +struct SearchTeamView: View { + @State private var searchText = "" + @State private var shownTeamName = "" + @Binding var teamName: String + @Binding var showParentButton: Bool + var label: String + var teams: [String] + + + var searchResults: [String] { + searchText.isEmpty ? [] : teams.filter{$0.localizedCaseInsensitiveContains(searchText)} + } + + var body: some View { + VStack { + HStack(alignment: .center, spacing: 10) { + Text(label).fontWeight(.bold) + SearchBar(text: $searchText, filteredData: teams) + }.padding([.leading]) + + if (searchResults.count > 0 && shownTeamName == "") { + List { + ForEach(searchResults, id: \.self) { team in + Button(team, action: { + teamName = team // update for parent + showParentButton = true // update for parent + shownTeamName = team // hide the list + searchText = team // show user the selected team + }) + .tag(String?.some(team)) + } + } + .listStyle(.plain) + } + } + .onChange(of: searchText) { _ in + if searchText == "" { + // Cleared the search bar + clearFields() + } else if shownTeamName != "" && shownTeamName != searchText { + // Backspaced, clear out + clearFields() + } + } + } + + func clearFields() { + shownTeamName = "" // allow list to show again + teamName = "" // update for parent + showParentButton = false // update for parent + } +} + +struct SearchTeamView_Previews: PreviewProvider { + static var viewContext = PreviewDataController.shared.container.viewContext + + static var previews: some View { + let teams = TeamHelper.loadTeams().teams + return SearchTeamView(teamName: .constant(""), showParentButton: .constant(false), label: "Team 1", teams: teams).environment(\.managedObjectContext, viewContext) + } +} diff --git a/foam-madness/View/Team/SelectTeamsView.swift b/foam-madness/View/Team/SelectTeamsView.swift index 0933d21..40df718 100644 --- a/foam-madness/View/Team/SelectTeamsView.swift +++ b/foam-madness/View/Team/SelectTeamsView.swift @@ -15,8 +15,10 @@ struct SelectTeamsView: View { @State private var teams: [String] = [] @State private var reverseTeamDict: [String: [String: String]] = [:] - @State private var team1: String? - @State private var team2: String? + @State private var team1: String = "" + @State private var team2: String = "" + @State private var showButton1 = false + @State private var showButton2 = false @State private var progressToGame = false @State private var createdGame: Game? @@ -25,52 +27,39 @@ struct SelectTeamsView: View { VStack { Text("Select Teams").foregroundColor(commonBlue).font(.largeTitle).fontWeight(.bold) - VStack { - VStack { - Text("Team 1").font(.title2).fontWeight(.bold) - Picker("First Picker", selection: $team1) { - ForEach(teams, id: \.self) { team in - Text(team).tag(String?.some(team)) - } - } - .pickerStyle(WheelPickerStyle()) - } - - VStack { - Text("Team 2").font(.title2).fontWeight(.bold) - Picker("Second Picker", selection: $team2) { - ForEach(teams, id: \.self) { team in - Text(team).tag(String?.some(team)) - } - } - .pickerStyle(WheelPickerStyle()) - } - }.padding([.top, .bottom]) + VStack() { + SearchTeamView(teamName: $team1, showParentButton: $showButton1, label: "Team 1", teams: teams) + SearchTeamView(teamName: $team2, showParentButton: $showButton2, label: "Team 2", teams: teams) + } - if (progressToGame) { - NavigationLink("", destination: PlayGameView(game: createdGame!), isActive: $progressToGame) - } else { - Button("Continue") { - createGame() + if (showButton1 && showButton2) { + if (progressToGame) { + NavigationLink("", destination: PlayGameView(game: createdGame!), isActive: $progressToGame) + } else { + Button("Continue") { + createGame() + } + .buttonStyle(PrimaryButtonFullWidthStyle()) + .padding() } - .buttonStyle(PrimaryButtonFullWidthStyle()) - .padding() } } .onAppear { teams = loadedTeams.teams reverseTeamDict = loadedTeams.reverseTeamDict - team1 = teams[0] - team2 = teams[0] } } private func createGame() -> Void { + if team1.isEmpty || team2.isEmpty { + alertUser(title: "Please Select Teams", message: "Both teams need to be selected.") + return + } if $team1.wrappedValue == $team2.wrappedValue { alertUser(title: "Invalid Teams", message: "Selected teams must be different.") return } - createdGame = GameHelper.prepareSingleGame(team1!, team2!, reverseTeamDict, viewContext) + createdGame = GameHelper.prepareSingleGame(team1, team2, reverseTeamDict, viewContext) progressToGame = true } diff --git a/foam-madness/View/Tournament/SelectInitialBracketView.swift b/foam-madness/View/Tournament/SelectInitialBracketView.swift index 40f761b..69842a6 100644 --- a/foam-madness/View/Tournament/SelectInitialBracketView.swift +++ b/foam-madness/View/Tournament/SelectInitialBracketView.swift @@ -10,31 +10,116 @@ import SwiftUI struct SelectInitialBracketView: View { @State var isSimulated: Bool - @State var chosenBracketFile: String? - - let brackets = BracketHelper.loadBrackets() + @State private var chosenBracketFile: String? + @State private var chosenBracketName: String? + @State private var chosenYear: String? + @State private var isWomens = false + @State private var yearsArray: [String] = [] + @State private var brackets: [BracketItem] = [] + let gridPadding = 10.0 var body: some View { - List { - ForEach(brackets.reversed(), id: \.self) { bracket in + GeometryReader { geometry in + VStack(spacing: geometry.size.height * 0.03) { + Spacer() + + VStack { + Text("Choose a Year").font(.title2) + LazyVGrid(columns: [ + GridItem(.flexible()), + GridItem(.flexible()), + GridItem(.flexible()), + GridItem(.flexible()) + ], spacing: gridPadding) { + ForEach(yearsArray, id: \.self) { year in + Button(action: { + chosenYear = year + }) { + Text(year) + .lineLimit(1) + .font(.headline) + .foregroundColor(chosenYear == year ? Color.white : Color.primary) + .padding() + } + .frame(maxWidth: .infinity) + .background(chosenYear == year ? commonBlue : Color.secondary) + .cornerRadius(5.0) + } + }.padding(gridPadding) + } + + VStack { + Text("Men's or Women's?").font(.title2) + Picker("", selection: $isWomens) { + Text("Men's").tag(false) + Text("Women's").tag(true) + } + .pickerStyle(.segmented) + .padding([.leading, .trailing], 30) + } + + VStack(spacing: 10) { + Text("Current Bracket Chosen") + .font(.title2) + Text(chosenBracketName ?? "") + .font(.title2) + .fontWeight(.bold) + } + + Spacer() + NavigationLink( + "Continue", destination: BracketCreationView( isSimulated: isSimulated, - chosenBracketFile: bracket.first?.key ?? "" + chosenBracketFile: chosenBracketFile ?? "" ) - ) { - Text(bracket.first?.value ?? "") + ) + .buttonStyle(PrimaryButtonFullWidthStyle()) + .padding([.leading, .trailing, .bottom]) + } + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .principal) { + Text("Choose a Starting Bracket") + .fontWeight(.bold) } - .buttonStyle(.plain) } - } - .navigationBarTitleDisplayMode(.inline) - .toolbar { - ToolbarItem(placement: .principal) { - Text("Choose a Starting Bracket") - .fontWeight(.bold) + .onAppear() { + brackets = BracketHelper.loadBrackets() + getYears() + } + .onChange(of: chosenYear) { _ in + getChosenBracket() } + .onChange(of: isWomens) { _ in + getChosenBracket() + } + } + } + + private func getYears() { + let initialYearsArray = brackets.map { $0.year } + let uniqueYears = Set(initialYearsArray) + // sort descending + let sortedYears = uniqueYears.sorted(by: >) + yearsArray = sortedYears.map { String($0) } + chosenYear = yearsArray[0] + } + + private func getBracketName() -> String { + if brackets.count > 0 { + return brackets.filter({ $0.year == Int(chosenYear ?? "") && $0.isWomens == isWomens})[0].name + } + return "" + } + + private func getChosenBracket() { + if (chosenYear != nil && brackets.count > 0) { + let chosenBracket = brackets.filter({ $0.year == Int(chosenYear ?? "") && $0.isWomens == isWomens})[0] + chosenBracketFile = chosenBracket.file + chosenBracketName = chosenBracket.name } } } diff --git a/foam-madness/View/Tournament/TournamentGamesView.swift b/foam-madness/View/Tournament/TournamentGamesView.swift index 7c311e2..b16b43e 100644 --- a/foam-madness/View/Tournament/TournamentGamesView.swift +++ b/foam-madness/View/Tournament/TournamentGamesView.swift @@ -10,6 +10,7 @@ import SwiftUI struct TournamentGamesView: View { @State private var initialRound: Int16 = 0 + @State private var finalRound: Int16 = 6 @State private var roundStepper: Int16 = 0 @State private var roundText = "ROUND" @State private var games: [Game] = [] @@ -31,7 +32,7 @@ struct TournamentGamesView: View { .foregroundColor(commonBlue) .font(.title2) .fontWeight(.bold) - Stepper(value: $roundStepper, in: initialRound...6) { + Stepper(value: $roundStepper, in: initialRound...finalRound) { Text("") } .labelsHidden() @@ -62,11 +63,10 @@ struct TournamentGamesView: View { let gamesArray = Array(tournament.games!) as! [Game] games = gamesArray.sorted() { $0.tourneyGameId < $1.tourneyGameId } - if games.filter({ $0.round == 0}).count == 0 { - // skip first four - initialRound = 1 - roundStepper = 1 - } + let minRound = games.min(by: { $0.round < $1.round })?.round ?? 0 + finalRound = games.max(by: { $0.round < $1.round })?.round ?? 6 + initialRound = minRound + roundStepper = minRound } } diff --git a/foam-madness/brackets/bracketIndex.plist b/foam-madness/brackets/bracketIndex.plist index 07c5989..ed0bb14 100644 --- a/foam-madness/brackets/bracketIndex.plist +++ b/foam-madness/brackets/bracketIndex.plist @@ -3,76 +3,204 @@ - mensBracket2015 + File + mensBracket2024 + Name + 2024 Men's Bracket + IsWomens + + Year + 2024 + + + File + womensBracket2024 + Name + 2024 Women's Bracket + IsWomens + + Year + 2024 + + + File + mensBracket2015 + Name 2015 Men's Bracket + IsWomens + + Year + 2015 - womensBracket2015 + File + womensBracket2015 + Name 2015 Women's Bracket + IsWomens + + Year + 2015 - mensBracket2016 + File + mensBracket2016 + Name 2016 Men's Bracket + IsWomens + + Year + 2016 - womensBracket2016 + File + womensBracket2016 + Name 2016 Women's Bracket + IsWomens + + Year + 2016 - mensBracket2017 + File + mensBracket2017 + Name 2017 Men's Bracket + IsWomens + + Year + 2017 - womensBracket2017 + File + womensBracket2017 + Name 2017 Women's Bracket + IsWomens + + Year + 2017 - mensBracket2018 + File + mensBracket2018 + Name 2018 Men's Bracket + IsWomens + + Year + 2018 - womensBracket2018 + File + womensBracket2018 + Name 2018 Women's Bracket + IsWomens + + Year + 2018 - mensBracket2019 + File + mensBracket2019 + Name 2019 Men's Bracket + IsWomens + + Year + 2019 - womensBracket2019 + File + womensBracket2019 + Name 2019 Women's Bracket + IsWomens + + Year + 2019 - bracketology2020 + File + bracketology2020 + Name 2020 Joe Lunardi's Bracketology + IsWomens + + Year + 2020 - womensBracketology2020 - 2020 Womens - Charlie Creme's Bracketology + File + womensBracketology2020 + Name + 2020 Women's - Charlie Creme's Bracketology + IsWomens + + Year + 2020 - mensBracket2021 + File + mensBracket2021 + Name 2021 Men's Bracket + IsWomens + + Year + 2021 - womensBracket2021 + File + womensBracket2021 + Name 2021 Women's Bracket + IsWomens + + Year + 2021 - mensBracket2022 + File + mensBracket2022 + Name 2022 Men's Bracket + IsWomens + + Year + 2022 - womensBracket2022 + File + womensBracket2022 + Name 2022 Women's Bracket + IsWomens + + Year + 2022 - mensBracket2023 + File + mensBracket2023 + Name 2023 Men's Bracket + IsWomens + + Year + 2023 - womensBracket2023 + File + womensBracket2023 + Name 2023 Women's Bracket + IsWomens + + Year + 2023 diff --git a/foam-madness/brackets/mensBracket2024.plist b/foam-madness/brackets/mensBracket2024.plist new file mode 100644 index 0000000..cb7729d --- /dev/null +++ b/foam-madness/brackets/mensBracket2024.plist @@ -0,0 +1,218 @@ + + + + + Year + 2024 + IsWomens + + FirstFour + + 0 + + NextGame + 12 + Seed + 16 + Region + West + + 1 + + NextGame + 26 + Seed + 10 + Region + South + + 2 + + NextGame + 28 + Seed + 16 + Region + Midwest + + 3 + + NextGame + 34 + Seed + 10 + Region + Midwest + + + RegionIDs + + 0 + East + 1 + West + 2 + South + 3 + Midwest + + Source + + URL + https://www.ncaa.com/brackets/print/basketball-men/d1/2024 + Date Accessed + 2024-03-17T23:25:36Z + + Regions + + East + + 1 + 268 + 10 + 112 + 11 + 114 + 12 + 259 + 13 + 41 + 14 + 179 + 15 + 221 + 16 + 233 + 2 + 147 + 3 + 64 + 4 + 4 + 5 + 50 + 6 + 44 + 7 + 340 + 8 + 123 + 9 + 192 + + Midwest + + 1 + 203 + 101 + 60 + 102 + 104 + 11 + 42 + 12 + 170 + 13 + 215 + 14 + 25 + 15 + 213 + 161 + 178 + 162 + 135 + 2 + 320 + 3 + 66 + 4 + 0 + 5 + 35 + 6 + 315 + 7 + 22 + 8 + 32 + 9 + 241 + + South + + 1 + 2 + 101 + 79 + 102 + 19 + 11 + 27 + 12 + 151 + 13 + 59 + 14 + 193 + 15 + 344 + 16 + 162 + 2 + 3 + 3 + 14 + 4 + 10 + 5 + 6 + 6 + 49 + 7 + 20 + 8 + 293 + 9 + 239 + + West + + 1 + 301 + 10 + 295 + 11 + 297 + 12 + 136 + 13 + 101 + 14 + 100 + 15 + 160 + 161 + 141 + 162 + 338 + 2 + 48 + 3 + 52 + 4 + 258 + 5 + 54 + 6 + 97 + 7 + 16 + 8 + 174 + 9 + 62 + + + + diff --git a/foam-madness/brackets/womensBracket2024.plist b/foam-madness/brackets/womensBracket2024.plist new file mode 100644 index 0000000..7cc6cfd --- /dev/null +++ b/foam-madness/brackets/womensBracket2024.plist @@ -0,0 +1,218 @@ + + + + + Year + 2024 + IsWomens + + FirstFour + + 0 + + NextGame + 4 + Seed + 16 + Region + Albany-1 + + 1 + + NextGame + 20 + Seed + 16 + Region + Albany-2 + + 2 + + NextGame + 30 + Seed + 12 + Region + Portland-3 + + 3 + + NextGame + 32 + Seed + 11 + Region + Portland-3 + + + RegionIDs + + 0 + Albany-1 + 1 + Portland-4 + 2 + Albany-2 + 3 + Portland-3 + + Source + + URL + https://www.ncaa.com/brackets/print/basketball-women/d1/2024 + Date Accessed + 2024-03-18T00:44:50Z + + Regions + + Albany-1 + + 1 + 315 + 10 + 3 + 11 + 239 + 12 + 124 + 13 + 120 + 14 + 47 + 15 + 154 + 161 + 209 + 162 + 201 + 2 + 306 + 3 + 198 + 4 + 45 + 5 + 39 + 6 + 293 + 7 + 288 + 8 + 301 + 9 + 62 + + Portland-4 + + 1 + 22 + 10 + 24 + 11 + 329 + 12 + 221 + 13 + 51 + 14 + 318 + 15 + 186 + 16 + 113 + 2 + 232 + 3 + 27 + 4 + 35 + 5 + 327 + 6 + 320 + 7 + 147 + 8 + 258 + 9 + 33 + + Albany-2 + + 1 + 8 + 10 + 294 + 11 + 173 + 12 + 112 + 13 + 309 + 14 + 207 + 15 + 352 + 161 + 102 + 162 + 319 + 2 + 28 + 3 + 38 + 4 + 152 + 5 + 19 + 6 + 58 + 7 + 66 + 8 + 31 + 9 + 202 + + Portland-3 + + 1 + 65 + 10 + 23 + 111 + 4 + 112 + 48 + 121 + 334 + 122 + 105 + 13 + 169 + 14 + 148 + 15 + 280 + 16 + 240 + 2 + 56 + 3 + 268 + 4 + 337 + 5 + 52 + 6 + 235 + 7 + 10 + 8 + 0 + 9 + 40 + + + + diff --git a/foam-madness/probabilities/historicalProbabilities.plist b/foam-madness/probabilities/historicalProbabilities.plist index f0a324b..aedd61d 100644 --- a/foam-madness/probabilities/historicalProbabilities.plist +++ b/foam-madness/probabilities/historicalProbabilities.plist @@ -5,7 +5,7 @@ Source Date Accessed - 2022-05-17T02:51:00Z + 2024-03-15T00:32:40Z URL http://mcubed.net/ncaab/seeds.shtml @@ -20,15 +20,15 @@ 4 0.705 5 - 0.825 + 0.797 6 0.706 7 0.857 8 - 0.791 + 0.785 9 - 0.905 + 0.906 10 0.875 11 @@ -42,28 +42,28 @@ 15 0.5 16 - 0.993 + 0.987 2 2 0.5 3 - 0.609 + 0.606 4 0.5 5 - 0.286 + 0.25 6 0.722 7 - 0.7 + 0.696 8 0.4 9 - 0.5 + 0.667 10 - 0.635 + 0.641 11 0.842 12 @@ -73,7 +73,7 @@ 14 0.5 15 - 0.9320000000000001 + 0.928 16 0.5 @@ -82,27 +82,27 @@ 3 0.5 4 - 0.625 + 0.556 5 0.5 6 - 0.581 + 0.583 7 - 0.611 + 0.632 8 1 9 - 1 + 0.75 10 0.6919999999999999 11 - 0.661 + 0.667 12 0.5 13 0.5 14 - 0.851 + 0.855 15 0.667 16 @@ -113,15 +113,15 @@ 4 0.5 5 - 0.5610000000000001 + 0.573 6 0.333 7 0.333 8 - 0.333 + 0.385 9 - 0.5 + 0.4 10 1 11 @@ -129,7 +129,7 @@ 12 0.705 13 - 0.796 + 0.789 14 0.5 15 @@ -148,15 +148,15 @@ 8 0.25 9 - 0.25 + 0.4 10 1 11 0.5 12 - 0.667 + 0.674 13 - 0.842 + 0.85 14 0.5 15 @@ -177,7 +177,7 @@ 10 0.6 11 - 0.625 + 0.628 12 0.5 13 @@ -185,7 +185,7 @@ 14 0.875 15 - 0.5 + 1 16 0.5 @@ -198,7 +198,7 @@ 9 0.5 10 - 0.605 + 0.606 11 0 12 @@ -208,7 +208,7 @@ 14 1 15 - 0.4 + 0.333 16 0.5 @@ -217,7 +217,7 @@ 8 0.5 9 - 0.512 + 0.511 10 0.5 11 diff --git a/foam-madness/probabilities/historicalProbabilitiesWomen.plist b/foam-madness/probabilities/historicalProbabilitiesWomen.plist index c371199..e569dae 100644 --- a/foam-madness/probabilities/historicalProbabilitiesWomen.plist +++ b/foam-madness/probabilities/historicalProbabilitiesWomen.plist @@ -5,7 +5,7 @@ Source Date Accessed - 2022-05-17T02:56:10Z + 2024-03-15T00:40:23Z URL http://mcubed.net/ncaabw/seeds.shtml @@ -14,21 +14,21 @@ 1 0.5 2 - 0.62 + 0.621 3 - 0.739 + 0.729 4 0.8090000000000001 5 - 0.913 + 0.915 6 - 0.857 + 0.875 7 0.8 8 - 0.957 + 0.945 9 - 0.97 + 0.959 10 1 11 @@ -49,21 +49,21 @@ 2 0.5 3 - 0.637 + 0.62 4 - 0.467 + 0.533 5 - 0.5 + 0.6 6 - 0.771 + 0.789 7 - 0.855 + 0.847 8 0 9 0 10 - 0.863 + 0.885 11 1 12 @@ -86,17 +86,17 @@ 5 1 6 - 0.6919999999999999 + 0.68 7 - 0.462 + 0.5 8 0.5 9 - 0.5 + 1 10 - 0.571 + 0.5 11 - 0.6830000000000001 + 0.698 12 0.5 13 @@ -113,23 +113,23 @@ 4 0.5 5 - 0.653 + 0.641 6 1 7 - 0.667 + 1 8 1 9 - 1 + 0.667 10 0.5 11 0.5 12 - 0.821 + 0.862 13 - 0.9379999999999999 + 0.9399999999999999 14 0.5 15 @@ -146,7 +146,7 @@ 7 0.5 8 - 0.5 + 0.667 9 0 10 @@ -154,7 +154,7 @@ 11 0.5 12 - 0.789 + 0.787 13 0.571 14 @@ -169,7 +169,7 @@ 6 0.5 7 - 0.667 + 1 8 0.5 9 @@ -177,7 +177,7 @@ 10 0.5 11 - 0.6889999999999999 + 0.6840000000000001 12 0.5 13 @@ -198,7 +198,7 @@ 9 0.5 10 - 0.646 + 0.642 11 0 12 @@ -217,7 +217,7 @@ 8 0.5 9 - 0.542 + 0.52 10 0.5 11 diff --git a/foam-madness/teams.plist b/foam-madness/teams.plist index 7503c3d..09ff614 100644 --- a/foam-madness/teams.plist +++ b/foam-madness/teams.plist @@ -2,6 +2,104 @@ + 364 + + abbreviation + UT + name + Utah Tech + + 363 + + abbreviation + UST + name + St. Thomas (Minnesota) + + 362 + + abbreviation + USI + name + Southern Indiana + + 361 + + abbreviation + UNA + name + North Alabama + + 360 + + abbreviation + UCSD + name + UC San Diego + + 359 + + abbreviation + TAMC + name + Texas A&M - Commerce + + 358 + + abbreviation + TSU + name + Tarleton + + 357 + + abbreviation + SC + name + Stonehill + + 356 + + abbreviation + QUC + name + Queens - Charlotte + + 355 + + abbreviation + MERR + name + Merrimack + + 354 + + abbreviation + LU + name + Lindenwood + + 353 + + abbreviation + LMC + name + Le Moyne College + + 352 + + abbreviation + CBU + name + California Baptist + + 351 + + abbreviation + BELL + name + Bellarmine + 0 abbreviation @@ -33,9 +131,9 @@ 101 abbreviation - CSUSC + COFC name - Charleston S.C. + College of Charleston 102 @@ -63,7 +161,7 @@ abbreviation COBA name - Columbia-Barnard + Columbia - Barnard 106 @@ -147,21 +245,21 @@ abbreviation EIU name - E Illinois + Eastern Illinois 117 abbreviation EKU name - E Kentucky + Eastern Kentucky 118 abbreviation EMU name - E Michigan + Eastern Michigan 119 @@ -217,7 +315,7 @@ abbreviation FIU name - Florida Intl + Florida International 126 @@ -334,9 +432,9 @@ 140 abbreviation - HBU + HCU name - Houston Baptist + Houston Christian 141 @@ -406,7 +504,7 @@ abbreviation NDSU name - N Dakota St + North Dakota St 150 @@ -525,14 +623,14 @@ abbreviation LUC name - Loyola-Chicago + Loyola - Chicago 166 abbreviation LUM name - Loyola-Maryland + Loyola - Maryland 167 @@ -581,14 +679,14 @@ abbreviation MIA-OH name - Miami-Ohio + Miami - Ohio 173 abbreviation MTSU name - Mid Tennessee St + Middle Tennessee St 174 @@ -728,7 +826,7 @@ abbreviation NSU name - Northwestern St + Northwestern St (Louisiana) 192 @@ -833,7 +931,7 @@ abbreviation IPFW name - Purdue-Ft Wayne + Purdue - Fort Wayne 205 @@ -882,28 +980,28 @@ abbreviation SFU name - St Francis-Penn + Saint Francis - Penn 211 abbreviation SJU name - St Joseph's + Saint Joseph's 212 abbreviation SLU name - St Louis + Saint Louis 213 abbreviation SPU name - St Peter's + Saint Peter's 214 @@ -973,42 +1071,42 @@ abbreviation SEMO name - SE Missouri St + Southeast Missouri St 223 abbreviation SELA name - SE Louisiana + Southeastern Louisiana 224 abbreviation SIUC name - S Illinois-Carbondale + Southern Illinois Carbondale 225 abbreviation SIUE name - S Illinois-Edwardsville + Southern Illinois Edwardsville 226 abbreviation SMU name - Southern Methodist + Southern Methodist (SMU) 227 abbreviation SUBR name - Southern-Baton Rouge + Southern - Baton Rouge 228 @@ -1036,14 +1134,14 @@ abbreviation SFC name - St. Francis-Brooklyn + St. Francis College-Brooklyn 231 abbreviation SJU name - St. John’s-NY + St. John’s - New York 232 @@ -1064,7 +1162,7 @@ abbreviation STON name - Stony Brook + SUNY Stony Brook 235 @@ -1113,14 +1211,14 @@ abbreviation TAMCC name - Texas A&M-Corpus Christi + Texas A&M - Corpus Christi 241 abbreviation TCU name - Texas Christian + Texas Christian (TCU) 242 @@ -1148,28 +1246,28 @@ abbreviation UNCC name - N Carolina-Charlotte + North Carolina - Charlotte 246 abbreviation UNCG name - N Carolina-Greensboro + North Carolina - Greensboro 247 abbreviation USM name - Southern Miss + Southern Mississippi 248 abbreviation URTGV name - Texas-Rio Grande + Texas - Rio Grande 249 @@ -1253,7 +1351,7 @@ abbreviation UAB name - Alabama-Birmingham + Alabama-Birmingham (UAB) 26 @@ -1281,7 +1379,7 @@ abbreviation CAL name - California + California (Berkeley) 263 @@ -1323,7 +1421,7 @@ abbreviation UCONN name - Connecticut + Connecticut (UCONN) 269 @@ -1428,14 +1526,14 @@ abbreviation UMES name - Maryland-E Shore + Maryland-Eastern Shore 282 abbreviation UMBC name - Maryland-BC + Maryland-Baltimore County 283 @@ -1477,7 +1575,7 @@ abbreviation MISS name - Mississippi + Mississippi (Ole Miss) 289 @@ -1526,7 +1624,7 @@ abbreviation UNLV name - Nevada-Las Vegas + Nevada-Las Vegas (UNLV) 295 @@ -1687,7 +1785,7 @@ abbreviation USCU name - S Carolina-Upstate + South Carolina-Upstate 315 @@ -1806,7 +1904,7 @@ abbreviation FSU name - Florida St + Florida State 330 @@ -1848,14 +1946,14 @@ abbreviation VCU name - VCU + Virginia Commonwealth (VCU) 336 abbreviation VMI name - Virginia Military + Virginia Military (VMI) 337 @@ -1883,7 +1981,7 @@ abbreviation NKU name - N Kentucky + Northern Kentucky 340 @@ -1988,7 +2086,7 @@ abbreviation LSU name - LSU + LSU (Louisiana State) 39 @@ -2058,7 +2156,7 @@ abbreviation EWU name - E Washington + Eastern Washington 48 @@ -2086,7 +2184,7 @@ abbreviation SDSU name - San Diego St + San Diego State 51 @@ -2114,7 +2212,7 @@ abbreviation STM name - St Mary’s + Saint Mary’s 55 @@ -2128,7 +2226,7 @@ abbreviation OSU name - Ohio St + Ohio State 57 @@ -2198,7 +2296,7 @@ abbreviation USC name - Southern California + Southern California (USC) 66 @@ -2212,7 +2310,7 @@ abbreviation UALR name - Little Rock + Arkansas - Little Rock 68 @@ -2233,7 +2331,7 @@ abbreviation UNT name - N Texas + North Texas 70 @@ -2254,7 +2352,7 @@ abbreviation AMER name - American Univ + American University 73 @@ -2282,7 +2380,7 @@ abbreviation BALL name - Ball St + Ball State 77 @@ -2296,7 +2394,7 @@ abbreviation SUNYB name - Binghamton + SUNY Binghamton 79 @@ -2387,7 +2485,7 @@ abbreviation ETST name - E Tennessee St + East Tennessee St 90 @@ -2415,7 +2513,7 @@ abbreviation CCSU name - C Connecticut St + Central Connecticut St 94