Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd6f604cd7 | ||
|
|
1763f142f1 | ||
|
|
b442b6a360 | ||
|
|
119c28ef18 | ||
|
|
b69b3fce7a | ||
|
|
59026de077 | ||
|
|
52f1e34d49 | ||
|
|
2c561e9807 | ||
|
|
e2aeb5bfa4 | ||
|
|
5b40a5942b | ||
|
|
ee3cea5643 | ||
|
|
5209c4a296 | ||
|
|
e077c32956 | ||
|
|
8dcef502be | ||
|
|
3ee97406f1 | ||
|
|
2768934c7c | ||
|
|
6c8ec21ffe | ||
|
|
ba3f8a5a6c | ||
|
|
3a71dc1e62 | ||
|
|
d14f2ba527 | ||
|
|
acd45229e7 | ||
|
|
aff1d5c255 | ||
|
|
0448a4beee | ||
|
|
ddb9394ab7 | ||
|
|
071aa3bd8e | ||
|
|
ac95601609 | ||
|
|
9606436e9e | ||
|
|
30807b7e2e | ||
|
|
34b743a55b | ||
|
|
63bd9a6de4 | ||
|
|
1f3ff5912c | ||
|
|
7bb0981ed6 | ||
|
|
eb4107365c | ||
|
|
6238e39f69 | ||
|
|
1adf6de990 | ||
|
|
2840298467 | ||
|
|
89fe646d0e | ||
|
|
b35136944c | ||
|
|
4d41c454a1 | ||
|
|
18ba758c0c | ||
|
|
3aedd01b08 | ||
|
|
235dd4e611 | ||
|
|
adf09c2cc4 | ||
|
|
a44ecc5e24 | ||
|
|
9980a095ed | ||
|
|
1d6a4aa7f3 | ||
|
|
8988ad9146 | ||
|
|
59d48ec154 | ||
|
|
be990538bc | ||
|
|
55c8806186 | ||
|
|
0ecf899b56 | ||
|
|
2f06fd221d | ||
|
|
f1227da9ca | ||
|
|
38db3c8d8f | ||
|
|
2b9a21c28b | ||
|
|
84c487dba5 | ||
|
|
6345e3d5d8 | ||
|
|
0ca03b7f21 | ||
|
|
482f42dca7 | ||
|
|
996bad94f1 | ||
|
|
4ca0b54de2 | ||
|
|
3738088dde | ||
|
|
1ec9e93f16 |
16
ChangeLog.md
16
ChangeLog.md
@@ -1,5 +1,21 @@
|
||||
# Changelog for mtlstats
|
||||
|
||||
## 0.10.0
|
||||
- Don't show player number zero in reports
|
||||
- Fixed player/goalie name capitalisation on edit
|
||||
- Return to correct edit menus after editing player stats
|
||||
- Enabled batch editing of player/goalie YTD/lifetime stats
|
||||
- Bugfix: allow user to edit goalie shutouts
|
||||
- Added line numbers to lifetime player/goalie reports
|
||||
- Implemented rookie flag
|
||||
|
||||
## 0.9.0
|
||||
- Bugfix: Display lifetime stats in report, not YTD
|
||||
- Force expected capitalization on player/goalie names
|
||||
- Don't show lifetime totals in report
|
||||
- Sort players in YTD and lifetime reports by points
|
||||
- Moved player/goalie creation/editing to edit submenu
|
||||
|
||||
## 0.8.0
|
||||
- Bugfix: removed quotation marks from goalie names in report
|
||||
- Allow lower case player names
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: mtlstats
|
||||
version: 0.8.0
|
||||
version: 0.10.0
|
||||
github: "mtlstats/mtlstats"
|
||||
license: GPL-3
|
||||
author: "Jonathan Lamothe"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -30,8 +30,11 @@ module Mtlstats.Actions
|
||||
, removeChar
|
||||
, createPlayer
|
||||
, createGoalie
|
||||
, edit
|
||||
, editPlayer
|
||||
, editSelectedPlayer
|
||||
, editGoalie
|
||||
, editSelectedGoalie
|
||||
, addPlayer
|
||||
, addGoalie
|
||||
, resetCreatePlayerState
|
||||
@@ -46,6 +49,7 @@ import Data.Maybe (fromMaybe)
|
||||
import Lens.Micro ((^.), (&), (.~), (%~))
|
||||
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Util
|
||||
|
||||
-- | Starts a new season
|
||||
startNewSeason :: ProgState -> ProgState
|
||||
@@ -82,7 +86,7 @@ removeChar = inputBuffer %~ \case
|
||||
-- | Starts player creation mode
|
||||
createPlayer :: ProgState -> ProgState
|
||||
createPlayer = let
|
||||
callback = modify $ progMode .~ MainMenu
|
||||
callback = modify edit
|
||||
cps = newCreatePlayerState
|
||||
& cpsSuccessCallback .~ callback
|
||||
& cpsFailureCallback .~ callback
|
||||
@@ -91,20 +95,50 @@ createPlayer = let
|
||||
-- | Starts goalie creation mode
|
||||
createGoalie :: ProgState -> ProgState
|
||||
createGoalie = let
|
||||
callback = modify $ progMode .~ MainMenu
|
||||
callback = modify edit
|
||||
cgs = newCreateGoalieState
|
||||
& cgsSuccessCallback .~ callback
|
||||
& cgsFailureCallback .~ callback
|
||||
in progMode .~ CreateGoalie cgs
|
||||
|
||||
-- | Launches the edit menu
|
||||
edit :: ProgState -> ProgState
|
||||
edit = progMode .~ EditMenu
|
||||
|
||||
-- | Starts the player editing process
|
||||
editPlayer :: ProgState -> ProgState
|
||||
editPlayer = progMode .~ EditPlayer newEditPlayerState
|
||||
|
||||
-- | Edits the selected 'Player'
|
||||
editSelectedPlayer
|
||||
:: (Player -> Player)
|
||||
-- ^ The modification to be made to the 'Player'
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editSelectedPlayer f s = fromMaybe s $ do
|
||||
n <- s^.progMode.editPlayerStateL.epsSelectedPlayer
|
||||
let
|
||||
players = s^.database.dbPlayers
|
||||
players' = modifyNth n f players
|
||||
Just $ s & database.dbPlayers .~ players'
|
||||
|
||||
-- | Starts the 'Goalie' editing process
|
||||
editGoalie :: ProgState -> ProgState
|
||||
editGoalie = progMode .~ EditGoalie newEditGoalieState
|
||||
|
||||
-- | Edits the selected 'Goalie'
|
||||
editSelectedGoalie
|
||||
:: (Goalie -> Goalie)
|
||||
-- ^ The modification to be made to the 'Goalie'
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editSelectedGoalie f s = fromMaybe s $ do
|
||||
n <- s^.progMode.editGoalieStateL.egsSelectedGoalie
|
||||
let
|
||||
goalies = s^.database.dbGoalies
|
||||
goalies' = modifyNth n f goalies
|
||||
Just $ s & database.dbGoalies .~ goalies'
|
||||
|
||||
-- | Adds the entered player to the roster
|
||||
addPlayer :: ProgState -> ProgState
|
||||
addPlayer s = fromMaybe s $ do
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-}
|
||||
|
||||
module Mtlstats.Actions.EditGoalie
|
||||
( editGoalieNumber
|
||||
, editGoalieName
|
||||
, editGoalieYtdGames
|
||||
, editGoalieYtdMins
|
||||
, editGoalieYtdGoals
|
||||
, editGoalieYtdWins
|
||||
, editGoalieYtdLosses
|
||||
, editGoalieYtdTies
|
||||
, editGoalieLtGames
|
||||
, editGoalieLtMins
|
||||
, editGoalieLtGoals
|
||||
, editGoalieLtWins
|
||||
, editGoalieLtLosses
|
||||
, editGoalieLtTies
|
||||
) where
|
||||
|
||||
import Control.Monad (void)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Lens.Micro ((^.), (&), (.~), (%~))
|
||||
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Util
|
||||
|
||||
-- | Edits a goalie's number
|
||||
editGoalieNumber
|
||||
:: Int
|
||||
-- ^ New goalie number
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieNumber num = editGoalie (gNumber .~ num) EGMenu
|
||||
|
||||
-- | Edits a goalie's name
|
||||
editGoalieName
|
||||
:: String
|
||||
-- ^ The new name
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieName name = editGoalie (gName .~ name) EGMenu
|
||||
|
||||
-- | Edits a goalie's YTD games
|
||||
editGoalieYtdGames
|
||||
:: Int
|
||||
-- ^ The number of games played
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieYtdGames games = editGoalie (gYtd.gsGames .~ games) EGYtd
|
||||
|
||||
-- | Edits a goalie's YTD minutes
|
||||
editGoalieYtdMins
|
||||
:: Int
|
||||
-- ^ The number of minutes played
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieYtdMins mins = editGoalie (gYtd.gsMinsPlayed .~ mins) EGYtd
|
||||
|
||||
-- | Edits a goalie's YTD goals allowed
|
||||
editGoalieYtdGoals
|
||||
:: Int
|
||||
-- ^ The number of goals
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieYtdGoals goals = editGoalie (gYtd.gsGoalsAllowed .~ goals) EGYtd
|
||||
|
||||
-- | Edits a goalie's YTD wins
|
||||
editGoalieYtdWins
|
||||
:: Int
|
||||
-- ^ The number of wins
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieYtdWins wins = editGoalie (gYtd.gsWins .~ wins) EGYtd
|
||||
|
||||
-- | Edits a goalie's YTD losses
|
||||
editGoalieYtdLosses
|
||||
:: Int
|
||||
-- ^ The number of losses
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieYtdLosses losses = editGoalie (gYtd.gsLosses .~ losses) EGYtd
|
||||
|
||||
-- | Edits a goalie's YTD ties
|
||||
editGoalieYtdTies
|
||||
:: Int
|
||||
-- ^ The number of ties
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieYtdTies ties = editGoalie (gYtd.gsTies .~ ties) EGYtd
|
||||
|
||||
-- | Edits a goalie's lifetime games played
|
||||
editGoalieLtGames
|
||||
:: Int
|
||||
-- ^ The number of games
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieLtGames games = editGoalie (gLifetime.gsGames .~ games) EGLifetime
|
||||
|
||||
-- | Edits a goalie's lifetime minutes played
|
||||
editGoalieLtMins
|
||||
:: Int
|
||||
-- ^ The number of minutes
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieLtMins mins = editGoalie (gLifetime.gsMinsPlayed .~ mins) EGLifetime
|
||||
|
||||
-- | Edits a goalie's lifetime goals allowed
|
||||
editGoalieLtGoals
|
||||
:: Int
|
||||
-- ^ The number of goals
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieLtGoals goals = editGoalie (gLifetime.gsGoalsAllowed .~ goals) EGLifetime
|
||||
|
||||
-- | Edits a goalie's lifetime wins
|
||||
editGoalieLtWins
|
||||
:: Int
|
||||
-- ^ The number of wins
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieLtWins wins = editGoalie (gLifetime.gsWins .~ wins) EGLifetime
|
||||
|
||||
-- | Edits a goalie's lifetime losses
|
||||
editGoalieLtLosses
|
||||
:: Int
|
||||
-- ^ The number of losses
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieLtLosses losses = editGoalie (gLifetime.gsLosses .~ losses) EGLifetime
|
||||
|
||||
-- | Edits a goalie's lifetime ties
|
||||
editGoalieLtTies
|
||||
:: Int
|
||||
-- ^ The number of ties
|
||||
-> ProgState
|
||||
-> ProgState
|
||||
editGoalieLtTies ties = editGoalie (gLifetime.gsTies .~ ties) EGLifetime
|
||||
|
||||
editGoalie :: (Goalie -> Goalie) -> EditGoalieMode -> ProgState -> ProgState
|
||||
editGoalie f mode s = fromMaybe s $ do
|
||||
gid <- s^.progMode.editGoalieStateL.egsSelectedGoalie
|
||||
void $ nth gid $ s^.database.dbGoalies
|
||||
Just $ s
|
||||
& database.dbGoalies %~ modifyNth gid f
|
||||
& progMode.editGoalieStateL.egsMode .~ mode
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -41,9 +41,10 @@ import Mtlstats.Types
|
||||
-- run
|
||||
dispatch :: ProgState -> Controller
|
||||
dispatch s = case s^.progMode of
|
||||
MainMenu -> mainMenuC
|
||||
NewSeason -> newSeasonC
|
||||
MainMenu -> mainMenuC
|
||||
NewSeason -> newSeasonC
|
||||
NewGame gs -> newGameC gs
|
||||
EditMenu -> editMenuC
|
||||
CreatePlayer cps
|
||||
| null $ cps^.cpsNumber -> getPlayerNumC
|
||||
| null $ cps^.cpsName -> getPlayerNameC
|
||||
@@ -70,6 +71,9 @@ newSeasonC = Controller
|
||||
return True
|
||||
}
|
||||
|
||||
editMenuC :: Controller
|
||||
editMenuC = menuController editMenu
|
||||
|
||||
getPlayerNumC :: Controller
|
||||
getPlayerNumC = Controller
|
||||
{ drawController = drawPrompt playerNumPrompt
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -46,23 +46,25 @@ selectC = promptController goalieToEditPrompt
|
||||
|
||||
editC :: EditGoalieMode -> Controller
|
||||
editC = \case
|
||||
EGMenu -> menuC
|
||||
EGNumber -> numberC
|
||||
EGName -> nameC
|
||||
EGYtd -> ytdMenuC
|
||||
EGLifetime -> lifetimeMenuC
|
||||
EGYtdGames -> ytdGamesC
|
||||
EGYtdMins -> ytdMinsC
|
||||
EGYtdGoals -> ytdGoalsC
|
||||
EGYtdWins -> ytdWinsC
|
||||
EGYtdLosses -> ytdLossesC
|
||||
EGYtdTies -> ytdTiesC
|
||||
EGLtGames -> ltGamesC
|
||||
EGLtMins -> ltMinsC
|
||||
EGLtGoals -> ltGoalsC
|
||||
EGLtWins -> ltWinsC
|
||||
EGLtLosses -> ltLossesC
|
||||
EGLtTies -> ltTiesC
|
||||
EGMenu -> menuC
|
||||
EGNumber -> numberC
|
||||
EGName -> nameC
|
||||
EGYtd -> ytdMenuC
|
||||
EGLifetime -> lifetimeMenuC
|
||||
EGYtdGames b -> ytdGamesC b
|
||||
EGYtdMins b -> ytdMinsC b
|
||||
EGYtdGoals b -> ytdGoalsC b
|
||||
EGYtdShutouts b -> ytdShutoutsC b
|
||||
EGYtdWins b -> ytdWinsC b
|
||||
EGYtdLosses b -> ytdLossesC b
|
||||
EGYtdTies -> ytdTiesC
|
||||
EGLtGames b -> ltGamesC b
|
||||
EGLtMins b -> ltMinsC b
|
||||
EGLtGoals b -> ltGoalsC b
|
||||
EGLtShutouts b -> ltShutoutsC b
|
||||
EGLtWins b -> ltWinsC b
|
||||
EGLtLosses b -> ltLossesC b
|
||||
EGLtTies -> ltTiesC
|
||||
|
||||
menuC :: Controller
|
||||
menuC = menuControllerWith header editGoalieMenu
|
||||
@@ -79,38 +81,44 @@ ytdMenuC = menuControllerWith header editGoalieYtdMenu
|
||||
lifetimeMenuC :: Controller
|
||||
lifetimeMenuC = menuControllerWith header editGoalieLtMenu
|
||||
|
||||
ytdGamesC :: Controller
|
||||
ytdGamesC = promptController editGoalieYtdGamesPrompt
|
||||
ytdGamesC :: Bool -> Controller
|
||||
ytdGamesC = promptController . editGoalieYtdGamesPrompt
|
||||
|
||||
ytdMinsC :: Controller
|
||||
ytdMinsC = promptController editGoalieYtdMinsPrompt
|
||||
ytdMinsC :: Bool -> Controller
|
||||
ytdMinsC = promptController . editGoalieYtdMinsPrompt
|
||||
|
||||
ytdGoalsC :: Controller
|
||||
ytdGoalsC = promptController editGoalieYtdGoalsPrompt
|
||||
ytdGoalsC :: Bool -> Controller
|
||||
ytdGoalsC = promptController . editGoalieYtdGoalsPrompt
|
||||
|
||||
ytdWinsC :: Controller
|
||||
ytdWinsC = promptController editGoalieYtdWinsPrompt
|
||||
ytdShutoutsC :: Bool -> Controller
|
||||
ytdShutoutsC = promptController . editGoalieYtdShutoutsPrompt
|
||||
|
||||
ytdLossesC :: Controller
|
||||
ytdLossesC = promptController editGoalieYtdLossesPrompt
|
||||
ytdWinsC :: Bool -> Controller
|
||||
ytdWinsC = promptController . editGoalieYtdWinsPrompt
|
||||
|
||||
ytdLossesC :: Bool -> Controller
|
||||
ytdLossesC = promptController . editGoalieYtdLossesPrompt
|
||||
|
||||
ytdTiesC :: Controller
|
||||
ytdTiesC = promptController editGoalieYtdTiesPrompt
|
||||
|
||||
ltGamesC :: Controller
|
||||
ltGamesC = promptController editGoalieLtGamesPrompt
|
||||
ltGamesC :: Bool -> Controller
|
||||
ltGamesC = promptController . editGoalieLtGamesPrompt
|
||||
|
||||
ltMinsC :: Controller
|
||||
ltMinsC = promptController editGoalieLtMinsPrompt
|
||||
ltMinsC :: Bool -> Controller
|
||||
ltMinsC = promptController . editGoalieLtMinsPrompt
|
||||
|
||||
ltGoalsC :: Controller
|
||||
ltGoalsC = promptController editGoalieLtGoalsPrompt
|
||||
ltGoalsC :: Bool -> Controller
|
||||
ltGoalsC = promptController . editGoalieLtGoalsPrompt
|
||||
|
||||
ltWinsC :: Controller
|
||||
ltWinsC = promptController editGoalieLtWinsPrompt
|
||||
ltShutoutsC :: Bool -> Controller
|
||||
ltShutoutsC = promptController . editGoalieLtShutoutsPrompt
|
||||
|
||||
ltLossesC :: Controller
|
||||
ltLossesC = promptController editGoalieLtLossesPrompt
|
||||
ltWinsC :: Bool -> Controller
|
||||
ltWinsC = promptController . editGoalieLtWinsPrompt
|
||||
|
||||
ltLossesC :: Bool -> Controller
|
||||
ltLossesC = promptController . editGoalieLtLossesPrompt
|
||||
|
||||
ltTiesC :: Controller
|
||||
ltTiesC = promptController editGoalieLtTiesPrompt
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -38,18 +38,18 @@ editPlayerC :: EditPlayerState -> Controller
|
||||
editPlayerC eps
|
||||
| null $ eps^.epsSelectedPlayer = selectPlayerC
|
||||
| otherwise = case eps^.epsMode of
|
||||
EPMenu -> menuC
|
||||
EPNumber -> numberC
|
||||
EPName -> nameC
|
||||
EPPosition -> positionC
|
||||
EPYtd -> ytdC
|
||||
EPLifetime -> lifetimeC
|
||||
EPYtdGoals -> ytdGoalsC
|
||||
EPYtdAssists -> ytdAssistsC
|
||||
EPYtdPMin -> ytdPMinC
|
||||
EPLtGoals -> ltGoalsC
|
||||
EPLtAssists -> ltAssistsC
|
||||
EPLtPMin -> ltPMinC
|
||||
EPMenu -> menuC
|
||||
EPNumber -> numberC
|
||||
EPName -> nameC
|
||||
EPPosition -> positionC
|
||||
EPYtd -> ytdC
|
||||
EPLifetime -> lifetimeC
|
||||
EPYtdGoals b -> ytdGoalsC b
|
||||
EPYtdAssists b -> ytdAssistsC b
|
||||
EPYtdPMin -> ytdPMinC
|
||||
EPLtGoals b -> ltGoalsC b
|
||||
EPLtAssists b -> ltAssistsC b
|
||||
EPLtPMin -> ltPMinC
|
||||
|
||||
selectPlayerC :: Controller
|
||||
selectPlayerC = promptController playerToEditPrompt
|
||||
@@ -72,20 +72,20 @@ ytdC = menuControllerWith header editPlayerYtdMenu
|
||||
lifetimeC :: Controller
|
||||
lifetimeC = menuControllerWith header editPlayerLtMenu
|
||||
|
||||
ytdGoalsC :: Controller
|
||||
ytdGoalsC = promptController editPlayerYtdGoalsPrompt
|
||||
ytdGoalsC :: Bool -> Controller
|
||||
ytdGoalsC = promptController . editPlayerYtdGoalsPrompt
|
||||
|
||||
ytdAssistsC :: Controller
|
||||
ytdAssistsC = promptController editPlayerYtdAssistsPrompt
|
||||
ytdAssistsC :: Bool -> Controller
|
||||
ytdAssistsC = promptController . editPlayerYtdAssistsPrompt
|
||||
|
||||
ytdPMinC :: Controller
|
||||
ytdPMinC = promptController editPlayerYtdPMinPrompt
|
||||
|
||||
ltGoalsC :: Controller
|
||||
ltGoalsC = promptController editPlayerLtGoalsPrompt
|
||||
ltGoalsC :: Bool -> Controller
|
||||
ltGoalsC = promptController . editPlayerLtGoalsPrompt
|
||||
|
||||
ltAssistsC :: Controller
|
||||
ltAssistsC = promptController editPlayerLtAssistsPrompt
|
||||
ltAssistsC :: Bool -> Controller
|
||||
ltAssistsC = promptController . editPlayerLtAssistsPrompt
|
||||
|
||||
ltPMinC :: Controller
|
||||
ltPMinC = promptController editPlayerLtPMinPrompt
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -26,6 +26,7 @@ module Mtlstats.Format
|
||||
, left
|
||||
, right
|
||||
, centre
|
||||
, padRight
|
||||
, overlay
|
||||
, month
|
||||
, labelTable
|
||||
@@ -87,6 +88,16 @@ centre n str = let
|
||||
pad = replicate pLen ' '
|
||||
in take n $ pad ++ str ++ repeat ' '
|
||||
|
||||
-- | Pads text on the right with spaces to fit a minimum width
|
||||
padRight
|
||||
:: Int
|
||||
-- ^ The width to pad to
|
||||
-> String
|
||||
-- ^ The text to pad
|
||||
-> String
|
||||
padRight width str =
|
||||
overlay str $ replicate width ' '
|
||||
|
||||
-- | Overlays one string on top of another
|
||||
overlay
|
||||
:: String
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-}
|
||||
|
||||
module Mtlstats.Helpers.Goalie (goalieDetails) where
|
||||
module Mtlstats.Helpers.Goalie (goalieDetails, goalieName) where
|
||||
|
||||
import Lens.Micro ((^.))
|
||||
|
||||
@@ -31,7 +31,7 @@ goalieDetails :: Goalie -> String
|
||||
goalieDetails g = let
|
||||
header = unlines $ labelTable
|
||||
[ ( "Number", show $ g^.gNumber )
|
||||
, ( "Name", g^.gName )
|
||||
, ( "Name", goalieName g )
|
||||
]
|
||||
|
||||
body = unlines $ numTable ["YTD", "Lifetime"] $ map
|
||||
@@ -39,9 +39,20 @@ goalieDetails g = let
|
||||
[ ( "Games played", gsGames )
|
||||
, ( "Mins played", gsMinsPlayed )
|
||||
, ( "Goals allowed", gsGoalsAllowed )
|
||||
, ( "Shutouts", gsShutouts )
|
||||
, ( "Wins", gsWins )
|
||||
, ( "Losses", gsLosses )
|
||||
, ( "Ties", gsTies )
|
||||
]
|
||||
|
||||
in header ++ "\n" ++ body
|
||||
|
||||
-- | Returns the goalie name, modified if they are a rookie
|
||||
goalieName :: Goalie -> String
|
||||
goalieName g = let
|
||||
|
||||
suffix = if g^.gRookie
|
||||
then "*"
|
||||
else ""
|
||||
|
||||
in g^.gName ++ suffix
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-}
|
||||
|
||||
module Mtlstats.Helpers.Player (playerDetails) where
|
||||
module Mtlstats.Helpers.Player (playerDetails, playerName) where
|
||||
|
||||
import Lens.Micro ((^.))
|
||||
|
||||
@@ -32,7 +32,7 @@ playerDetails p = unlines $ top ++ [""] ++ table
|
||||
where
|
||||
top = labelTable
|
||||
[ ( "Number", show $ p^.pNumber )
|
||||
, ( "Name", p^.pName )
|
||||
, ( "Name", playerName p )
|
||||
, ( "Position", p^.pPosition )
|
||||
]
|
||||
|
||||
@@ -43,3 +43,14 @@ playerDetails p = unlines $ top ++ [""] ++ table
|
||||
, ( "Assists", psAssists )
|
||||
, ( "Penalty mins", psPMin )
|
||||
]
|
||||
|
||||
-- | Presents a modified version of the player's name indicating
|
||||
-- whether or not they're a rookie
|
||||
playerName :: Player -> String
|
||||
playerName p = let
|
||||
|
||||
suffix = if p^.pRookie
|
||||
then "*"
|
||||
else ""
|
||||
|
||||
in p^.pName ++ suffix
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -31,7 +31,8 @@ module Mtlstats.Menu (
|
||||
newSeasonMenu,
|
||||
gameMonthMenu,
|
||||
gameTypeMenu,
|
||||
gameGoalieMenu
|
||||
gameGoalieMenu,
|
||||
editMenu
|
||||
) where
|
||||
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
@@ -113,14 +114,8 @@ mainMenu = Menu "*** MAIN MENU ***" True
|
||||
modify startNewSeason >> return True
|
||||
, MenuItem '2' "New Game" $
|
||||
modify startNewGame >> return True
|
||||
, MenuItem '3' "Create Player" $
|
||||
modify createPlayer >> return True
|
||||
, MenuItem '4' "Create Goalie" $
|
||||
modify createGoalie >> return True
|
||||
, MenuItem '5' "Edit Player" $
|
||||
modify editPlayer >> return True
|
||||
, MenuItem '6' "Edit Goalie" $
|
||||
modify editGoalie >> return True
|
||||
, MenuItem '3' "Edit" $
|
||||
modify edit >> return True
|
||||
, MenuItem 'X' "Exit" $ do
|
||||
db <- gets $ view database
|
||||
liftIO $ do
|
||||
@@ -186,3 +181,18 @@ gameGoalieMenu s = let
|
||||
(\(ch, (gid, goalie)) -> MenuItem ch (goalieSummary goalie) $
|
||||
modify $ GI.setGameGoalie gid) $
|
||||
zip ['1'..] goalies
|
||||
|
||||
-- | The edit menu
|
||||
editMenu :: Menu ()
|
||||
editMenu = Menu "*** EDIT ***" ()
|
||||
[ MenuItem '1' "Create Player" $
|
||||
modify createPlayer
|
||||
, MenuItem '2' "Create Goalie" $
|
||||
modify createGoalie
|
||||
, MenuItem '3' "Edit Player" $
|
||||
modify editPlayer
|
||||
, MenuItem '4' "Edit Goalie" $
|
||||
modify editGoalie
|
||||
, MenuItem 'R' "Return to Main Menu" $
|
||||
modify backHome
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -26,38 +26,43 @@ module Mtlstats.Menu.EditGoalie
|
||||
) where
|
||||
|
||||
import Control.Monad.Trans.State (modify)
|
||||
import Data.Maybe (maybe)
|
||||
import Lens.Micro ((.~))
|
||||
import Lens.Micro ((.~), (%~))
|
||||
|
||||
import Mtlstats.Actions
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Types.Menu
|
||||
|
||||
-- | The 'Goalie' edit menu
|
||||
editGoalieMenu :: Menu ()
|
||||
editGoalieMenu = Menu "*** EDIT GOALTENDER ***" () $ map
|
||||
(\(key, label, val) -> MenuItem key label $ modify $ maybe
|
||||
(progMode .~ MainMenu)
|
||||
(progMode.editGoalieStateL.egsMode .~)
|
||||
val)
|
||||
(\(ch, label, action) -> MenuItem ch label $ modify action)
|
||||
|
||||
-- key, label, value
|
||||
[ ( '1', "Edit number", Just EGNumber )
|
||||
, ( '2', "Edit name", Just EGName )
|
||||
, ( '3', "Edit YTD stats", Just EGYtd )
|
||||
, ( '4', "Edit Lifetime stats", Just EGLifetime )
|
||||
, ( 'R', "Return to Main Menu", Nothing )
|
||||
[ ( '1', "Edit number", set EGNumber )
|
||||
, ( '2', "Edit name", set EGName )
|
||||
, ( '3', "Toggle rookie flag", toggle )
|
||||
, ( '4', "Edit YTD stats", set EGYtd )
|
||||
, ( '5', "Edit Lifetime stats", set EGLifetime )
|
||||
, ( 'R', "Return to Edit Menu", edit )
|
||||
]
|
||||
|
||||
where
|
||||
set mode = progMode.editGoalieStateL.egsMode .~ mode
|
||||
toggle = editSelectedGoalie (gRookie %~ not)
|
||||
|
||||
-- | The 'Goalie' YTD edit menu
|
||||
editGoalieYtdMenu :: Menu ()
|
||||
editGoalieYtdMenu = editMenu "*** EDIT GOALTENDER YEAR-TO-DATE ***"
|
||||
-- key, label, value
|
||||
[ ( '1', "Edit YTD games", EGYtdGames )
|
||||
, ( '2', "Edit YTD minutes", EGYtdMins )
|
||||
, ( '3', "Edit YTD goals", EGYtdGoals )
|
||||
, ( '4', "Edit YTD wins", EGYtdWins )
|
||||
, ( '5', "Edit YTD losses", EGYtdLosses )
|
||||
, ( '6', "Edit YTD ties", EGYtdTies )
|
||||
, ( 'R', "Return to edit menu", EGMenu )
|
||||
[ ( '1', "Edit all YTD stats", EGYtdGames True )
|
||||
, ( '2', "Edit YTD games", EGYtdGames False )
|
||||
, ( '3', "Edit YTD minutes", EGYtdMins False )
|
||||
, ( '4', "Edit YTD goals", EGYtdGoals False )
|
||||
, ( '5', "Edit YTD shutouts", EGYtdShutouts False )
|
||||
, ( '6', "Edit YTD wins", EGYtdWins False )
|
||||
, ( '7', "Edit YTD losses", EGYtdLosses False )
|
||||
, ( '8', "Edit YTD ties", EGYtdTies )
|
||||
, ( 'R', "Return to edit menu", EGMenu )
|
||||
]
|
||||
|
||||
-- | The 'Goalie' lifetime edit menu
|
||||
@@ -65,13 +70,15 @@ editGoalieLtMenu :: Menu ()
|
||||
editGoalieLtMenu = editMenu
|
||||
"*** EDIT GOALTENDER LIFETIME ***"
|
||||
-- key, label, value
|
||||
[ ( '1', "Edit lifetime games", EGLtGames )
|
||||
, ( '2', "Edit lifetime minutes", EGLtMins )
|
||||
, ( '3', "Edit lifetime goals", EGLtGoals )
|
||||
, ( '4', "Edit lifetime wins", EGLtWins )
|
||||
, ( '5', "Edit lifetime losses", EGLtLosses )
|
||||
, ( '6', "Edit lifetime ties", EGLtTies )
|
||||
, ( 'R', "Return to edit menu", EGMenu )
|
||||
[ ( '1', "Edit all lifetime stats", EGLtGames True )
|
||||
, ( '2', "Edit lifetime games", EGLtGames False )
|
||||
, ( '3', "Edit lifetime minutes", EGLtMins False )
|
||||
, ( '4', "Edit lifetime goals", EGLtGoals False )
|
||||
, ( '5', "Edit lifetime shutouts", EGLtShutouts False )
|
||||
, ( '6', "Edit lifetime wins", EGLtWins False )
|
||||
, ( '7', "Edit lifetime losses", EGLtLosses False )
|
||||
, ( '8', "Edit lifetime ties", EGLtTies )
|
||||
, ( 'R', "Return to edit menu", EGMenu )
|
||||
]
|
||||
|
||||
editMenu :: String -> [(Char, String, EditGoalieMode)] -> Menu ()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -26,35 +26,41 @@ module Mtlstats.Menu.EditPlayer
|
||||
) where
|
||||
|
||||
import Control.Monad.Trans.State (modify)
|
||||
import Lens.Micro ((.~))
|
||||
import Lens.Micro ((.~), (%~))
|
||||
|
||||
import Mtlstats.Actions
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Types.Menu
|
||||
|
||||
-- | The 'Player' edit menu
|
||||
editPlayerMenu :: Menu ()
|
||||
editPlayerMenu = Menu "*** EDIT PLAYER ***" () $ map
|
||||
(\(ch, label, mode) -> MenuItem ch label $ case mode of
|
||||
Nothing -> modify $ progMode .~ MainMenu
|
||||
Just m -> modify $ progMode.editPlayerStateL.epsMode .~ m)
|
||||
(\(ch, label, action) -> MenuItem ch label $ modify action)
|
||||
|
||||
-- key, label, value
|
||||
[ ( '1', "Edit number", Just EPNumber )
|
||||
, ( '2', "Edit name", Just EPName )
|
||||
, ( '3', "Edit position", Just EPPosition )
|
||||
, ( '4', "Edit YTD stats", Just EPYtd )
|
||||
, ( '5', "Edit lifetime stats", Just EPLifetime )
|
||||
, ( 'R', "Finished editing", Nothing )
|
||||
[ ( '1', "Edit number", set EPNumber )
|
||||
, ( '2', "Edit name", set EPName )
|
||||
, ( '3', "Edit position", set EPPosition )
|
||||
, ( '4', "Toggle rookie flag", toggle )
|
||||
, ( '5', "Edit YTD stats", set EPYtd )
|
||||
, ( '6', "Edit lifetime stats", set EPLifetime )
|
||||
, ( 'R', "Return to Edit Menu", edit )
|
||||
]
|
||||
|
||||
where
|
||||
set mode = progMode.editPlayerStateL.epsMode .~ mode
|
||||
toggle = editSelectedPlayer $ pRookie %~ not
|
||||
|
||||
-- | The 'Player' YTD stats edit menu
|
||||
editPlayerYtdMenu :: Menu ()
|
||||
editPlayerYtdMenu = editMenu
|
||||
"*** EDIT PLAYER YEAR-TO-DATE ***"
|
||||
-- key, label, value
|
||||
[ ( '1', "Edit YTD goals", EPYtdGoals )
|
||||
, ( '2', "Edit YTD assists", EPYtdAssists )
|
||||
, ( '3', "Edit YTD penalty mins", EPYtdPMin )
|
||||
, ( 'R', "Return to player edit menu", EPMenu )
|
||||
[ ( '1', "Edit all YTD stats", EPYtdGoals True )
|
||||
, ( '2', "Edit YTD goals", EPYtdGoals False )
|
||||
, ( '3', "Edit YTD assists", EPYtdAssists False )
|
||||
, ( '4', "Edit YTD penalty mins", EPYtdPMin )
|
||||
, ( 'R', "Return to player edit menu", EPMenu )
|
||||
]
|
||||
|
||||
-- | The 'Player' lifetime stats edit menu
|
||||
@@ -62,10 +68,11 @@ editPlayerLtMenu :: Menu ()
|
||||
editPlayerLtMenu = editMenu
|
||||
"*** EDIT PLAYER LIFETIME ***"
|
||||
-- key, label, value
|
||||
[ ( '1', "Edit lifetime goals", EPLtGoals )
|
||||
, ( '2', "Edit lifetime assits", EPLtAssists )
|
||||
, ( '3', "Edit lifetime penalty mins", EPLtPMin )
|
||||
, ( 'R', "Return to edit player menu", EPMenu )
|
||||
[ ( '1', "Edit all lifetime stats", EPLtGoals True )
|
||||
, ( '2', "Edit lifetime goals", EPLtGoals False )
|
||||
, ( '3', "Edit lifetime assits", EPLtAssists False )
|
||||
, ( '4', "Edit lifetime penalty mins", EPLtPMin )
|
||||
, ( 'R', "Return to edit player menu", EPMenu )
|
||||
]
|
||||
|
||||
editMenu :: String -> [(Char, String, EditPlayerMode)] -> Menu ()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -29,7 +29,9 @@ module Mtlstats.Prompt (
|
||||
promptController,
|
||||
strPrompt,
|
||||
ucStrPrompt,
|
||||
namePrompt,
|
||||
numPrompt,
|
||||
numPromptWithFallback,
|
||||
selectPrompt,
|
||||
-- * Individual prompts
|
||||
playerNumPrompt,
|
||||
@@ -46,7 +48,6 @@ import Control.Monad (when)
|
||||
import Control.Monad.Extra (whenJust)
|
||||
import Control.Monad.Trans.State (gets, modify)
|
||||
import Data.Char (isDigit, toUpper)
|
||||
import Data.Foldable (forM_)
|
||||
import Lens.Micro ((^.), (&), (.~), (?~), (%~))
|
||||
import Lens.Micro.Extras (view)
|
||||
import Text.Read (readMaybe)
|
||||
@@ -126,6 +127,17 @@ ucStrPrompt
|
||||
ucStrPrompt pStr act = (strPrompt pStr act)
|
||||
{ promptProcessChar = \ch -> (++ [toUpper ch]) }
|
||||
|
||||
-- | Creates a prompt which forces capitalization of input to
|
||||
-- accomodate a player or goalie name
|
||||
namePrompt
|
||||
:: String
|
||||
-- ^ The prompt string
|
||||
-> (String -> Action ())
|
||||
-- ^ The callback function for the result
|
||||
-> Prompt
|
||||
namePrompt pStr act = (strPrompt pStr act)
|
||||
{ promptProcessChar = capitalizeName }
|
||||
|
||||
-- | Builds a numeric prompt
|
||||
numPrompt
|
||||
:: String
|
||||
@@ -133,12 +145,25 @@ numPrompt
|
||||
-> (Int -> Action ())
|
||||
-- ^ The callback function for the result
|
||||
-> Prompt
|
||||
numPrompt pStr act = Prompt
|
||||
numPrompt pStr = numPromptWithFallback pStr $ return ()
|
||||
|
||||
-- | Builds a numeric prompt with a fallback action
|
||||
numPromptWithFallback
|
||||
:: String
|
||||
-- ^ The prompt string
|
||||
-> Action ()
|
||||
-- ^ The action to call on invalid (or blank) input
|
||||
-> (Int -> Action ())
|
||||
-- ^ The callback function for the result
|
||||
-> Prompt
|
||||
numPromptWithFallback pStr fallback act = Prompt
|
||||
{ promptDrawer = drawSimplePrompt pStr
|
||||
, promptProcessChar = \ch str -> if isDigit ch
|
||||
then str ++ [ch]
|
||||
else str
|
||||
, promptAction = \inStr -> forM_ (readMaybe inStr) act
|
||||
, promptAction = \inStr -> case readMaybe inStr of
|
||||
Nothing -> fallback
|
||||
Just n -> act n
|
||||
, promptSpecialKey = const $ return ()
|
||||
}
|
||||
|
||||
@@ -157,7 +182,7 @@ selectPrompt params = Prompt
|
||||
in "F" ++ show n ++ ") " ++ desc)
|
||||
results
|
||||
C.moveCursor row col
|
||||
, promptProcessChar = \ch -> (++[ch])
|
||||
, promptProcessChar = spProcessChar params
|
||||
, promptAction = \sStr -> if null sStr
|
||||
then spCallback params Nothing
|
||||
else do
|
||||
@@ -186,7 +211,7 @@ playerNumPrompt = numPrompt "Player number: " $
|
||||
|
||||
-- | Prompts for a new player's name
|
||||
playerNamePrompt :: Prompt
|
||||
playerNamePrompt = strPrompt "Player name: " $
|
||||
playerNamePrompt = namePrompt "Player name: " $
|
||||
modify . (progMode.createPlayerStateL.cpsName .~)
|
||||
|
||||
-- | Prompts for a new player's position
|
||||
@@ -201,7 +226,7 @@ goalieNumPrompt = numPrompt "Goalie number: " $
|
||||
|
||||
-- | Prompts for the goalie's name
|
||||
goalieNamePrompt :: Prompt
|
||||
goalieNamePrompt = strPrompt "Goalie name: " $
|
||||
goalieNamePrompt = namePrompt "Goalie name: " $
|
||||
modify . (progMode.createGoalieStateL.cgsName .~)
|
||||
|
||||
-- | Selects a player (creating one if necessary)
|
||||
@@ -218,6 +243,7 @@ selectPlayerPrompt pStr callback = selectPrompt SelectParams
|
||||
, spSearch = \sStr db -> playerSearch sStr (db^.dbPlayers)
|
||||
, spSearchExact = \sStr db -> fst <$> playerSearchExact sStr (db^.dbPlayers)
|
||||
, spElemDesc = playerSummary
|
||||
, spProcessChar = capitalizeName
|
||||
, spCallback = callback
|
||||
, spNotFound = \sStr -> do
|
||||
mode <- gets (^.progMode)
|
||||
@@ -246,6 +272,7 @@ selectGoaliePrompt pStr callback = selectPrompt SelectParams
|
||||
, spSearch = \sStr db -> goalieSearch sStr (db^.dbGoalies)
|
||||
, spSearchExact = \sStr db -> fst <$> goalieSearchExact sStr (db^.dbGoalies)
|
||||
, spElemDesc = goalieSummary
|
||||
, spProcessChar = capitalizeName
|
||||
, spCallback = callback
|
||||
, spNotFound = \sStr -> do
|
||||
mode <- gets (^.progMode)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -26,12 +26,14 @@ module Mtlstats.Prompt.EditGoalie
|
||||
, editGoalieYtdGamesPrompt
|
||||
, editGoalieYtdMinsPrompt
|
||||
, editGoalieYtdGoalsPrompt
|
||||
, editGoalieYtdShutoutsPrompt
|
||||
, editGoalieYtdWinsPrompt
|
||||
, editGoalieYtdLossesPrompt
|
||||
, editGoalieYtdTiesPrompt
|
||||
, editGoalieLtGamesPrompt
|
||||
, editGoalieLtMinsPrompt
|
||||
, editGoalieLtGoalsPrompt
|
||||
, editGoalieLtShutoutsPrompt
|
||||
, editGoalieLtWinsPrompt
|
||||
, editGoalieLtLossesPrompt
|
||||
, editGoalieLtTiesPrompt
|
||||
@@ -40,7 +42,7 @@ module Mtlstats.Prompt.EditGoalie
|
||||
import Control.Monad.Trans.State (modify)
|
||||
import Lens.Micro ((.~))
|
||||
|
||||
import Mtlstats.Actions.EditGoalie
|
||||
import Mtlstats.Actions
|
||||
import Mtlstats.Prompt
|
||||
import Mtlstats.Types
|
||||
|
||||
@@ -51,70 +53,171 @@ goalieToEditPrompt = selectGoaliePrompt "Goalie to edit: " $
|
||||
|
||||
-- | Prompt to edit a goalie's number
|
||||
editGoalieNumberPrompt :: Prompt
|
||||
editGoalieNumberPrompt = numPrompt "Goalie number: " $
|
||||
modify . editGoalieNumber
|
||||
editGoalieNumberPrompt = editNum "Goalie number: " EGMenu
|
||||
(gNumber .~)
|
||||
|
||||
-- | Prompt to edit a goalie's name
|
||||
editGoalieNamePrompt :: Prompt
|
||||
editGoalieNamePrompt = strPrompt "Goalie name: " $
|
||||
modify . editGoalieName
|
||||
editGoalieNamePrompt = namePrompt "Goalie name: " $ \name ->
|
||||
if null name
|
||||
then goto EGMenu
|
||||
else doEdit EGMenu $ gName .~ name
|
||||
|
||||
-- | Prompt to edit a goalie's YTD games played
|
||||
editGoalieYtdGamesPrompt :: Prompt
|
||||
editGoalieYtdGamesPrompt = numPrompt "Year-to-date games played: " $
|
||||
modify . editGoalieYtdGames
|
||||
editGoalieYtdGamesPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieYtdGamesPrompt batchMode =
|
||||
editNum "Year-to-date games played: " mode
|
||||
(gYtd.gsGames .~)
|
||||
where
|
||||
mode = if batchMode then EGYtdMins True else EGYtd
|
||||
|
||||
-- | Prompt to edit a goalie's YTD minutes played
|
||||
editGoalieYtdMinsPrompt :: Prompt
|
||||
editGoalieYtdMinsPrompt = numPrompt "Year-to-date minutes played: " $
|
||||
modify . editGoalieYtdMins
|
||||
editGoalieYtdMinsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieYtdMinsPrompt batchMode =
|
||||
editNum "Year-to-date minutes played: " mode
|
||||
(gYtd.gsMinsPlayed .~)
|
||||
where
|
||||
mode = if batchMode then EGYtdGoals True else EGYtd
|
||||
|
||||
-- | Prompt to edit a goalie's YTD goales allowed
|
||||
editGoalieYtdGoalsPrompt :: Prompt
|
||||
editGoalieYtdGoalsPrompt = numPrompt "Year-to-date goals allowed: " $
|
||||
modify . editGoalieYtdGoals
|
||||
editGoalieYtdGoalsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieYtdGoalsPrompt batchMode =
|
||||
editNum "Year-to-date goals allowed: " mode
|
||||
(gYtd.gsGoalsAllowed .~)
|
||||
where
|
||||
mode = if batchMode then EGYtdShutouts True else EGYtd
|
||||
|
||||
-- | Prompt to edit a goalie's YTD shutouts
|
||||
editGoalieYtdShutoutsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieYtdShutoutsPrompt batchMode =
|
||||
editNum "Year-to-date shutouts: " mode
|
||||
(gYtd.gsShutouts .~)
|
||||
where
|
||||
mode = if batchMode then EGYtdWins True else EGYtd
|
||||
|
||||
-- | Prompt to edit a goalie's YTD wins
|
||||
editGoalieYtdWinsPrompt :: Prompt
|
||||
editGoalieYtdWinsPrompt = numPrompt "Year-to-date wins: " $
|
||||
modify . editGoalieYtdWins
|
||||
editGoalieYtdWinsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieYtdWinsPrompt batchMode =
|
||||
editNum "Year-to-date wins: " mode
|
||||
(gYtd.gsWins .~)
|
||||
where
|
||||
mode = if batchMode then EGYtdLosses True else EGYtd
|
||||
|
||||
-- | Prompt to edit a goalie's YTD losses
|
||||
editGoalieYtdLossesPrompt :: Prompt
|
||||
editGoalieYtdLossesPrompt = numPrompt "Year-to-date losses: " $
|
||||
modify . editGoalieYtdLosses
|
||||
editGoalieYtdLossesPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieYtdLossesPrompt batchMode =
|
||||
editNum "Year-to-date losses: " mode
|
||||
(gYtd.gsLosses .~)
|
||||
where
|
||||
mode = if batchMode then EGYtdTies else EGYtd
|
||||
|
||||
-- | Prompt to edit a goalie's YTD ties
|
||||
editGoalieYtdTiesPrompt :: Prompt
|
||||
editGoalieYtdTiesPrompt = numPrompt "Year-to-date ties: " $
|
||||
modify . editGoalieYtdTies
|
||||
editGoalieYtdTiesPrompt = editNum "Year-to-date ties: " EGYtd
|
||||
(gYtd.gsTies .~)
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime games played
|
||||
editGoalieLtGamesPrompt :: Prompt
|
||||
editGoalieLtGamesPrompt = numPrompt "Lifetime games played: " $
|
||||
modify . editGoalieLtGames
|
||||
editGoalieLtGamesPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieLtGamesPrompt batchMode =
|
||||
editNum "Lifetime games played: " mode
|
||||
(gLifetime.gsGames .~)
|
||||
where
|
||||
mode = if batchMode then EGLtMins True else EGLifetime
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime minutes played
|
||||
editGoalieLtMinsPrompt :: Prompt
|
||||
editGoalieLtMinsPrompt = numPrompt "Lifetime minutes played: " $
|
||||
modify . editGoalieLtMins
|
||||
editGoalieLtMinsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieLtMinsPrompt batchMode =
|
||||
editNum "Lifetime minutes played: " mode
|
||||
(gLifetime.gsMinsPlayed .~)
|
||||
where
|
||||
mode = if batchMode then EGLtGoals True else EGLifetime
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime goals allowed
|
||||
editGoalieLtGoalsPrompt :: Prompt
|
||||
editGoalieLtGoalsPrompt = numPrompt "Lifetime goals allowed: " $
|
||||
modify . editGoalieLtGoals
|
||||
editGoalieLtGoalsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieLtGoalsPrompt batchMode =
|
||||
editNum "Lifetime goals allowed: " mode
|
||||
(gLifetime.gsGoalsAllowed .~)
|
||||
where
|
||||
mode = if batchMode then EGLtShutouts True else EGLifetime
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime shutouts
|
||||
editGoalieLtShutoutsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieLtShutoutsPrompt batchMode =
|
||||
editNum "Lifetime shutouts: " mode
|
||||
(gLifetime.gsShutouts .~)
|
||||
where
|
||||
mode = if batchMode then EGLtWins True else EGLifetime
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime wins
|
||||
editGoalieLtWinsPrompt :: Prompt
|
||||
editGoalieLtWinsPrompt = numPrompt "Lifetime wins: " $
|
||||
modify . editGoalieLtWins
|
||||
editGoalieLtWinsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieLtWinsPrompt batchMode =
|
||||
editNum "Lifetime wins: " mode
|
||||
(gLifetime.gsWins .~)
|
||||
where
|
||||
mode = if batchMode then EGLtLosses True else EGLifetime
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime losses
|
||||
editGoalieLtLossesPrompt :: Prompt
|
||||
editGoalieLtLossesPrompt = numPrompt "Lifetime losses: " $
|
||||
modify . editGoalieLtLosses
|
||||
editGoalieLtLossesPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates whether or not we're in batch mode
|
||||
-> Prompt
|
||||
editGoalieLtLossesPrompt batchMode =
|
||||
editNum "Lifetime losses: " mode
|
||||
(gLifetime.gsLosses .~)
|
||||
where
|
||||
mode = if batchMode then EGLtTies else EGLifetime
|
||||
|
||||
-- | Prompt to edit a goalie's lifetime ties
|
||||
editGoalieLtTiesPrompt :: Prompt
|
||||
editGoalieLtTiesPrompt = numPrompt "Lifetime ties: " $
|
||||
modify . editGoalieLtTies
|
||||
editGoalieLtTiesPrompt = editNum "Lifetime ties: " EGLifetime
|
||||
(gLifetime.gsTies .~)
|
||||
|
||||
editNum
|
||||
:: String
|
||||
-> EditGoalieMode
|
||||
-> (Int -> Goalie -> Goalie)
|
||||
-> Prompt
|
||||
editNum pStr mode f = numPromptWithFallback pStr
|
||||
(goto mode)
|
||||
(doEdit mode . f)
|
||||
|
||||
doEdit :: EditGoalieMode -> (Goalie -> Goalie) -> Action ()
|
||||
doEdit mode f = do
|
||||
modify $ editSelectedGoalie f
|
||||
goto mode
|
||||
|
||||
goto :: EditGoalieMode -> Action ()
|
||||
goto = modify . (progMode.editGoalieStateL.egsMode .~)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -31,62 +31,95 @@ module Mtlstats.Prompt.EditPlayer
|
||||
, editPlayerLtPMinPrompt
|
||||
) where
|
||||
|
||||
import Control.Monad.Extra (whenJustM)
|
||||
import Control.Monad.Trans.State (gets, modify)
|
||||
import Lens.Micro ((^.), (.~), (%~))
|
||||
import Control.Monad.Trans.State (modify)
|
||||
import Lens.Micro ((.~))
|
||||
|
||||
import Mtlstats.Actions
|
||||
import Mtlstats.Prompt
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Util
|
||||
|
||||
-- | Prompt to edit a player's number
|
||||
editPlayerNumPrompt :: Prompt
|
||||
editPlayerNumPrompt = numPrompt "Player number: " $
|
||||
editPlayer . (pNumber .~)
|
||||
editPlayerNumPrompt = editNum "Player number: " EPMenu
|
||||
(pNumber .~)
|
||||
|
||||
-- | Prompt to edit a player's name
|
||||
editPlayerNamePrompt :: Prompt
|
||||
editPlayerNamePrompt = strPrompt "Player name: " $
|
||||
editPlayer . (pName .~)
|
||||
editPlayerNamePrompt = namePrompt "Player name: " $ \name ->
|
||||
if null name
|
||||
then goto EPMenu
|
||||
else doEdit EPMenu $ pName .~ name
|
||||
|
||||
-- | Prompt to edit a player's position
|
||||
editPlayerPosPrompt :: Prompt
|
||||
editPlayerPosPrompt = ucStrPrompt "Player position: " $
|
||||
editPlayer . (pPosition .~)
|
||||
editPlayerPosPrompt = ucStrPrompt "Player position: " $ \pos ->
|
||||
if null pos
|
||||
then goto EPMenu
|
||||
else doEdit EPMenu $ pPosition .~ pos
|
||||
|
||||
-- | Prompt to edit a player's year-to-date goals
|
||||
editPlayerYtdGoalsPrompt :: Prompt
|
||||
editPlayerYtdGoalsPrompt = numPrompt "Year-to-date goals: " $
|
||||
editPlayer . (pYtd.psGoals .~)
|
||||
editPlayerYtdGoalsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates wheter or not we're editing in batch mode
|
||||
-> Prompt
|
||||
editPlayerYtdGoalsPrompt batchMode = editNum "Year-to-date goals: " mode
|
||||
(pYtd.psGoals .~)
|
||||
where
|
||||
mode = if batchMode then EPYtdAssists True else EPYtd
|
||||
|
||||
-- | Prompt to edit a player's year-to-date assists
|
||||
editPlayerYtdAssistsPrompt :: Prompt
|
||||
editPlayerYtdAssistsPrompt = numPrompt "Year-to-date assists: " $
|
||||
editPlayer . (pYtd.psAssists .~)
|
||||
editPlayerYtdAssistsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates wheter or not we're editing in batch mode
|
||||
-> Prompt
|
||||
editPlayerYtdAssistsPrompt batchMode = editNum "Year-to-date assists: " mode
|
||||
(pYtd.psAssists .~)
|
||||
where
|
||||
mode = if batchMode then EPYtdPMin else EPYtd
|
||||
|
||||
-- | Prompt to edit a player's year-to-date penalty minutes
|
||||
editPlayerYtdPMinPrompt :: Prompt
|
||||
editPlayerYtdPMinPrompt = numPrompt "Year-to-date penalty minutes: " $
|
||||
editPlayer . (pYtd.psPMin .~)
|
||||
editPlayerYtdPMinPrompt = editNum "Year-to-date penalty minutes: " EPYtd
|
||||
(pYtd.psPMin .~)
|
||||
|
||||
-- | Prompt to edit a player's lifetime goals
|
||||
editPlayerLtGoalsPrompt :: Prompt
|
||||
editPlayerLtGoalsPrompt = numPrompt "Lifetime goals: " $
|
||||
editPlayer . (pLifetime.psGoals .~)
|
||||
editPlayerLtGoalsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates wheter or not we're editing in batch mode
|
||||
-> Prompt
|
||||
editPlayerLtGoalsPrompt batchMode = editNum "Lifetime goals: " mode
|
||||
(pLifetime.psGoals .~)
|
||||
where
|
||||
mode = if batchMode then EPLtAssists True else EPLifetime
|
||||
|
||||
-- | Prompt to edit a player's lifetime assists
|
||||
editPlayerLtAssistsPrompt :: Prompt
|
||||
editPlayerLtAssistsPrompt = numPrompt "Lifetime assists: " $
|
||||
editPlayer . (pLifetime.psAssists .~)
|
||||
editPlayerLtAssistsPrompt
|
||||
:: Bool
|
||||
-- ^ Indicates wheter or not we're editing in batch mode
|
||||
-> Prompt
|
||||
editPlayerLtAssistsPrompt batchMode = editNum "Lifetime assists: " mode
|
||||
(pLifetime.psAssists .~)
|
||||
where
|
||||
mode = if batchMode then EPLtPMin else EPLifetime
|
||||
|
||||
-- | Prompt to edit a player's lifetime penalty minutes
|
||||
editPlayerLtPMinPrompt :: Prompt
|
||||
editPlayerLtPMinPrompt = numPrompt "Lifetime penalty minutes: " $
|
||||
editPlayer . (pLifetime.psPMin .~)
|
||||
editPlayerLtPMinPrompt = editNum "Lifetime penalty minutes: " EPLifetime
|
||||
(pLifetime.psPMin .~)
|
||||
|
||||
editPlayer :: (Player -> Player) -> Action ()
|
||||
editPlayer f =
|
||||
whenJustM (gets (^.progMode.editPlayerStateL.epsSelectedPlayer)) $ \pid ->
|
||||
modify
|
||||
$ (database.dbPlayers %~ modifyNth pid f)
|
||||
. (progMode.editPlayerStateL.epsMode .~ EPMenu)
|
||||
editNum
|
||||
:: String
|
||||
-> EditPlayerMode
|
||||
-> (Int -> Player -> Player)
|
||||
-> Prompt
|
||||
editNum pStr mode f = numPromptWithFallback pStr
|
||||
(goto mode)
|
||||
(doEdit mode . f)
|
||||
|
||||
doEdit :: EditPlayerMode -> (Player -> Player) -> Action ()
|
||||
doEdit mode f = do
|
||||
modify $ editSelectedPlayer f
|
||||
goto mode
|
||||
|
||||
goto :: EditPlayerMode -> Action ()
|
||||
goto = modify . (progMode.editPlayerStateL.epsMode .~)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -21,12 +21,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
module Mtlstats.Report (report, gameDate) where
|
||||
|
||||
import Data.List (sortOn)
|
||||
import qualified Data.Map as M
|
||||
import Data.Maybe (fromMaybe, mapMaybe)
|
||||
import Data.Ord (Down (Down))
|
||||
import Lens.Micro ((^.))
|
||||
|
||||
import Mtlstats.Config
|
||||
import Mtlstats.Format
|
||||
import Mtlstats.Helpers.Goalie
|
||||
import Mtlstats.Helpers.Player
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Util
|
||||
|
||||
@@ -127,7 +131,7 @@ gameStatsReport width s = let
|
||||
|
||||
criteria (_, ps) = psPoints ps > 0
|
||||
|
||||
in filteredPlayerReport width "GAME" criteria playerStats
|
||||
in filteredPlayerReport width "GAME" criteria True False playerStats
|
||||
++ [""]
|
||||
++ gameGoalieReport width goalieStats
|
||||
|
||||
@@ -135,7 +139,8 @@ yearToDateStatsReport :: Int -> ProgState -> [String]
|
||||
yearToDateStatsReport width s = let
|
||||
db = s^.database
|
||||
|
||||
playerStats = map (\p -> (p, p^.pYtd))
|
||||
playerStats = sortOn (Down . psPoints . snd)
|
||||
$ map (\p -> (p, p^.pYtd))
|
||||
$ filter playerIsActive
|
||||
$ db^.dbPlayers
|
||||
|
||||
@@ -143,23 +148,24 @@ yearToDateStatsReport width s = let
|
||||
$ filter goalieIsActive
|
||||
$ db^.dbGoalies
|
||||
|
||||
in playerReport width "YEAR TO DATE" playerStats
|
||||
in playerReport width "YEAR TO DATE" True False playerStats
|
||||
++ [""]
|
||||
++ goalieReport width goalieStats
|
||||
++ goalieReport width True False goalieStats
|
||||
|
||||
lifetimeStatsReport :: Int -> ProgState -> [String]
|
||||
lifetimeStatsReport width s = let
|
||||
db = s^.database
|
||||
|
||||
playerStats = map (\p -> (p, p^.pYtd))
|
||||
playerStats = sortOn (Down . psPoints . snd)
|
||||
$ map (\p -> (p, p^.pLifetime))
|
||||
$ db^.dbPlayers
|
||||
|
||||
goalieStats = map (\g -> (g, g^.gYtd))
|
||||
goalieStats = map (\g -> (g, g^.gLifetime))
|
||||
$ db^.dbGoalies
|
||||
|
||||
in playerReport width "LIFETIME" playerStats
|
||||
in playerReport width "LIFETIME" False True playerStats
|
||||
++ [""]
|
||||
++ goalieReport width goalieStats
|
||||
++ goalieReport width False True goalieStats
|
||||
|
||||
gameDate :: GameState -> String
|
||||
gameDate gs = fromMaybe "" $ do
|
||||
@@ -168,19 +174,28 @@ gameDate gs = fromMaybe "" $ do
|
||||
d <- padNum 2 <$> gs^.gameDay
|
||||
Just $ m ++ " " ++ d ++ " " ++ y
|
||||
|
||||
playerReport :: Int -> String -> [(Player, PlayerStats)] -> [String]
|
||||
playerReport width label ps =
|
||||
filteredPlayerReport width label (const True) ps
|
||||
playerReport
|
||||
:: Int
|
||||
-> String
|
||||
-> Bool
|
||||
-> Bool
|
||||
-> [(Player, PlayerStats)]
|
||||
-> [String]
|
||||
playerReport width label =
|
||||
filteredPlayerReport width label (const True)
|
||||
|
||||
filteredPlayerReport
|
||||
:: Int
|
||||
-> String
|
||||
-> ((Player, PlayerStats) -> Bool)
|
||||
-> Bool
|
||||
-> Bool
|
||||
-> [(Player, PlayerStats)]
|
||||
-> [String]
|
||||
filteredPlayerReport width label criteria ps = let
|
||||
tStats = foldl addPlayerStats newPlayerStats $ map snd ps
|
||||
fps = filter criteria ps
|
||||
filteredPlayerReport width label criteria showTotals lineNumbers ps = let
|
||||
tStats = foldl addPlayerStats newPlayerStats $ map snd ps
|
||||
criteria' = (&&) <$> criteria <*> \(p, _) -> p^.pNumber /= 0
|
||||
fps = filter criteria' ps
|
||||
|
||||
rHeader =
|
||||
[ centre width (label ++ " STATISTICS")
|
||||
@@ -206,7 +221,7 @@ filteredPlayerReport width label criteria ps = let
|
||||
body = map
|
||||
(\(p, stats) ->
|
||||
[ CellText $ show (p^.pNumber) ++ " "
|
||||
, CellText $ p^.pName
|
||||
, CellText $ playerName p
|
||||
] ++ statsCells stats)
|
||||
fps
|
||||
|
||||
@@ -217,23 +232,41 @@ filteredPlayerReport width label criteria ps = let
|
||||
, CellText ""
|
||||
] ++ statsCells tStats
|
||||
|
||||
table = overlayLast (label ++ " TOTALS")
|
||||
$ map (centre width)
|
||||
olayText = if showTotals
|
||||
then label ++ " TOTALS"
|
||||
else ""
|
||||
|
||||
lnOverlay = if lineNumbers
|
||||
then "" : [right 2 $ show x | x <- [(1 :: Int)..]]
|
||||
else repeat ""
|
||||
|
||||
table = overlayLast olayText
|
||||
$ map (\(ln, line) -> overlay ln $ centre width line)
|
||||
$ zip lnOverlay
|
||||
$ complexTable ([right, left] ++ repeat right)
|
||||
$ tHeader : body ++ [separator, totals]
|
||||
$ tHeader : body ++ if showTotals
|
||||
then [separator, totals]
|
||||
else []
|
||||
|
||||
in rHeader ++ table
|
||||
|
||||
goalieReport :: Int -> [(Goalie, GoalieStats)] -> [String]
|
||||
goalieReport width goalieData = let
|
||||
olayText = "GOALTENDING TOTALS"
|
||||
goalieReport
|
||||
:: Int
|
||||
-> Bool
|
||||
-> Bool
|
||||
-> [(Goalie, GoalieStats)]
|
||||
-> [String]
|
||||
goalieReport width showTotals lineNumbers goalieData = let
|
||||
olayText = if showTotals
|
||||
then "GOALTENDING TOTALS"
|
||||
else ""
|
||||
|
||||
tData = foldl addGoalieStats newGoalieStats
|
||||
$ map snd goalieData
|
||||
|
||||
header =
|
||||
[ CellText "NO."
|
||||
, CellText $ left (length olayText) "GOALTENDER"
|
||||
, CellText $ padRight (length olayText) "GOALTENDER"
|
||||
, CellText "GP"
|
||||
, CellText " MIN"
|
||||
, CellText " GA"
|
||||
@@ -252,7 +285,7 @@ goalieReport width goalieData = let
|
||||
body = map
|
||||
(\(goalie, stats) ->
|
||||
[ CellText $ show (goalie^.gNumber) ++ " "
|
||||
, CellText $ goalie^.gName
|
||||
, CellText $ goalieName goalie
|
||||
] ++ rowCells stats)
|
||||
goalieData
|
||||
|
||||
@@ -262,10 +295,17 @@ goalieReport width goalieData = let
|
||||
|
||||
summary = replicate 2 (CellText "") ++ rowCells tData
|
||||
|
||||
in map (centre width)
|
||||
lnOverlay = if lineNumbers
|
||||
then "" : [right 2 $ show x | x <- [(1 :: Int)..]]
|
||||
else repeat ""
|
||||
|
||||
in map (\(ln, line) -> overlay ln $ centre width line)
|
||||
$ zip lnOverlay
|
||||
$ overlayLast olayText
|
||||
$ complexTable ([right, left] ++ repeat right)
|
||||
$ header : body ++ [separator, summary]
|
||||
$ header : body ++ if showTotals
|
||||
then [separator, summary]
|
||||
else []
|
||||
|
||||
gameGoalieReport :: Int -> [(Goalie, GoalieStats)] -> [String]
|
||||
gameGoalieReport width goalieData = let
|
||||
@@ -280,7 +320,7 @@ gameGoalieReport width goalieData = let
|
||||
body = map
|
||||
(\(goalie, stats) ->
|
||||
[ CellText $ show (goalie^.gNumber) ++ " "
|
||||
, CellText $ goalie^.gName
|
||||
, CellText $ goalieName goalie
|
||||
, CellText $ show $ stats^.gsMinsPlayed
|
||||
, CellText $ show $ stats^.gsGoalsAllowed
|
||||
, CellText $ showFloating $ gsAverage stats
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -106,6 +106,7 @@ module Mtlstats.Types (
|
||||
pNumber,
|
||||
pName,
|
||||
pPosition,
|
||||
pRookie,
|
||||
pYtd,
|
||||
pLifetime,
|
||||
-- ** PlayerStats Lenses
|
||||
@@ -115,6 +116,7 @@ module Mtlstats.Types (
|
||||
-- ** Goalie Lenses
|
||||
gNumber,
|
||||
gName,
|
||||
gRookie,
|
||||
gYtd,
|
||||
gLifetime,
|
||||
-- ** GoalieStats Lenses
|
||||
@@ -230,6 +232,7 @@ data ProgMode
|
||||
= MainMenu
|
||||
| NewSeason
|
||||
| NewGame GameState
|
||||
| EditMenu
|
||||
| CreatePlayer CreatePlayerState
|
||||
| CreateGoalie CreateGoalieState
|
||||
| EditPlayer EditPlayerState
|
||||
@@ -239,6 +242,7 @@ instance Show ProgMode where
|
||||
show MainMenu = "MainMenu"
|
||||
show NewSeason = "NewSeason"
|
||||
show (NewGame _) = "NewGame"
|
||||
show EditMenu = "EditMenu"
|
||||
show (CreatePlayer _) = "CreatePlayer"
|
||||
show (CreateGoalie _) = "CreateGoalie"
|
||||
show (EditPlayer _) = "EditPlayer"
|
||||
@@ -345,11 +349,11 @@ data EditPlayerMode
|
||||
| EPPosition
|
||||
| EPYtd
|
||||
| EPLifetime
|
||||
| EPYtdGoals
|
||||
| EPYtdAssists
|
||||
| EPYtdGoals Bool
|
||||
| EPYtdAssists Bool
|
||||
| EPYtdPMin
|
||||
| EPLtGoals
|
||||
| EPLtAssists
|
||||
| EPLtGoals Bool
|
||||
| EPLtAssists Bool
|
||||
| EPLtPMin
|
||||
deriving (Eq, Show)
|
||||
|
||||
@@ -367,17 +371,19 @@ data EditGoalieMode
|
||||
| EGName
|
||||
| EGYtd
|
||||
| EGLifetime
|
||||
| EGYtdGames
|
||||
| EGYtdMins
|
||||
| EGYtdGoals
|
||||
| EGYtdWins
|
||||
| EGYtdLosses
|
||||
| EGYtdGames Bool
|
||||
| EGYtdMins Bool
|
||||
| EGYtdGoals Bool
|
||||
| EGYtdShutouts Bool
|
||||
| EGYtdWins Bool
|
||||
| EGYtdLosses Bool
|
||||
| EGYtdTies
|
||||
| EGLtGames
|
||||
| EGLtMins
|
||||
| EGLtGoals
|
||||
| EGLtWins
|
||||
| EGLtLosses
|
||||
| EGLtGames Bool
|
||||
| EGLtMins Bool
|
||||
| EGLtGoals Bool
|
||||
| EGLtShutouts Bool
|
||||
| EGLtWins Bool
|
||||
| EGLtLosses Bool
|
||||
| EGLtTies
|
||||
deriving (Eq, Show)
|
||||
|
||||
@@ -395,29 +401,6 @@ data Database = Database
|
||||
-- ^ Statistics for away games
|
||||
} deriving (Eq, Show)
|
||||
|
||||
instance FromJSON Database where
|
||||
parseJSON = withObject "Database" $ \v -> Database
|
||||
<$> v .: "players"
|
||||
<*> v .: "goalies"
|
||||
<*> v .: "games"
|
||||
<*> v .: "home_game_stats"
|
||||
<*> v .: "away_game_stats"
|
||||
|
||||
instance ToJSON Database where
|
||||
toJSON (Database players goalies games hgs ags) = object
|
||||
[ "players" .= players
|
||||
, "goalies" .= goalies
|
||||
, "games" .= games
|
||||
, "home_game_stats" .= hgs
|
||||
, "away_game_stats" .= ags
|
||||
]
|
||||
toEncoding (Database players goalies games hgs ags) = pairs $
|
||||
"players" .= players <>
|
||||
"goalies" .= goalies <>
|
||||
"games" .= games <>
|
||||
"home_game_stats" .= hgs <>
|
||||
"away_game_stats" .= ags
|
||||
|
||||
-- | Represents a (non-goalie) player
|
||||
data Player = Player
|
||||
{ _pNumber :: Int
|
||||
@@ -426,35 +409,14 @@ data Player = Player
|
||||
-- ^ The player's name
|
||||
, _pPosition :: String
|
||||
-- ^ The player's position
|
||||
, _pRookie :: Bool
|
||||
-- ^ Indicates that the player is a rookie
|
||||
, _pYtd :: PlayerStats
|
||||
-- ^ The Player's year-to-date stats
|
||||
, _pLifetime :: PlayerStats
|
||||
-- ^ The player's lifetime stats
|
||||
} deriving (Eq, Show)
|
||||
|
||||
instance FromJSON Player where
|
||||
parseJSON = withObject "Player" $ \v -> Player
|
||||
<$> v .: "number"
|
||||
<*> v .: "name"
|
||||
<*> v .: "position"
|
||||
<*> v .: "ytd"
|
||||
<*> v .: "lifetime"
|
||||
|
||||
instance ToJSON Player where
|
||||
toJSON (Player num name pos ytd lt) = object
|
||||
[ "number" .= num
|
||||
, "name" .= name
|
||||
, "position" .= pos
|
||||
, "ytd" .= ytd
|
||||
, "lifetime" .= lt
|
||||
]
|
||||
toEncoding (Player num name pos ytd lt) = pairs $
|
||||
"number" .= num <>
|
||||
"name" .= name <>
|
||||
"position" .= pos <>
|
||||
"ytd" .= ytd <>
|
||||
"lifetime" .= lt
|
||||
|
||||
-- | Represents a (non-goalie) player's stats
|
||||
data PlayerStats = PlayerStats
|
||||
{ _psGoals :: Int
|
||||
@@ -465,55 +427,20 @@ data PlayerStats = PlayerStats
|
||||
-- ^ The number of penalty minutes
|
||||
} deriving (Eq, Show)
|
||||
|
||||
instance FromJSON PlayerStats where
|
||||
parseJSON = withObject "PlayerStats" $ \v -> PlayerStats
|
||||
<$> v .: "goals"
|
||||
<*> v .: "assists"
|
||||
<*> v .: "penalty_mins"
|
||||
|
||||
instance ToJSON PlayerStats where
|
||||
toJSON (PlayerStats g a pm) = object
|
||||
[ "goals" .= g
|
||||
, "assists" .= a
|
||||
, "penalty_mins" .= pm
|
||||
]
|
||||
toEncoding (PlayerStats g a pm) = pairs $
|
||||
"goals" .= g <>
|
||||
"assists" .= a <>
|
||||
"penalty_mins" .= pm
|
||||
|
||||
-- | Represents a goalie
|
||||
data Goalie = Goalie
|
||||
{ _gNumber :: Int
|
||||
-- ^ The goalie's number
|
||||
, _gName :: String
|
||||
-- ^ The goalie's name
|
||||
, _gRookie :: Bool
|
||||
-- ^ Indicates that the goalie is a rookie
|
||||
, _gYtd :: GoalieStats
|
||||
-- ^ The goalie's year-to-date stats
|
||||
, _gLifetime :: GoalieStats
|
||||
-- ^ The goalie's lifetime stats
|
||||
} deriving (Eq, Show)
|
||||
|
||||
instance FromJSON Goalie where
|
||||
parseJSON = withObject "Goalie" $ \v -> Goalie
|
||||
<$> v .: "number"
|
||||
<*> v .: "name"
|
||||
<*> v .: "ytd"
|
||||
<*> v .: "lifetime"
|
||||
|
||||
instance ToJSON Goalie where
|
||||
toJSON (Goalie num name ytd lt) = object
|
||||
[ "number" .= num
|
||||
, "name" .= name
|
||||
, "ytd" .= ytd
|
||||
, "lifetime" .= lt
|
||||
]
|
||||
toEncoding (Goalie num name ytd lt) = pairs $
|
||||
"number" .= num <>
|
||||
"name" .= name <>
|
||||
"ytd" .= ytd <>
|
||||
"lifetime" .= lt
|
||||
|
||||
-- | Represents a goalie's stats
|
||||
data GoalieStats = GoalieStats
|
||||
{ _gsGames :: Int
|
||||
@@ -532,6 +459,162 @@ data GoalieStats = GoalieStats
|
||||
-- ^ The number of ties
|
||||
} deriving (Eq, Show)
|
||||
|
||||
-- | Game statistics
|
||||
data GameStats = GameStats
|
||||
{ _gmsWins :: Int
|
||||
-- ^ Games won
|
||||
, _gmsLosses :: Int
|
||||
-- ^ Games lost
|
||||
, _gmsOvertime :: Int
|
||||
-- ^ Games lost in overtime
|
||||
, _gmsGoalsFor :: Int
|
||||
-- ^ Goals for the team
|
||||
, _gmsGoalsAgainst :: Int
|
||||
-- ^ Goals against the team
|
||||
} deriving (Eq, Show)
|
||||
|
||||
-- | Defines a user prompt
|
||||
data Prompt = Prompt
|
||||
{ promptDrawer :: ProgState -> C.Update ()
|
||||
-- ^ Draws the prompt to the screen
|
||||
, promptProcessChar :: Char -> String -> String
|
||||
-- ^ Modifies the string based on the character entered
|
||||
, promptAction :: String -> Action ()
|
||||
-- ^ Action to perform when the value is entered
|
||||
, promptSpecialKey :: C.Key -> Action ()
|
||||
-- ^ Action to perform when a special key is pressed
|
||||
}
|
||||
|
||||
-- | Parameters for a search prompt
|
||||
data SelectParams a = SelectParams
|
||||
{ spPrompt :: String
|
||||
-- ^ The search prompt
|
||||
, spSearchHeader :: String
|
||||
-- ^ The header to display at the top of the search list
|
||||
, spSearch :: String -> Database -> [(Int, a)]
|
||||
-- ^ The search function
|
||||
, spSearchExact :: String -> Database -> Maybe Int
|
||||
-- ^ Search function looking for an exact match
|
||||
, spElemDesc :: a -> String
|
||||
-- ^ Provides a string description of an element
|
||||
, spProcessChar :: Char -> String -> String
|
||||
-- ^ Processes a character entered by the user
|
||||
, spCallback :: Maybe Int -> Action ()
|
||||
-- ^ The function when the selection is made
|
||||
, spNotFound :: String -> Action ()
|
||||
-- ^ The function to call when the selection doesn't exist
|
||||
}
|
||||
|
||||
-- | Describes a table cell
|
||||
data TableCell
|
||||
= CellText String
|
||||
-- ^ A cell with text
|
||||
| CellFill Char
|
||||
-- ^ A cell filled with the given character
|
||||
deriving (Eq, Show)
|
||||
|
||||
makeLenses ''ProgState
|
||||
makeLenses ''GameState
|
||||
makeLenses ''CreatePlayerState
|
||||
makeLenses ''CreateGoalieState
|
||||
makeLenses ''EditPlayerState
|
||||
makeLenses ''EditGoalieState
|
||||
makeLenses ''Database
|
||||
makeLenses ''Player
|
||||
makeLenses ''PlayerStats
|
||||
makeLenses ''Goalie
|
||||
makeLenses ''GoalieStats
|
||||
makeLenses ''GameStats
|
||||
|
||||
instance FromJSON Database where
|
||||
parseJSON = withObject "Database" $ \v -> Database
|
||||
<$> v .:? "players" .!= []
|
||||
<*> v .:? "goalies" .!= []
|
||||
<*> v .:? "games" .!= 0
|
||||
<*> v .:? "home_game_stats" .!= newGameStats
|
||||
<*> v .:? "away_game_stats" .!= newGameStats
|
||||
|
||||
instance ToJSON Database where
|
||||
toJSON (Database players goalies games hgs ags) = object
|
||||
[ "players" .= players
|
||||
, "goalies" .= goalies
|
||||
, "games" .= games
|
||||
, "home_game_stats" .= hgs
|
||||
, "away_game_stats" .= ags
|
||||
]
|
||||
toEncoding (Database players goalies games hgs ags) = pairs $
|
||||
"players" .= players <>
|
||||
"goalies" .= goalies <>
|
||||
"games" .= games <>
|
||||
"home_game_stats" .= hgs <>
|
||||
"away_game_stats" .= ags
|
||||
|
||||
instance FromJSON Player where
|
||||
parseJSON = withObject "Player" $ \v -> Player
|
||||
<$> v .: "number"
|
||||
<*> v .: "name"
|
||||
<*> v .: "position"
|
||||
<*> v .:? "rookie" .!= False
|
||||
<*> v .:? "ytd" .!= newPlayerStats
|
||||
<*> v .:? "lifetime" .!= newPlayerStats
|
||||
|
||||
instance ToJSON Player where
|
||||
toJSON (Player num name pos rk ytd lt) = object
|
||||
[ "number" .= num
|
||||
, "name" .= name
|
||||
, "position" .= pos
|
||||
, "rookie" .= rk
|
||||
, "ytd" .= ytd
|
||||
, "lifetime" .= lt
|
||||
]
|
||||
toEncoding (Player num name pos rk ytd lt) = pairs $
|
||||
"number" .= num <>
|
||||
"name" .= name <>
|
||||
"position" .= pos <>
|
||||
"rookie" .= rk <>
|
||||
"ytd" .= ytd <>
|
||||
"lifetime" .= lt
|
||||
|
||||
instance FromJSON PlayerStats where
|
||||
parseJSON = withObject "PlayerStats" $ \v -> PlayerStats
|
||||
<$> v .:? "goals" .!= 0
|
||||
<*> v .:? "assists" .!= 0
|
||||
<*> v .:? "penalty_mins" .!= 0
|
||||
|
||||
instance ToJSON PlayerStats where
|
||||
toJSON (PlayerStats g a pm) = object
|
||||
[ "goals" .= g
|
||||
, "assists" .= a
|
||||
, "penalty_mins" .= pm
|
||||
]
|
||||
toEncoding (PlayerStats g a pm) = pairs $
|
||||
"goals" .= g <>
|
||||
"assists" .= a <>
|
||||
"penalty_mins" .= pm
|
||||
|
||||
instance FromJSON Goalie where
|
||||
parseJSON = withObject "Goalie" $ \v -> Goalie
|
||||
<$> v .: "number"
|
||||
<*> v .: "name"
|
||||
<*> v .:? "rookie" .!= False
|
||||
<*> v .:? "ytd" .!= newGoalieStats
|
||||
<*> v .:? "lifetime" .!= newGoalieStats
|
||||
|
||||
instance ToJSON Goalie where
|
||||
toJSON (Goalie num name rk ytd lt) = object
|
||||
[ "number" .= num
|
||||
, "name" .= name
|
||||
, "ytd" .= ytd
|
||||
, "rookie" .= rk
|
||||
, "lifetime" .= lt
|
||||
]
|
||||
toEncoding (Goalie num name rk ytd lt) = pairs $
|
||||
"number" .= num <>
|
||||
"name" .= name <>
|
||||
"rookie" .= rk <>
|
||||
"ytd" .= ytd <>
|
||||
"lifetime" .= lt
|
||||
|
||||
instance FromJSON GoalieStats where
|
||||
parseJSON = withObject "GoalieStats" $ \v -> GoalieStats
|
||||
<$> v .:? "games" .!= 0
|
||||
@@ -561,20 +644,6 @@ instance ToJSON GoalieStats where
|
||||
"losses" .= l <>
|
||||
"ties" .= t
|
||||
|
||||
-- | Game statistics
|
||||
data GameStats = GameStats
|
||||
{ _gmsWins :: Int
|
||||
-- ^ Games won
|
||||
, _gmsLosses :: Int
|
||||
-- ^ Games lost
|
||||
, _gmsOvertime :: Int
|
||||
-- ^ Games lost in overtime
|
||||
, _gmsGoalsFor :: Int
|
||||
-- ^ Goals for the team
|
||||
, _gmsGoalsAgainst :: Int
|
||||
-- ^ Goals against the team
|
||||
} deriving (Eq, Show)
|
||||
|
||||
instance FromJSON GameStats where
|
||||
parseJSON = withObject "GameStats" $ \v -> GameStats
|
||||
<$> v .: "wins"
|
||||
@@ -598,57 +667,6 @@ instance ToJSON GameStats where
|
||||
"goals_for" .= gf <>
|
||||
"goals_against" .= ga
|
||||
|
||||
-- | Defines a user prompt
|
||||
data Prompt = Prompt
|
||||
{ promptDrawer :: ProgState -> C.Update ()
|
||||
-- ^ Draws the prompt to the screen
|
||||
, promptProcessChar :: Char -> String -> String
|
||||
-- ^ Modifies the string based on the character entered
|
||||
, promptAction :: String -> Action ()
|
||||
-- ^ Action to perform when the value is entered
|
||||
, promptSpecialKey :: C.Key -> Action ()
|
||||
-- ^ Action to perform when a special key is pressed
|
||||
}
|
||||
|
||||
-- | Parameters for a search prompt
|
||||
data SelectParams a = SelectParams
|
||||
{ spPrompt :: String
|
||||
-- ^ The search prompt
|
||||
, spSearchHeader :: String
|
||||
-- ^ The header to display at the top of the search list
|
||||
, spSearch :: String -> Database -> [(Int, a)]
|
||||
-- ^ The search function
|
||||
, spSearchExact :: String -> Database -> Maybe Int
|
||||
-- ^ Search function looking for an exact match
|
||||
, spElemDesc :: a -> String
|
||||
-- ^ Provides a string description of an element
|
||||
, spCallback :: Maybe Int -> Action ()
|
||||
-- ^ The function when the selection is made
|
||||
, spNotFound :: String -> Action ()
|
||||
-- ^ The function to call when the selection doesn't exist
|
||||
}
|
||||
|
||||
-- | Describes a table cell
|
||||
data TableCell
|
||||
= CellText String
|
||||
-- ^ A cell with text
|
||||
| CellFill Char
|
||||
-- ^ A cell filled with the given character
|
||||
deriving (Eq, Show)
|
||||
|
||||
makeLenses ''ProgState
|
||||
makeLenses ''GameState
|
||||
makeLenses ''CreatePlayerState
|
||||
makeLenses ''CreateGoalieState
|
||||
makeLenses ''EditPlayerState
|
||||
makeLenses ''EditGoalieState
|
||||
makeLenses ''Database
|
||||
makeLenses ''Player
|
||||
makeLenses ''PlayerStats
|
||||
makeLenses ''Goalie
|
||||
makeLenses ''GoalieStats
|
||||
makeLenses ''GameStats
|
||||
|
||||
gameStateL :: Lens' ProgMode GameState
|
||||
gameStateL = lens
|
||||
(\case
|
||||
@@ -776,6 +794,7 @@ newPlayer num name pos = Player
|
||||
{ _pNumber = num
|
||||
, _pName = name
|
||||
, _pPosition = pos
|
||||
, _pRookie = True
|
||||
, _pYtd = newPlayerStats
|
||||
, _pLifetime = newPlayerStats
|
||||
}
|
||||
@@ -798,6 +817,7 @@ newGoalie
|
||||
newGoalie num name = Goalie
|
||||
{ _gNumber = num
|
||||
, _gName = name
|
||||
, _gRookie = True
|
||||
, _gYtd = newGoalieStats
|
||||
, _gLifetime = newGoalieStats
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{- |
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,8 +19,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-}
|
||||
|
||||
module Mtlstats.Util (nth, modifyNth, updateMap, slice) where
|
||||
module Mtlstats.Util
|
||||
( nth
|
||||
, modifyNth
|
||||
, updateMap
|
||||
, slice
|
||||
, capitalizeName
|
||||
) where
|
||||
|
||||
import Data.Char (isSpace, toUpper)
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- | Attempt to select the element from a list at a given index
|
||||
@@ -75,3 +82,25 @@ slice
|
||||
-- ^ The list to take a subset of
|
||||
-> [a]
|
||||
slice offset len = take len . drop offset
|
||||
|
||||
-- | Name capitalization function for a player
|
||||
capitalizeName
|
||||
:: Char
|
||||
-- ^ The character being input
|
||||
-> String
|
||||
-- ^ The current string
|
||||
-> String
|
||||
-- ^ The resulting string
|
||||
capitalizeName ch str = str ++ [ch']
|
||||
where
|
||||
ch' = if lockFlag str
|
||||
then toUpper ch
|
||||
else ch
|
||||
lockFlag "" = True
|
||||
lockFlag (c:cs)
|
||||
| c == ',' = lockFlag' cs
|
||||
| otherwise = lockFlag cs
|
||||
lockFlag' "" = True
|
||||
lockFlag' (c:cs)
|
||||
| isSpace c = lockFlag' cs
|
||||
| otherwise = False
|
||||
|
||||
@@ -1,537 +0,0 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-}
|
||||
|
||||
module Actions.EditGoalieSpec (spec) where
|
||||
|
||||
import Data.Maybe (fromJust)
|
||||
import Lens.Micro ((^.), (&), (.~))
|
||||
import Test.Hspec (Spec, context, describe, it, shouldBe)
|
||||
|
||||
import Mtlstats.Actions.EditGoalie
|
||||
import Mtlstats.Types
|
||||
import Mtlstats.Util
|
||||
|
||||
spec :: Spec
|
||||
spec = describe "EditGoalie" $ do
|
||||
editGoalieNumberSpec
|
||||
editGoalieNameSpec
|
||||
editGoalieYtdGamesSpec
|
||||
editGoalieYtdMinsSpec
|
||||
editGoalieYtdGoalsSpec
|
||||
editGoalieYtdWinsSpec
|
||||
editGoalieYtdLossesSpec
|
||||
editGoalieYtdTiesSpec
|
||||
editGoalieLtGamesSpec
|
||||
editGoalieLtMinsSpec
|
||||
editGoalieLtGoalsSpec
|
||||
editGoalieLtWinsSpec
|
||||
editGoalieLtLossesSpec
|
||||
editGoalieLtTiesSpec
|
||||
|
||||
editGoalieNumberSpec :: Spec
|
||||
editGoalieNumberSpec = describe "editGoalieNumber" $ editTest
|
||||
(editGoalieNumber 5)
|
||||
EGNumber
|
||||
(uncurry newGoalie)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, (5, "Joe")
|
||||
, (3, "Bob")
|
||||
, EGMenu
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, (2, "Joe")
|
||||
, (5, "Bob")
|
||||
, EGMenu
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, (2, "Joe")
|
||||
, (3, "Bob")
|
||||
, EGNumber
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, (2, "Joe")
|
||||
, (3, "Bob")
|
||||
, EGNumber
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieNameSpec :: Spec
|
||||
editGoalieNameSpec = describe "editGoalieName" $ editTest
|
||||
(editGoalieName "foo")
|
||||
EGName
|
||||
(uncurry newGoalie)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "foo" )
|
||||
, ( 3, "Bob" )
|
||||
, EGMenu
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe" )
|
||||
, ( 3, "foo" )
|
||||
, EGMenu
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe" )
|
||||
, ( 3, "Bob" )
|
||||
, EGName
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe" )
|
||||
, ( 3, "Bob" )
|
||||
, EGName
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieYtdGamesSpec :: Spec
|
||||
editGoalieYtdGamesSpec = describe "editGoalieYtdGames" $ editTest
|
||||
(editGoalieYtdGames 1)
|
||||
EGYtdGames
|
||||
(\(num, name, games) -> newGoalie num name & gYtd.gsGames .~ games)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdGames
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdGames
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieYtdMinsSpec :: Spec
|
||||
editGoalieYtdMinsSpec = describe "editGoalieYtdMins" $ editTest
|
||||
(editGoalieYtdMins 1)
|
||||
EGYtdMins
|
||||
(\(num, name, mins) -> newGoalie num name & gYtd.gsMinsPlayed .~ mins)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, (2, "Joe", 0 )
|
||||
, (3, "Bob", 1 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdMins
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdMins
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieYtdGoalsSpec :: Spec
|
||||
editGoalieYtdGoalsSpec = describe "editGoalieYtdGoals" $ editTest
|
||||
(editGoalieYtdGoals 1)
|
||||
EGYtdGoals
|
||||
(\(num, name, goals) -> newGoalie num name & gYtd.gsGoalsAllowed .~ goals)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdGoals
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdGoals
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieYtdWinsSpec :: Spec
|
||||
editGoalieYtdWinsSpec = describe "editGoalieYtdWins" $ editTest
|
||||
(editGoalieYtdWins 1)
|
||||
EGYtdWins
|
||||
(\(num, name, wins) -> newGoalie num name & gYtd.gsWins .~ wins)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdWins
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdWins
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieYtdLossesSpec :: Spec
|
||||
editGoalieYtdLossesSpec = describe "editGoalieYtdLosses" $ editTest
|
||||
(editGoalieYtdLosses 1)
|
||||
EGYtdLosses
|
||||
(\(num, name, losses) -> newGoalie num name & gYtd.gsLosses .~ losses)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdLosses
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdLosses
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieYtdTiesSpec :: Spec
|
||||
editGoalieYtdTiesSpec = describe "editGoalieYtdTies" $ editTest
|
||||
(editGoalieYtdTies 1)
|
||||
EGYtdTies
|
||||
(\(num, name, ties) -> newGoalie num name & gYtd.gsTies .~ ties)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGYtd
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdTies
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGYtdTies
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieLtGamesSpec :: Spec
|
||||
editGoalieLtGamesSpec = describe "editGoalieLtGames" $ editTest
|
||||
(editGoalieLtGames 1)
|
||||
EGLtGames
|
||||
(\(num, name, games) -> newGoalie num name & gLifetime.gsGames .~ games)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtGames
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtGames
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieLtMinsSpec :: Spec
|
||||
editGoalieLtMinsSpec = describe "editGoalieLtMins" $ editTest
|
||||
(editGoalieLtMins 1)
|
||||
EGLtMins
|
||||
(\(num, name, mins) -> newGoalie num name & gLifetime.gsMinsPlayed .~ mins)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtMins
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtMins
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieLtGoalsSpec :: Spec
|
||||
editGoalieLtGoalsSpec = describe "editGoalieLtGoals" $ editTest
|
||||
(editGoalieLtGoals 1)
|
||||
EGLtGoals
|
||||
(\(num, name, goals) -> newGoalie num name & gLifetime.gsGoalsAllowed .~ goals)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtGoals
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtGoals
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieLtWinsSpec :: Spec
|
||||
editGoalieLtWinsSpec = describe "editGoalieLtWins" $ editTest
|
||||
(editGoalieLtWins 1)
|
||||
EGLtWins
|
||||
(\(num, name, wins) -> newGoalie num name & gLifetime.gsWins .~ wins)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtWins
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtWins
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieLtLossesSpec :: Spec
|
||||
editGoalieLtLossesSpec = describe "editGoalieLtLosses" $ editTest
|
||||
(editGoalieLtLosses 1)
|
||||
EGLtLosses
|
||||
(\(num, name, losses) -> newGoalie num name & gLifetime.gsLosses .~ losses)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtLosses
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtLosses
|
||||
)
|
||||
]
|
||||
|
||||
editGoalieLtTiesSpec :: Spec
|
||||
editGoalieLtTiesSpec = describe "editGoalieLtTies" $ editTest
|
||||
(editGoalieLtTies 1)
|
||||
EGLtTies
|
||||
(\(num, name, ties) -> newGoalie num name & gLifetime.gsTies .~ ties)
|
||||
[ ( "set Joe"
|
||||
, Just 0
|
||||
, ( 2, "Joe", 1 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "set Bob"
|
||||
, Just 1
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 1 )
|
||||
, EGLifetime
|
||||
)
|
||||
, ( "out of bounds"
|
||||
, Just 2
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtTies
|
||||
)
|
||||
, ( "no goalie selected"
|
||||
, Nothing
|
||||
, ( 2, "Joe", 0 )
|
||||
, ( 3, "Bob", 0 )
|
||||
, EGLtTies
|
||||
)
|
||||
]
|
||||
|
||||
editTest
|
||||
:: (ProgState -> ProgState)
|
||||
-> EditGoalieMode
|
||||
-> (a -> Goalie)
|
||||
-> [(String, Maybe Int, a, a, EditGoalieMode)]
|
||||
-> Spec
|
||||
editTest func setMode mkGoalie params = do
|
||||
mapM_
|
||||
(\(setLabel, setGid, joeData, bobData, expectMode) -> context setLabel $ do
|
||||
let
|
||||
egs = newEditGoalieState
|
||||
& egsSelectedGoalie .~ setGid
|
||||
& egsMode .~ setMode
|
||||
|
||||
ps = func $ progState $ EditGoalie egs
|
||||
|
||||
mapM_
|
||||
(\(chkLabel, chkGid, goalieData) -> context chkLabel $ let
|
||||
actual = fromJust $ nth chkGid $ ps^.database.dbGoalies
|
||||
expected = mkGoalie goalieData
|
||||
in it ("should be " ++ show expected) $
|
||||
actual `shouldBe` expected)
|
||||
-- label, goalie ID, goalie data
|
||||
[ ( "check Joe", 0, joeData )
|
||||
, ( "check Bob", 1, bobData )
|
||||
]
|
||||
|
||||
context "check mode" $
|
||||
it ("should be " ++ show expectMode) $
|
||||
ps^.progMode.editGoalieStateL.egsMode `shouldBe` expectMode)
|
||||
|
||||
params
|
||||
|
||||
context "wrong progMode" $ do
|
||||
let ps = func $ progState MainMenu
|
||||
|
||||
it "should not change the database" $
|
||||
ps^.database `shouldBe` db
|
||||
|
||||
it "should not change the progMode" $
|
||||
show (ps^.progMode) `shouldBe` "MainMenu"
|
||||
|
||||
joe :: Goalie
|
||||
joe = newGoalie 2 "Joe"
|
||||
|
||||
bob :: Goalie
|
||||
bob = newGoalie 3 "Bob"
|
||||
|
||||
db :: Database
|
||||
db = newDatabase & dbGoalies .~ [joe, bob]
|
||||
|
||||
progState :: ProgMode -> ProgState
|
||||
progState mode = newProgState
|
||||
& progMode .~ mode
|
||||
& database .~ db
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -38,7 +38,6 @@ import Test.Hspec
|
||||
import Mtlstats.Actions
|
||||
import Mtlstats.Types
|
||||
|
||||
import qualified Actions.EditGoalieSpec as EditGoalie
|
||||
import qualified Actions.NewGameSpec as NewGame
|
||||
import qualified TypesSpec as TS
|
||||
|
||||
@@ -52,8 +51,11 @@ spec = describe "Mtlstats.Actions" $ do
|
||||
removeCharSpec
|
||||
createPlayerSpec
|
||||
createGoalieSpec
|
||||
editSpec
|
||||
editPlayerSpec
|
||||
editSelectedPlayerSpec
|
||||
editGoalieSpec
|
||||
editSelectedGoalieSpec
|
||||
addPlayerSpec
|
||||
addGoalieSpec
|
||||
resetCreatePlayerStateSpec
|
||||
@@ -62,7 +64,6 @@ spec = describe "Mtlstats.Actions" $ do
|
||||
scrollUpSpec
|
||||
scrollDownSpec
|
||||
NewGame.spec
|
||||
EditGoalie.spec
|
||||
|
||||
startNewSeasonSpec :: Spec
|
||||
startNewSeasonSpec = describe "startNewSeason" $ do
|
||||
@@ -198,18 +199,76 @@ createGoalieSpec = describe "createGoalie" $
|
||||
s = createGoalie newProgState
|
||||
in show (s^.progMode) `shouldBe` "CreateGoalie"
|
||||
|
||||
editSpec :: Spec
|
||||
editSpec = describe "edit" $
|
||||
it "should change the mode to EditMenu" $ let
|
||||
ps = edit newProgState
|
||||
in show (ps^.progMode) `shouldBe` "EditMenu"
|
||||
|
||||
editPlayerSpec :: Spec
|
||||
editPlayerSpec = describe "editPlayer" $
|
||||
it "should change the mode appropriately" $ let
|
||||
s = editPlayer newProgState
|
||||
in show (s^.progMode) `shouldBe` "EditPlayer"
|
||||
|
||||
editSelectedPlayerSpec :: Spec
|
||||
editSelectedPlayerSpec = describe "editSelectedPlayer" $ mapM_
|
||||
(\(label, pState, expected) -> context label $
|
||||
it "should edit the players appropriately" $ let
|
||||
pState' = editSelectedPlayer (pName .~ "foo") pState
|
||||
players' = pState'^.database.dbPlayers
|
||||
in players' `shouldBe` expected)
|
||||
|
||||
-- label, initial state, expected
|
||||
[ ( "wrong mode", baseState, players )
|
||||
, ( "not selected", changePlayer Nothing, players )
|
||||
, ( "player 0", changePlayer $ Just 0, changed0 )
|
||||
, ( "player 1", changePlayer $ Just 1, changed1 )
|
||||
, ( "out of bounds", changePlayer $ Just 2, players )
|
||||
]
|
||||
|
||||
where
|
||||
baseState = newProgState & database.dbPlayers .~ players
|
||||
changePlayer n = baseState
|
||||
& (progMode.editPlayerStateL.epsSelectedPlayer .~ n)
|
||||
players = [ player 0, player 1 ]
|
||||
changed0 = [ player' 0, player 1 ]
|
||||
changed1 = [ player 0, player' 1 ]
|
||||
player n = newPlayer n ("Player " ++ show n) "pos"
|
||||
player' n = newPlayer n "foo" "pos"
|
||||
|
||||
editGoalieSpec :: Spec
|
||||
editGoalieSpec = describe "editGoalie" $
|
||||
it "should change the mode appropriately" $ let
|
||||
s = editGoalie newProgState
|
||||
in show (s^.progMode) `shouldBe` "EditGoalie"
|
||||
|
||||
editSelectedGoalieSpec :: Spec
|
||||
editSelectedGoalieSpec = describe "editSelectedGoalie" $ mapM_
|
||||
(\(label, pState, expected) -> context label $
|
||||
it "should edit the goalies appropriately" $ let
|
||||
pState' = editSelectedGoalie (gName .~ "foo") pState
|
||||
goalies' = pState'^.database.dbGoalies
|
||||
in goalies' `shouldBe` expected)
|
||||
|
||||
-- label, initial state, expected
|
||||
[ ( "wrong mode", baseState, goalies )
|
||||
, ( "not selected", changeGoalie Nothing, goalies )
|
||||
, ( "goalie 0", changeGoalie $ Just 0, changed0 )
|
||||
, ( "goalie 1", changeGoalie $ Just 1, changed1 )
|
||||
, ( "out of bounds", changeGoalie $ Just 2, goalies )
|
||||
]
|
||||
|
||||
where
|
||||
baseState = newProgState & database.dbGoalies .~ goalies
|
||||
changeGoalie n = baseState
|
||||
& (progMode.editGoalieStateL.egsSelectedGoalie .~ n)
|
||||
goalies = [ goalie 0, goalie 1 ]
|
||||
changed0 = [ goalie' 0, goalie 1 ]
|
||||
changed1 = [ goalie 0, goalie' 1 ]
|
||||
goalie n = newGoalie n ("Player " ++ show n)
|
||||
goalie' n = newGoalie n "foo"
|
||||
|
||||
addPlayerSpec :: Spec
|
||||
addPlayerSpec = describe "addPlayer" $ do
|
||||
let
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -33,6 +33,7 @@ spec = describe "Mtlstats.Format" $ do
|
||||
leftSpec
|
||||
rightSpec
|
||||
centreSpec
|
||||
padRightSpec
|
||||
overlaySpec
|
||||
monthSpec
|
||||
labelTableSpec
|
||||
@@ -98,6 +99,16 @@ centreSpec = describe "centre" $ do
|
||||
it "should truncate the text" $
|
||||
centre 2 "foo" `shouldBe` "fo"
|
||||
|
||||
padRightSpec :: Spec
|
||||
padRightSpec = describe "padRight" $ mapM_
|
||||
(\(label, width, str, expected) -> context label $
|
||||
it ("should be " ++ show expected) $
|
||||
padRight width str `shouldBe` expected)
|
||||
-- label, width, input string, expected
|
||||
[ ( "text shorter", 5, "foo", "foo " )
|
||||
, ( "text longer", 3, "foobar", "foobar" )
|
||||
]
|
||||
|
||||
overlaySpec :: Spec
|
||||
overlaySpec = describe "overlay" $ do
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -22,45 +22,64 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
module Helpers.GoalieSpec (spec) where
|
||||
|
||||
import Lens.Micro ((&), (.~), (%~))
|
||||
import Test.Hspec (Spec, describe, it, shouldBe)
|
||||
import Test.Hspec (Spec, context, describe, it, shouldBe)
|
||||
|
||||
import Mtlstats.Helpers.Goalie
|
||||
import Mtlstats.Types
|
||||
|
||||
spec :: Spec
|
||||
spec = describe "Goalie"
|
||||
spec = describe "Goalie" $ do
|
||||
goalieDetailsSpec
|
||||
goalieNameSpec
|
||||
|
||||
goalieDetailsSpec :: Spec
|
||||
goalieDetailsSpec = describe "goalieDetails" $ let
|
||||
input = newGoalie 1 "Joe"
|
||||
& gRookie .~ True
|
||||
& gYtd
|
||||
%~ ( gsGames .~ 2 )
|
||||
. ( gsMinsPlayed .~ 3 )
|
||||
. ( gsGoalsAllowed .~ 4 )
|
||||
. ( gsWins .~ 5 )
|
||||
. ( gsLosses .~ 6 )
|
||||
. ( gsTies .~ 7 )
|
||||
. ( gsShutouts .~ 5 )
|
||||
. ( gsWins .~ 6 )
|
||||
. ( gsLosses .~ 7 )
|
||||
. ( gsTies .~ 8 )
|
||||
& gLifetime
|
||||
%~ ( gsGames .~ 8 )
|
||||
. ( gsMinsPlayed .~ 9 )
|
||||
. ( gsGoalsAllowed .~ 10 )
|
||||
. ( gsWins .~ 11 )
|
||||
. ( gsLosses .~ 12 )
|
||||
. ( gsTies .~ 13 )
|
||||
%~ ( gsGames .~ 9 )
|
||||
. ( gsMinsPlayed .~ 10 )
|
||||
. ( gsGoalsAllowed .~ 11 )
|
||||
. ( gsShutouts .~ 12 )
|
||||
. ( gsWins .~ 13 )
|
||||
. ( gsLosses .~ 14 )
|
||||
. ( gsTies .~ 15 )
|
||||
|
||||
expected = unlines
|
||||
[ "Number: 1"
|
||||
, " Name: Joe"
|
||||
, " Name: Joe*"
|
||||
, ""
|
||||
, " YTD Lifetime"
|
||||
, " Games played 2 8"
|
||||
, " Mins played 3 9"
|
||||
, "Goals allowed 4 10"
|
||||
, " Wins 5 11"
|
||||
, " Losses 6 12"
|
||||
, " Ties 7 13"
|
||||
, " Games played 2 9"
|
||||
, " Mins played 3 10"
|
||||
, "Goals allowed 4 11"
|
||||
, " Shutouts 5 12"
|
||||
, " Wins 6 13"
|
||||
, " Losses 7 14"
|
||||
, " Ties 8 15"
|
||||
]
|
||||
|
||||
in it "should format the output correctly" $
|
||||
goalieDetails input `shouldBe` expected
|
||||
|
||||
goalieNameSpec :: Spec
|
||||
goalieNameSpec = describe "goalieName" $ mapM_
|
||||
(\(label, g, expected) -> context label $
|
||||
it ("should be " ++ expected) $
|
||||
goalieName g `shouldBe` expected)
|
||||
|
||||
-- label, goalie, expected
|
||||
[ ( "rookie", goalie True, "foo*" )
|
||||
, ( "non-rookie", goalie False, "foo" )
|
||||
]
|
||||
|
||||
where
|
||||
goalie r = newGoalie 1 "foo" & gRookie .~ r
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -22,20 +22,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
module Helpers.PlayerSpec (spec) where
|
||||
|
||||
import Lens.Micro ((&), (.~))
|
||||
import Test.Hspec (Spec, describe, it, shouldBe)
|
||||
import Test.Hspec (Spec, context, describe, it, shouldBe)
|
||||
|
||||
import Mtlstats.Helpers.Player
|
||||
import Mtlstats.Types
|
||||
|
||||
spec :: Spec
|
||||
spec = describe "Player"
|
||||
spec = describe "Player" $ do
|
||||
playerDetailsSpec
|
||||
playerNameSpec
|
||||
|
||||
playerDetailsSpec :: Spec
|
||||
playerDetailsSpec = describe "playerDetails" $
|
||||
it "should give a detailed description" $ let
|
||||
|
||||
p = newPlayer 1 "Joe" "centre"
|
||||
& pRookie .~ True
|
||||
& pYtd .~ PlayerStats
|
||||
{ _psGoals = 2
|
||||
, _psAssists = 3
|
||||
@@ -49,7 +51,7 @@ playerDetailsSpec = describe "playerDetails" $
|
||||
|
||||
expected = unlines
|
||||
[ " Number: 1"
|
||||
, " Name: Joe"
|
||||
, " Name: Joe*"
|
||||
, "Position: centre"
|
||||
, ""
|
||||
, " YTD Lifetime"
|
||||
@@ -59,3 +61,19 @@ playerDetailsSpec = describe "playerDetails" $
|
||||
]
|
||||
|
||||
in playerDetails p `shouldBe` expected
|
||||
|
||||
playerNameSpec :: Spec
|
||||
playerNameSpec = describe "playerName" $ mapM_
|
||||
(\(label, p, expected) -> context label $
|
||||
it ("should be " ++ expected) $
|
||||
playerName p `shouldBe` expected)
|
||||
|
||||
-- label, player, expected
|
||||
[ ( "rookie", rookie, "foo*" )
|
||||
, ( "non-rookie", nonRookie, "foo" )
|
||||
]
|
||||
|
||||
where
|
||||
rookie = player True
|
||||
nonRookie = player False
|
||||
player r = newPlayer 1 "foo" "centre" & pRookie .~ r
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -36,7 +36,7 @@ import Data.Aeson.Types (Value (Object))
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.Ratio ((%))
|
||||
import Lens.Micro (Lens', (&), (^.), (.~), (?~))
|
||||
import System.Random (randomRIO)
|
||||
import System.Random (randomIO, randomRIO)
|
||||
import Test.Hspec (Spec, context, describe, it, shouldBe)
|
||||
|
||||
import Mtlstats.Config
|
||||
@@ -271,6 +271,7 @@ lensSpec lens getters setters = do
|
||||
|
||||
player :: Player
|
||||
player = newPlayer 1 "Joe" "centre"
|
||||
& pRookie .~ False
|
||||
& pYtd .~ playerStats 1
|
||||
& pLifetime .~ playerStats 2
|
||||
|
||||
@@ -279,6 +280,7 @@ playerJSON = Object $ HM.fromList
|
||||
[ ( "number", toJSON (1 :: Int) )
|
||||
, ( "name", toJSON ("Joe" :: String) )
|
||||
, ( "position", toJSON ("centre" :: String) )
|
||||
, ( "rookie", toJSON False )
|
||||
, ( "ytd", playerStatsJSON 1 )
|
||||
, ( "lifetime", playerStatsJSON 2 )
|
||||
]
|
||||
@@ -298,6 +300,7 @@ playerStatsJSON n = Object $ HM.fromList
|
||||
|
||||
goalie :: Goalie
|
||||
goalie = newGoalie 1 "Joe"
|
||||
& gRookie .~ False
|
||||
& gYtd .~ goalieStats 1
|
||||
& gLifetime .~ goalieStats 2
|
||||
|
||||
@@ -305,6 +308,7 @@ goalieJSON :: Value
|
||||
goalieJSON = Object $ HM.fromList
|
||||
[ ( "number", toJSON (1 :: Int) )
|
||||
, ( "name", toJSON ("Joe" :: String ) )
|
||||
, ( "rookie", toJSON False )
|
||||
, ( "ytd", goalieStatsJSON 1 )
|
||||
, ( "lifetime", goalieStatsJSON 2 )
|
||||
]
|
||||
@@ -843,6 +847,7 @@ makePlayer = Player
|
||||
<$> makeNum
|
||||
<*> makeName
|
||||
<*> makeName
|
||||
<*> makeBool
|
||||
<*> makePlayerStats
|
||||
<*> makePlayerStats
|
||||
|
||||
@@ -851,6 +856,7 @@ makeGoalie :: IO Goalie
|
||||
makeGoalie = Goalie
|
||||
<$> makeNum
|
||||
<*> makeName
|
||||
<*> makeBool
|
||||
<*> makeGoalieStats
|
||||
<*> makeGoalieStats
|
||||
|
||||
@@ -875,6 +881,9 @@ makeGoalieStats = GoalieStats
|
||||
makeNum :: IO Int
|
||||
makeNum = randomRIO (1, 10)
|
||||
|
||||
makeBool :: IO Bool
|
||||
makeBool = randomIO
|
||||
|
||||
makeName :: IO String
|
||||
makeName = replicateM 10 $ randomRIO ('A', 'Z')
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{-
|
||||
|
||||
mtlstats
|
||||
Copyright (C) 2019 Rhéal Lamothe
|
||||
Copyright (C) 1984, 1985, 2019, 2020 Rhéal Lamothe
|
||||
<rheal.lamothe@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -32,6 +32,7 @@ spec = describe "Mtlstats.Util" $ do
|
||||
modifyNthSpec
|
||||
updateMapSpec
|
||||
sliceSpec
|
||||
capitalizeNameSpec
|
||||
|
||||
nthSpec :: Spec
|
||||
nthSpec = describe "nth" $ mapM_
|
||||
@@ -93,3 +94,23 @@ sliceSpec = describe "slice" $ do
|
||||
context "negative offset" $
|
||||
it "should return the correct number of elements from the beginning" $
|
||||
slice (-10) 2 list `shouldBe` [2, 4]
|
||||
|
||||
capitalizeNameSpec :: Spec
|
||||
capitalizeNameSpec = describe "capitalizeName" $ mapM_
|
||||
(\(label, ch, str, expected) -> context label $
|
||||
it ("should be " ++ expected) $
|
||||
capitalizeName ch str `shouldBe` expected)
|
||||
-- label, character, string, expected
|
||||
[ ( "initial lower", 'a', "", "A" )
|
||||
, ( "initial upper", 'A', "", "A" )
|
||||
, ( "initial non-alpha", '0', "", "0" )
|
||||
, ( "pre-comma lower", 'a', "A", "AA" )
|
||||
, ( "pre-comma upper", 'A', "A", "AA" )
|
||||
, ( "pre-comma non-alpha", '0', "A", "A0" )
|
||||
, ( "post-comma first lower", 'a', "FOO, ", "FOO, A" )
|
||||
, ( "post-comma first upper", 'A', "FOO, ", "FOO, A" )
|
||||
, ( "post-comma first non-alpha", '0', "FOO, ", "FOO, 0" )
|
||||
, ( "unrestricted upper", 'A', "FOO, A", "FOO, AA" )
|
||||
, ( "unrestricted lower", 'a', "FOO, A", "FOO, Aa" )
|
||||
, ( "unrestricted non-alpha", '0', "FOO, A", "FOO, A0" )
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user