From 9b6dfc4be9bfe488c731f828d76bd379b269df15 Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Mon, 6 Apr 2020 14:46:30 -0400 Subject: [PATCH 1/4] implemented selectActivePlayerPrompt --- src/Mtlstats/Prompt.hs | 34 +++++++++++++++++++++++++++++----- src/Mtlstats/Types.hs | 32 +++++++++++++++++++++++++++++--- test/TypesSpec.hs | 14 ++++++++++++++ 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/Mtlstats/Prompt.hs b/src/Mtlstats/Prompt.hs index 47e65b1..d02ccb0 100644 --- a/src/Mtlstats/Prompt.hs +++ b/src/Mtlstats/Prompt.hs @@ -43,6 +43,7 @@ module Mtlstats.Prompt ( goalieNumPrompt, goalieNamePrompt, selectPlayerPrompt, + selectActivePlayerPrompt, selectGoaliePrompt, selectPositionPrompt, playerToEditPrompt @@ -263,18 +264,21 @@ goalieNamePrompt :: Prompt goalieNamePrompt = namePrompt "Goalie name: " $ modify . (progMode.createGoalieStateL.cgsName .~) --- | Selects a player (creating one if necessary) -selectPlayerPrompt - :: String +-- | Selects a player using a specified search function (creating the +-- player if necessary) +selectPlayerPromptWith + :: (String -> [Player] -> [(Int, Player)]) + -- ^ The search function + -> String -- ^ The prompt string -> (Maybe Int -> Action ()) -- ^ The callback to run (takes the index number of the payer as -- input) -> Prompt -selectPlayerPrompt pStr callback = selectPrompt SelectParams +selectPlayerPromptWith sFunc pStr callback = selectPrompt SelectParams { spPrompt = pStr , spSearchHeader = "Player select:" - , spSearch = \sStr db -> playerSearch sStr (db^.dbPlayers) + , spSearch = \sStr db -> sFunc sStr (db^.dbPlayers) , spSearchExact = \sStr db -> fst <$> playerSearchExact sStr (db^.dbPlayers) , spElemDesc = playerSummary , spProcessChar = capitalizeName @@ -292,6 +296,26 @@ selectPlayerPrompt pStr callback = selectPrompt SelectParams modify $ progMode .~ CreatePlayer cps } +-- | Selects a player (creating one if necessary) +selectPlayerPrompt + :: String + -- ^ The prompt string + -> (Maybe Int -> Action ()) + -- ^ The callback to run (takes the index number of the payer as + -- input) + -> Prompt +selectPlayerPrompt = selectPlayerPromptWith playerSearch + +-- | Selects an active player (creating one if necessary) +selectActivePlayerPrompt + :: String + -- ^ The prompt string + -> (Maybe Int -> Action ()) + -- ^ The callback to run (takes the index number of the payer as + -- input) + -> Prompt +selectActivePlayerPrompt = selectPlayerPromptWith activePlayerSearch + -- | Selects a goalie (creating one if necessary) selectGoaliePrompt :: String diff --git a/src/Mtlstats/Types.hs b/src/Mtlstats/Types.hs index b64f46a..1bee699 100644 --- a/src/Mtlstats/Types.hs +++ b/src/Mtlstats/Types.hs @@ -176,6 +176,7 @@ module Mtlstats.Types ( addGameStats, -- ** Player Helpers playerSearch, + activePlayerSearch, playerSearchExact, modifyPlayer, playerSummary, @@ -1003,6 +1004,23 @@ addGameStats s1 s2 = GameStats , _gmsGoalsAgainst = s1^.gmsGoalsAgainst + s2^.gmsGoalsAgainst } +-- | Searches through a list of players with a specified criteria +playerSearchWith + :: (Player -> Bool) + -- ^ The search criteria + -> String + -- ^ The search string + -> [Player] + -- ^ The list of players to search + -> [(Int, Player)] + -- ^ The matching players with their index numbers +playerSearchWith criteria sStr = + filter match . zip [0..] + where + match (_, p) + = map toUpper sStr `isInfixOf` map toUpper (p^.pName) + && criteria p + -- | Searches through a list of players playerSearch :: String @@ -1011,9 +1029,17 @@ playerSearch -- ^ The list of players to search -> [(Int, Player)] -- ^ The matching players with their index numbers -playerSearch sStr = - filter match . zip [0..] - where match (_, p) = map toUpper sStr `isInfixOf` map toUpper (p^.pName) +playerSearch = playerSearchWith $ const True + +-- | Searches through a list of players for an active player +activePlayerSearch + :: String + -- ^ The search string + -> [Player] + -- ^ The list of players to search + -> [(Int, Player)] + -- ^ The matching players with their index numbers +activePlayerSearch = playerSearchWith (^.pActive) -- | Searches for a player by exact match on name playerSearchExact diff --git a/test/TypesSpec.hs b/test/TypesSpec.hs index d88de00..1104e51 100644 --- a/test/TypesSpec.hs +++ b/test/TypesSpec.hs @@ -73,6 +73,7 @@ spec = describe "Mtlstats.Types" $ do gmsPointsSpec addGameStatsSpec playerSearchSpec + activePlayerSearchSpec playerSearchExactSpec modifyPlayerSpec playerSummarySpec @@ -647,6 +648,19 @@ playerSearchSpec = describe "playerSearch" $ mapM_ , ( "x", [] ) ] +activePlayerSearchSpec :: Spec +activePlayerSearchSpec = describe "activePlayerSearch" $ mapM_ + (\(sStr, expected) -> context sStr $ + it ("should return " ++ show expected) $ let + ps = [joe, bob, steve & pActive .~ False] + in activePlayerSearch sStr ps `shouldBe` expected) + -- search, result + [ ( "joe", [(0, joe)] ) + , ( "o", [(0, joe), (1, bob)] ) + , ( "e", [(0, joe)] ) + , ( "x", [] ) + ] + playerSearchExactSpec :: Spec playerSearchExactSpec = describe "playerSearchExact" $ mapM_ (\(sStr, expected) -> context sStr $ From 4f147cd5a44e6d7403825fdaea89c3fdd0bc2a08 Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Mon, 6 Apr 2020 15:01:26 -0400 Subject: [PATCH 2/4] implemented searchActiveGoaliePrompt --- src/Mtlstats/Prompt.hs | 34 +++++++++++++++++++++++++++++----- src/Mtlstats/Types.hs | 32 +++++++++++++++++++++++++++++--- test/TypesSpec.hs | 23 +++++++++++++++++++++++ 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/Mtlstats/Prompt.hs b/src/Mtlstats/Prompt.hs index d02ccb0..c6c74bc 100644 --- a/src/Mtlstats/Prompt.hs +++ b/src/Mtlstats/Prompt.hs @@ -45,6 +45,7 @@ module Mtlstats.Prompt ( selectPlayerPrompt, selectActivePlayerPrompt, selectGoaliePrompt, + selectActiveGoaliePrompt, selectPositionPrompt, playerToEditPrompt ) where @@ -316,18 +317,21 @@ selectActivePlayerPrompt -> Prompt selectActivePlayerPrompt = selectPlayerPromptWith activePlayerSearch --- | Selects a goalie (creating one if necessary) -selectGoaliePrompt - :: String +-- | Selects a goalie with a specified search criteria (creating the +-- goalie if necessary) +selectGoaliePromptWith + :: (String -> [Goalie] -> [(Int, Goalie)]) + -- ^ The search criteria + -> String -- ^ The prompt string -> (Maybe Int -> Action ()) -- ^ The callback to run (takes the index number of the goalie as -- input) -> Prompt -selectGoaliePrompt pStr callback = selectPrompt SelectParams +selectGoaliePromptWith criteria pStr callback = selectPrompt SelectParams { spPrompt = pStr , spSearchHeader = "Goalie select:" - , spSearch = \sStr db -> goalieSearch sStr (db^.dbGoalies) + , spSearch = \sStr db -> criteria sStr (db^.dbGoalies) , spSearchExact = \sStr db -> fst <$> goalieSearchExact sStr (db^.dbGoalies) , spElemDesc = goalieSummary , spProcessChar = capitalizeName @@ -345,6 +349,26 @@ selectGoaliePrompt pStr callback = selectPrompt SelectParams modify $ progMode .~ CreateGoalie cgs } +-- | Selects a goalie (creating one if necessary) +selectGoaliePrompt + :: String + -- ^ The prompt string + -> (Maybe Int -> Action ()) + -- ^ The callback to run (takes the index number of the goalie as + -- input) + -> Prompt +selectGoaliePrompt = selectGoaliePromptWith goalieSearch + +-- | Selects an active goalie (creating one if necessary) +selectActiveGoaliePrompt + :: String + -- ^ The prompt string + -> (Maybe Int -> Action ()) + -- ^ The callback to run (takes the index number of the goalie as + -- input) + -> Prompt +selectActiveGoaliePrompt = selectGoaliePromptWith activeGoalieSearch + -- | Selects (or creates) a player position selectPositionPrompt :: String diff --git a/src/Mtlstats/Types.hs b/src/Mtlstats/Types.hs index 1bee699..b5ad653 100644 --- a/src/Mtlstats/Types.hs +++ b/src/Mtlstats/Types.hs @@ -186,6 +186,7 @@ module Mtlstats.Types ( addPlayerStats, -- ** Goalie Helpers goalieSearch, + activeGoalieSearch, goalieSearchExact, goalieSummary, goalieIsActive, @@ -1094,6 +1095,23 @@ addPlayerStats s1 s2 = newPlayerStats & psAssists .~ s1^.psAssists + s2^.psAssists & psPMin .~ s1^.psPMin + s2^.psPMin +-- | Searches a list of goalies with a search criteria +goalieSearchWith + :: (Goalie -> Bool) + -- ^ The search criteria + -> String + -- ^ The search string + -> [Goalie] + -- ^ The list to search + -> [(Int, Goalie)] + -- ^ The search results with their corresponding index numbers +goalieSearchWith criteria sStr = + filter match . zip [0..] + where + match (_, g) + = map toUpper sStr `isInfixOf` map toUpper (g^.gName) + && criteria g + -- | Searches a list of goalies goalieSearch :: String @@ -1102,9 +1120,17 @@ goalieSearch -- ^ The list to search -> [(Int, Goalie)] -- ^ The search results with their corresponding index numbers -goalieSearch sStr = - filter match . zip [0..] - where match (_, g) = map toUpper sStr `isInfixOf` map toUpper (g^.gName) +goalieSearch = goalieSearchWith $ const True + +-- | Searches a list of goalies for an active goalie +activeGoalieSearch + :: String + -- ^ The search string + -> [Goalie] + -- ^ The list to search + -> [(Int, Goalie)] + -- ^ The search results with their corresponding index numbers +activeGoalieSearch = goalieSearchWith (^.gActive) -- | Searches a list of goalies for an exact match goalieSearchExact diff --git a/test/TypesSpec.hs b/test/TypesSpec.hs index 1104e51..e6d6340 100644 --- a/test/TypesSpec.hs +++ b/test/TypesSpec.hs @@ -81,6 +81,7 @@ spec = describe "Mtlstats.Types" $ do psPointsSpec addPlayerStatsSpec goalieSearchSpec + activeGoalieSearchSpec goalieSearchExactSpec goalieSummarySpec goalieIsActiveSpec @@ -792,6 +793,28 @@ goalieSearchSpec = describe "goalieSearch" $ do it "should return Bob" $ goalieSearch "bob" goalies `shouldBe` [result 1] +activeGoalieSearchSpec :: Spec +activeGoalieSearchSpec = describe "activeGoalieSearch" $ do + let + goalies = + [ newGoalie 2 "Joe" + , newGoalie 3 "Bob" + , newGoalie 5 "Steve" & gActive .~ False + ] + result n = (n, goalies!!n) + + context "partial match" $ + it "should return Joe" $ + activeGoalieSearch "e" goalies `shouldBe` [result 0] + + context "no match" $ + it "should return an empty list" $ + activeGoalieSearch "x" goalies `shouldBe` [] + + context "exact match" $ + it "should return Bob" $ + activeGoalieSearch "bob" goalies `shouldBe` [result 1] + goalieSearchExactSpec :: Spec goalieSearchExactSpec = describe "goalieSearchExact" $ do let From ed240c6a38f8baecdabd659835e0179f9184531d Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Mon, 6 Apr 2020 15:14:48 -0400 Subject: [PATCH 3/4] only search through active players/goalies on game input --- src/Mtlstats/Prompt/NewGame.hs | 6 +++--- src/Mtlstats/Prompt/NewGame/GoalieInput.hs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Mtlstats/Prompt/NewGame.hs b/src/Mtlstats/Prompt/NewGame.hs index eb35b06..b864a91 100644 --- a/src/Mtlstats/Prompt/NewGame.hs +++ b/src/Mtlstats/Prompt/NewGame.hs @@ -76,7 +76,7 @@ recordGoalPrompt -> Int -- ^ The goal number -> Prompt -recordGoalPrompt game goal = selectPlayerPrompt +recordGoalPrompt game goal = selectActivePlayerPrompt ( "*** GAME " ++ padNum 2 game ++ " ***\n" ++ "Who scored goal number " ++ show goal ++ "? " ) $ modify . (progMode.gameStateL.goalBy .~) @@ -90,7 +90,7 @@ recordAssistPrompt -> Int -- ^ The assist number -> Prompt -recordAssistPrompt game goal assist = selectPlayerPrompt +recordAssistPrompt game goal assist = selectActivePlayerPrompt ( "*** GAME " ++ padNum 2 game ++ " ***\n" ++ "Goal: " ++ show goal ++ "\n" ++ "Assist #" ++ show assist ++ ": " @@ -104,7 +104,7 @@ recordAssistPrompt game goal assist = selectPlayerPrompt -- | Prompts for the player to assign penalty minutes to pMinPlayerPrompt :: Prompt -pMinPlayerPrompt = selectPlayerPrompt +pMinPlayerPrompt = selectActivePlayerPrompt "Assign penalty minutes to: " $ \case Nothing -> modify $ progMode.gameStateL.gamePMinsRecorded .~ True diff --git a/src/Mtlstats/Prompt/NewGame/GoalieInput.hs b/src/Mtlstats/Prompt/NewGame/GoalieInput.hs index 3e87aec..df5e6d4 100644 --- a/src/Mtlstats/Prompt/NewGame/GoalieInput.hs +++ b/src/Mtlstats/Prompt/NewGame/GoalieInput.hs @@ -36,7 +36,8 @@ import Mtlstats.Types -- | Prompts for a goalie who played in the game selectGameGoaliePrompt :: Prompt -selectGameGoaliePrompt = selectGoaliePrompt "Which goalie played this game: " $ +selectGameGoaliePrompt = selectActiveGoaliePrompt + "Which goalie played this game: " $ \case Nothing -> modify finishGoalieEntry Just n -> modify $ progMode.gameStateL.gameSelectedGoalie ?~ n From 393a2c6dc4952345bb7cd895ccf0284a46fc94fa Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Mon, 6 Apr 2020 15:16:27 -0400 Subject: [PATCH 4/4] updated change log --- ChangeLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index a72815f..8fe2aec 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,8 @@ # Changelog for mtlstats +## current +- only search for active players/goalies on game data input + ## 0.15.0 - Ask for database to load on start-up - Add page break to report file