add elm for Acey Ducey

This commit is contained in:
Auryn Engel
2022-03-16 09:54:04 +01:00
parent 7da5cdb12b
commit aab72fc572
10 changed files with 8248 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
# Created by https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,elm
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,visualstudiocode,elm
### Elm ###
# elm-package generated files
elm-stuff
# elm-repl generated files
repl-temp-*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# Support for Project snippet scope
# End of https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,elm
# Created by https://www.toptal.com/developers/gitignore/api/node
# Edit at https://www.toptal.com/developers/gitignore?templates=node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
### Node Patch ###
# Serverless Webpack directories
.webpack/
# Optional stylelint cache
# SvelteKit build / generate output
.svelte-kit
# End of https://www.toptal.com/developers/gitignore/api/node

View File

@@ -0,0 +1,12 @@
# Acey Ducey
This is an Elm implementation of the `Basic Compouter Games` Game Acey Ducey.
## Build App
- install elm
```bash
yarn
yarn build
```

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
</head>
<body>
<div id="elm-app-is-loaded-here"></div>
<script src="app.min.js"></script>
<script>
var app = Elm.Main.init({
node: document.getElementById("elm-app-is-loaded-here"),
flags: {}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/random": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
{
"name": "01_Acey_Ducey",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/auryn31/01_Acey_Ducey.git",
"author": "Auryn Engel <auryn.engel@sap.com>",
"license": "MIT",
"scripts": {
"live": "elm-live src/Main.elm --proxy-prefix=/api --proxy-host=http://localhost:8080/api --open --start-page=resources/index.html -- --output=app.js",
"build": "elm make src/Main.elm --optimize --output docs/app.js && cp -R resources/ docs/"
},
"devDependencies": {
"elm-live": "^4.0.2",
"uglify-js": "^3.15.3"
}
}

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
</head>
<body>
<div id="elm-app-is-loaded-here"></div>
<script src="app.js"></script>
<script>
var app = Elm.Main.init({
node: document.getElementById("elm-app-is-loaded-here"),
flags: {}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,308 @@
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes exposing (style, type_, value)
import Html.Events exposing (onInput)
import Random
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- Models
type alias Model =
{ money : Int
, currentGame : Game
, lastGame : Maybe Game
, moneyBet : Int
, error : Maybe String
}
type alias Game =
{ cardA : Maybe Int
, cardB : Maybe Int
, cardC : Maybe Int
}
-- Init
init : () -> ( Model, Cmd Msg )
init _ =
( { money = 100, currentGame = { cardA = Nothing, cardB = Nothing, cardC = Nothing }, lastGame = Nothing, moneyBet = 0, error = Nothing }, Random.generate NewCard newCard )
-- Messages
type Msg
= BetMoney Int
| UpdateBetValue String
| NewCard Int
| NewCardC Int
| Play
| NewGame
-- Update
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
BetMoney bet ->
( { model | moneyBet = bet }, Cmd.none )
UpdateBetValue value ->
case String.toInt value of
Just newValue ->
if newValue > model.money then
( { model | error = Just "You cannot bet more than you have", moneyBet = model.money }, Cmd.none )
else
( { model | moneyBet = newValue, error = Nothing }, Cmd.none )
Nothing ->
( { model | error = Just "Wrong input for bet" }, Cmd.none )
NewCard card ->
case model.currentGame.cardA of
Nothing ->
let
currentGame =
model.currentGame
in
if card > 13 then
( model, Random.generate NewCard newCard )
else
( { model | currentGame = { currentGame | cardA = Just card } }, Random.generate NewCard newCard )
Just cardA ->
let
currentGame =
model.currentGame
in
if card <= cardA then
( { model | currentGame = { currentGame | cardA = Just card } }, Random.generate NewCard newCard )
else
( { model | currentGame = { currentGame | cardB = Just card } }, Cmd.none )
Play ->
( model, Random.generate NewCardC newCard )
NewCardC card ->
calculateNewState card model
NewGame ->
init ()
calculateNewState : Int -> Model -> ( Model, Cmd Msg )
calculateNewState cardC model =
case model.currentGame.cardA of
Just cardA ->
case model.currentGame.cardB of
Just cardB ->
let
currentGame =
model.currentGame
in
if cardC == cardA || cardC == cardB then
( model, Random.generate NewCardC newCard )
else if cardA < cardC && cardC < cardB then
( { model | money = model.money + model.moneyBet, currentGame = { currentGame | cardA = Nothing, cardB = Nothing }, lastGame = Just { cardA = model.currentGame.cardA, cardB = model.currentGame.cardB, cardC = Just cardC } }, Random.generate NewCard newCard )
else if model.moneyBet > model.money - model.moneyBet then
( { model | money = model.money - model.moneyBet, moneyBet = model.money - model.moneyBet, currentGame = { currentGame | cardA = Nothing, cardB = Nothing }, lastGame = Just { cardA = model.currentGame.cardA, cardB = model.currentGame.cardB, cardC = Just cardC } }, Random.generate NewCard newCard )
else
( { model | money = model.money - model.moneyBet, currentGame = { currentGame | cardA = Nothing, cardB = Nothing }, lastGame = Just { cardA = model.currentGame.cardA, cardB = model.currentGame.cardB, cardC = Just cardC } }, Random.generate NewCard newCard )
Nothing ->
( model, Cmd.none )
Nothing ->
( model, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
-- Views
view : Model -> Html Msg
view model =
div centerHeadlineStyle
[ showHeader
, showGame model
]
showHeader : Html msg
showHeader =
div headerStyle
[ h1 [ style "font-size" "4rem" ] [ text "ACEY DUCEY CARD GAME" ]
, div [] [ text "Creative Computing Morristown, New Jersey" ]
, div []
[ text """
Acey-Ducey is played in the following manner. The Dealer (Computer) deals two cards face up.
You have an option to bet or not bet depending on whether or not you feel the card will have a value between the first two.
If you do not want to bet, bet 0.
"""
]
]
showGame : Model -> Html Msg
showGame model =
if model.money <= 0 then
article gameStyle
[ p cardContentPStyle [ text "You lose all you money" ]
, button [ Html.Events.onClick NewGame, standardFontSize ] [ text "Again" ]
]
else
article gameStyle
[ p cardContentPStyle [ text ("Currently you have " ++ String.fromInt model.money ++ " in your pocket.") ]
, p cardContentPStyle [ text ("Card 1: " ++ cardToString model.currentGame.cardA) ]
, p cardContentPStyle [ text ("Card 2: " ++ cardToString model.currentGame.cardB) ]
, p cardContentPStyle [ text ("Your current bet is " ++ String.fromInt model.moneyBet) ]
, input [ type_ "range", Html.Attributes.max (String.fromInt model.money), Html.Attributes.min "0", Html.Attributes.value (String.fromInt model.moneyBet), onInput UpdateBetValue ] []
, button [ Html.Events.onClick Play, standardFontSize ] [ text "Play" ]
, showLastGame model.lastGame
, showError model.error
]
showLastGame : Maybe Game -> Html Msg
showLastGame game =
case game of
Nothing ->
div [ standardFontSize ] [ text "This is your first game" ]
Just value ->
div []
[ showLastWinLose value
, p cardContentPStyle [ text ("Card 1: " ++ cardToString value.cardA) ]
, p cardContentPStyle [ text ("Card 2: " ++ cardToString value.cardB) ]
, p cardContentPStyle [ text ("Drawn Card: " ++ cardToString value.cardC) ]
]
showLastWinLose : Game -> Html Msg
showLastWinLose game =
Maybe.map3 getGameStateMessage game.cardA game.cardB game.cardC |> Maybe.withDefault (text "something is wrong")
getGameStateMessage : Int -> Int -> Int -> Html Msg
getGameStateMessage cardA cardB cardC =
if cardA < cardC && cardB > cardC then
div [ standardFontSize ] [ text "You won :)" ]
else
div [ standardFontSize ] [ text "You loose :(" ]
showError : Maybe String -> Html Msg
showError value =
case value of
Just string ->
p [ standardFontSize ] [ text string ]
Nothing ->
div [] []
-- Helper
cardToString : Maybe Int -> String
cardToString card =
case card of
Just value ->
if value < 11 then
String.fromInt value
else
case value of
11 ->
"Jack"
12 ->
"Queen"
13 ->
"King"
14 ->
"Ace"
_ ->
"impossible value"
Nothing ->
"-"
newCard : Random.Generator Int
newCard =
Random.int 2 14
-- Styles
headerStyle : List (Attribute msg)
headerStyle =
[ style "font-size" "2rem", style "text-align" "center" ]
cardContentPStyle : List (Attribute msg)
cardContentPStyle =
[ style "font-size" "2rem"
]
gameStyle : List (Attribute msg)
gameStyle =
[ style "width" "100%"
, style "max-width" "70rem"
]
centerHeadlineStyle : List (Attribute msg)
centerHeadlineStyle =
[ style "display" "grid"
, style "place-items" "center"
, style "margin" "2rem"
]
standardFontSize : Attribute msg
standardFontSize =
style "font-size" "2rem"