halma-telegram-bot-0.1.0.0: src/Game/Halma/TelegramBot/View/I18n.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Game.Halma.TelegramBot.View.I18n
( HalmaLocale (..)
, NotYourTurnInfo (..)
, CantUndoReason (..)
, AIMove (..)
, enHalmaLocale
, deHalmaLocale
, LocaleId (..)
, allLocaleIds
, localeById
) where
import Game.Halma.Board (HalmaDirection)
import Game.Halma.TelegramBot.Model.Types
import Game.Halma.TelegramBot.View.Pretty
import Game.Halma.TelegramBot.Model.MoveCmd
import Data.Char (toUpper)
import Data.Monoid ((<>))
import qualified Data.Aeson as A
import qualified Data.Text as T
import qualified Web.Telegram.API.Bot as TG
data NotYourTurnInfo
= NotYourTurnInfo
{ you :: TG.User
, thePlayerWhoseTurnItIs :: Player
}
data CantUndoReason
= CantUndoNoGame
data AIMove
= AIMove
{ aiHomeCorner :: HalmaDirection
, aiMoveCmd :: MoveCmd
}
data HalmaLocale
= HalmaLocale
{ hlWelcomeMsg :: T.Text
, hlHelpMsg :: T.Text
, hlCongratulation :: ExtendedPartyResult -> T.Text
, hlCantStartNewRoundBecauseNoMatch :: T.Text
, hlStartingANewRound :: T.Text
, hlYourTurn :: HalmaDirection -> TG.User -> T.Text
, hlNotYourTurn :: NotYourTurnInfo -> T.Text
, hlCantUndo :: Maybe CantUndoReason -> T.Text
, hlAIMove :: AIMove -> T.Text
, hlNoMatchMsg :: T.Text
, hlNoRoundMsg :: T.Text
}
-- | English
enHalmaLocale :: HalmaLocale
enHalmaLocale =
HalmaLocale
{ hlWelcomeMsg =
"Greetings from HalmaBot! I am an [open-source](https://github.com/timjb/halma) Telegram bot " <>
"written in Haskell by Tim Baumann <tim@timbaumann.info>."
, hlHelpMsg =
"You can control me by sending these commands:\n" <>
"/newmatch — starts a new match between two or three players\n" <>
"/newround — start a new game round\n" <>
"/undo — reverse your last move\n" <>
"/setlang [" <> localesText <> "] — switch to another language\n" <>
"/help — display this message\n\n" <>
"Here's how move commands are structured:\n" <>
"First there comes a letter in the range A-O (the piece you want to " <>
" move), then the number of the row you want to move the piece to. " <>
"If there are multiple possible target positions on the row, I will " <>
"ask you which one you mean.\n" <>
"For example: the command 'a11' makes me move your piece labeled 'a' " <>
"to row number 11."
, hlCongratulation = congrat
, hlCantStartNewRoundBecauseNoMatch =
"Can't start a new round, because there is no match running. You have to start a /newmatch first."
, hlStartingANewRound =
"starting a new round!"
, hlYourTurn = \homeCorner user ->
prettyUser user <> " " <> teamEmoji homeCorner <> " it's your turn!"
, hlNotYourTurn = \notYourTurn ->
"Hey " <> prettyUser (you notYourTurn) <> ", it's not your turn, it's " <>
prettyPlayer (thePlayerWhoseTurnItIs notYourTurn) <> "'s!"
, hlCantUndo = \case
Nothing -> "can't undo!"
Just CantUndoNoGame -> "can't undo: no game running!"
, hlAIMove = \aiMove ->
"The AI " <> teamEmoji (aiHomeCorner aiMove) <>
" makes the following move: " <> showMoveCmd (aiMoveCmd aiMove)
, hlNoMatchMsg =
"Start a new Halma match with /newmatch"
, hlNoRoundMsg =
"Start a new round with /newround"
}
where
nominal i =
case i of
1 -> "first"
2 -> "second"
3 -> "third"
4 -> "fourth"
5 -> "fifth"
6 -> "sixth"
_ -> "(error: unexpected integer)"
deficitMsg result =
"with a deficit of " <> T.pack (show (eprLag result)) <> " moves"
congrat result =
let
party = prParty $ eprPartyResult result
in
case (partyPlayer party, eprPlace result) of
(AIPlayer, i) ->
"The AI " <> teamEmoji (partyHomeCorner party) <> " finishes " <>
nominal (i+1) <>
(if i == 0 then "" else " " <> deficitMsg result)
(TelegramPlayer user, 0) ->
prettyUser user <> ", " <>
"congratulations on your " <>
(if eprPlaceShared result then "shared " else "") <>
"first place \127941" -- unicode symbol: sports medal
(TelegramPlayer user, i) ->
prettyUser user <> ", " <>
"you are " <> nominal (i+1) <>
" " <> deficitMsg result
-- | German (deutsch)
deHalmaLocale :: HalmaLocale
deHalmaLocale =
HalmaLocale
{ hlWelcomeMsg =
"Hallo, ich bin @HalmaBot, ein [quelloffener](https://github.com/timjb/halma) Telegram-Bot " <>
" programmiert von Tim Baumann <tim@timbaumann.info> in Haskell."
, hlHelpMsg =
"Du kannst mich durch folgende Kommandos steuern:\n" <>
"/newmatch — startet ein neues Halma-Match\n" <>
"/newround — startet eine neue Spielrunde im aktuellen Match\n" <>
"/undo — macht den letzten Zug rückgängig\n" <>
"/setlang [" <> localesText <> "] — wechsle die Sprache / switch to another language\n" <>
"/help — zeigt diese Hilfe-Nachricht an\n\n" <>
"Zuganweisungen sind folgendermaßen aufgebaut:\n" <>
"Zuerst kommt ein Buchstabe von A bis O (der Spielstein, den du " <>
" bewegen möchtest), dann kommt die Nummer der Reihe in den du den " <>
" Stein bewegen möchtest. " <>
"Wenn es mehrere mögliche Zielpositionen innerhalb dieser Reihe gibt, " <>
"dann frage ich dich, welche du genau meinst.\n" <>
"Zum Beispiel: Das Kommando 'a11' bewegt deinen Stein mit der " <>
"Aufschrift 'a' in die Zeile Nummer 11."
, hlCongratulation = congrat
, hlCantStartNewRoundBecauseNoMatch =
"Um eine neue Runde zu starten, muss erst ein neues Spiel mit /newmatch gestartet werden."
, hlStartingANewRound =
"Neue Runde!"
, hlYourTurn = \homeCorner user ->
prettyUser user <> " " <> teamEmoji homeCorner <> ", du bist dran!"
, hlNotYourTurn = \notYourTurn ->
"Hey " <> prettyUser (you notYourTurn) <> ", du bist nicht an der Reihe, sondern " <>
prettyPlayer (thePlayerWhoseTurnItIs notYourTurn) <> "!"
, hlCantUndo = \case
Nothing -> "'undo' nicht möglich!"
Just CantUndoNoGame -> "'undo' nicht möglich: es ist gerade kein Spiel am Laufen!"
, hlAIMove = \aiMove ->
"Die KI " <> teamEmoji (aiHomeCorner aiMove) <>
" macht den folgenden Zug: " <> showMoveCmd (aiMoveCmd aiMove)
, hlNoMatchMsg =
"Starte ein neues Halma-Match mit /newmatch"
, hlNoRoundMsg =
"Starte eine neue Runde mit /newround"
}
where
nominal i =
case i of
1 -> "erster"
2 -> "zweiter"
3 -> "dritter"
4 -> "vierter"
5 -> "fünfter"
6 -> "sechster"
_ -> "(Fehler: unerwartete Zahl)"
deficitMsg result =
"mit einem Rückstand von " <>
T.pack (show (eprLag result)) <>
" Zügen"
congrat result =
let
party = prParty $ eprPartyResult result
in
case (partyPlayer party, eprPlace result) of
(AIPlayer, i) ->
"Die KI " <> teamEmoji (partyHomeCorner party) <> " wird " <>
(if eprPlaceShared result then "ebenfalls " else "") <>
capitalize (nominal (i+1)) <>
(if i == 0 then "" else " " <> deficitMsg result)
(TelegramPlayer user, 0) ->
prettyUser user <> ", " <>
"Glückwunsch zum " <>
(if eprPlaceShared result then "geteilten " else "") <>
"ersten Platz \127941" -- unicode symbol: sports medal
(TelegramPlayer user, i) ->
prettyUser user <> ", " <>
"du bist " <>
(if eprPlaceShared result then "auch " else "") <>
capitalize (nominal (i+1)) <>
" " <> deficitMsg result
capitalize :: T.Text -> T.Text
capitalize t =
if T.null t then
t
else
toUpper (T.head t) `T.cons` T.tail t
allLocaleIds :: [LocaleId]
allLocaleIds = [En, De]
localesText :: T.Text
localesText = T.intercalate " / " (map prettyLocaleId allLocaleIds)
localeById :: LocaleId -> HalmaLocale
localeById localeId =
case localeId of
En -> enHalmaLocale
De -> deHalmaLocale