Skip to content

Instantly share code, notes, and snippets.

@wegry
Created May 24, 2018 19:30
Show Gist options
  • Save wegry/898956b36a82d1821a6bccc35014984c to your computer and use it in GitHub Desktop.
Save wegry/898956b36a82d1821a6bccc35014984c to your computer and use it in GitHub Desktop.
Lucrative Hangman app
module Main exposing (..)
import Char
import Set
import Html exposing (Html, pre, text, div, h1, img, button, span)
import Html.Attributes exposing (src)
import Html.Events exposing (onClick)
---- MODEL ----
type alias Model =
{ word : String
, totalTries : Int
, triesLeft : Int
, currentGuesses : List Char
}
init : ( Model, Cmd Msg )
init =
let
totalTries =
5
in
( { word = "Ordnung muss sein" |> String.toUpper
, totalTries = totalTries
, triesLeft = totalTries
, currentGuesses = [ ' ' ]
}
, Cmd.none
)
---- UPDATE ----
type Msg
= LetterClicked Char
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
LetterClicked letter ->
let
correctGuess =
String.contains (String.fromChar letter) model.word
triesLeft =
if (correctGuess) then
model.triesLeft
else
model.triesLeft - 1
in
( { model | currentGuesses = letter :: model.currentGuesses, triesLeft = triesLeft }, Cmd.none )
type WhoAreYou
= Winner
| Loser
| Undecided
whoAreYou : Model -> WhoAreYou
whoAreYou { triesLeft, currentGuesses, word } =
let
characterSet =
word |> String.toList |> Set.fromList
guessSet =
currentGuesses |> Set.fromList
weCovered =
Set.diff characterSet guessSet |> Set.isEmpty
in
if triesLeft <= 0 then
Loser
else if weCovered then
Winner
else
Undecided
---- VIEW ----
view : Model -> Html Msg
view model =
let
areYouSuccessful =
whoAreYou model
letters =
List.range 65 90
|> List.map Char.fromCode
|> List.map
(\x ->
let
stringVersion =
String.fromChar x
in
button
[ Html.Attributes.disabled <|
areYouSuccessful
== Loser
|| (List.member x model.currentGuesses)
, onClick <| LetterClicked x
]
[ text stringVersion ]
)
wordView =
model.word
|> String.toList
|> List.map
(\x ->
if (x == ' ') then
' '
else if List.member x model.currentGuesses then
x
else
'_'
)
|> List.intersperse ' '
|> String.fromList
in
div []
[ img [ src "/logo.svg" ] []
, div [] letters
, pre [] [ (text wordView) ]
, span [] [ text (toString areYouSuccessful) ]
, span [] [ text (" " ++ (toString model.triesLeft) ++ " / " ++ (toString model.totalTries)) ]
]
---- PROGRAM ----
main : Program Never Model Msg
main =
Html.program
{ view = view
, init = init
, update = update
, subscriptions = always Sub.none
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment