mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-12 15:50:20 -08:00
add elm for Acey Ducey
This commit is contained in:
206
00_Alternate_Languages/01_Acey_Ducey/elm/.gitignore
vendored
Normal file
206
00_Alternate_Languages/01_Acey_Ducey/elm/.gitignore
vendored
Normal 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
|
||||
12
00_Alternate_Languages/01_Acey_Ducey/elm/README.md
Normal file
12
00_Alternate_Languages/01_Acey_Ducey/elm/README.md
Normal 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
|
||||
```
|
||||
5909
00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.js
Normal file
5909
00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.js
Normal file
File diff suppressed because it is too large
Load Diff
1
00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.min.js
vendored
Normal file
1
00_Alternate_Languages/01_Acey_Ducey/elm/docs/app.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
19
00_Alternate_Languages/01_Acey_Ducey/elm/docs/index.html
Normal file
19
00_Alternate_Languages/01_Acey_Ducey/elm/docs/index.html
Normal 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>
|
||||
25
00_Alternate_Languages/01_Acey_Ducey/elm/elm.json
Normal file
25
00_Alternate_Languages/01_Acey_Ducey/elm/elm.json
Normal 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": {}
|
||||
}
|
||||
}
|
||||
1733
00_Alternate_Languages/01_Acey_Ducey/elm/package-lock.json
generated
Normal file
1733
00_Alternate_Languages/01_Acey_Ducey/elm/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
00_Alternate_Languages/01_Acey_Ducey/elm/package.json
Normal file
16
00_Alternate_Languages/01_Acey_Ducey/elm/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
308
00_Alternate_Languages/01_Acey_Ducey/elm/src/Main.elm
Normal file
308
00_Alternate_Languages/01_Acey_Ducey/elm/src/Main.elm
Normal 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"
|
||||
Reference in New Issue
Block a user