Add tile rendering

Includes both black and white tile variants
This commit is contained in:
Correl Roush 2017-08-07 15:04:55 -04:00
parent 67e3d1928b
commit 95af102310
92 changed files with 397 additions and 12 deletions

6
priv/.gitignore vendored
View file

@ -1,2 +1,4 @@
index.html
elm-stuff
riichi.js
riichi.css
elm-stuff/
node_modules/

View file

@ -1,7 +1,37 @@
all: index.html
.PHONY: all node-deps clean run
index.html:
elm-make --yes src/Riichi.elm --output=index.html --warn
TARGET = js/riichi.js
SOURCE = src/Riichi.elm
CSS = css/riichi.css
CSS_SOURCE = src/Stylesheets.elm
ELM_FILES = $(shell find . -type f -name '*.elm')
PATH := ./node_modules/.bin:$(PATH)
ELMMAKE_FLAGS = --yes --warn
ifeq ($(DEBUG),1)
ELMMAKE_FLAGS += --debug
endif
all: node-deps $(TARGET) $(CSS)
node-deps:
npm i
$(TARGET): $(ELM_FILES)
elm-make $(ELMMAKE_FLAGS) src/Riichi.elm --output=$@
$(CSS): $(CSS_SOURCE)
elm-css $(CSS_SOURCE) -o css
clean-deps:
rm -rf elm-stuff
rm -rf node_modules
clean:
rm -rf elm-stuff index.html
rm -f $(TARGET) $(CSS)
rm -rf elm-stuff/build-artifacts
run: all
elm-reactor

1
priv/css/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
riichi.css

View file

@ -8,8 +8,12 @@
],
"exposed-modules": [],
"dependencies": {
"elm-community/list-extra": "6.1.0 <= v < 7.0.0",
"elm-community/maybe-extra": "4.0.0 <= v < 5.0.0",
"elm-lang/core": "5.0.0 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0"
"elm-lang/html": "2.0.0 <= v < 3.0.0",
"rtfeldman/elm-css": "9.1.0 <= v < 10.0.0",
"rtfeldman/elm-css-helpers": "2.1.0 <= v < 3.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}

BIN
priv/images/Black/Back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
priv/images/Black/Blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
priv/images/Black/Chun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
priv/images/Black/Front.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
priv/images/Black/Haku.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

BIN
priv/images/Black/Hatsu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
priv/images/Black/Man1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
priv/images/Black/Man2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
priv/images/Black/Man3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
priv/images/Black/Man4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
priv/images/Black/Man5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
priv/images/Black/Man6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
priv/images/Black/Man7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
priv/images/Black/Man8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
priv/images/Black/Man9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
priv/images/Black/Nan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
priv/images/Black/Pei.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
priv/images/Black/Pin1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
priv/images/Black/Pin2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
priv/images/Black/Pin3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
priv/images/Black/Pin4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
priv/images/Black/Pin5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
priv/images/Black/Pin6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
priv/images/Black/Pin7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
priv/images/Black/Pin8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
priv/images/Black/Pin9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
priv/images/Black/Shaa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
priv/images/Black/Sou1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
priv/images/Black/Sou2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
priv/images/Black/Sou3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
priv/images/Black/Sou4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
priv/images/Black/Sou5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
priv/images/Black/Sou6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
priv/images/Black/Sou7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
priv/images/Black/Sou8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
priv/images/Black/Sou9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
priv/images/Black/Ton.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
priv/images/White/Back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
priv/images/White/Blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
priv/images/White/Chun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
priv/images/White/Front.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
priv/images/White/Haku.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

BIN
priv/images/White/Hatsu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
priv/images/White/Man1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
priv/images/White/Man2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
priv/images/White/Man3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
priv/images/White/Man4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
priv/images/White/Man5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
priv/images/White/Man6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
priv/images/White/Man7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
priv/images/White/Man8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
priv/images/White/Man9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
priv/images/White/Nan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
priv/images/White/Pei.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
priv/images/White/Pin1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
priv/images/White/Pin2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
priv/images/White/Pin3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
priv/images/White/Pin4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
priv/images/White/Pin5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
priv/images/White/Pin6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
priv/images/White/Pin7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
priv/images/White/Pin8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
priv/images/White/Pin9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
priv/images/White/Shaa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
priv/images/White/Sou1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
priv/images/White/Sou2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
priv/images/White/Sou3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
priv/images/White/Sou4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
priv/images/White/Sou5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
priv/images/White/Sou6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
priv/images/White/Sou7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
priv/images/White/Sou8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
priv/images/White/Sou9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
priv/images/White/Ton.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

12
priv/index.html Normal file
View file

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Riichi</title>
<script type="text/javascript" src="/js/riichi.js"></script>
<link rel="stylesheet" href="/css/riichi.css" />
</head>
<body>
<script type="text/javascript">Elm.Riichi.fullscreen()</script>
</body>
</html>

1
priv/js/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
riichi.js

8
priv/package.json Normal file
View file

@ -0,0 +1,8 @@
{
"name": "riichi",
"version": "1.0.0",
"dependencies": {
"elm": "0.18",
"elm-css": "0.6.1"
}
}

33
priv/src/Hand.elm Normal file
View file

@ -0,0 +1,33 @@
module Hand exposing (..)
import Html exposing (Html, div, text)
import Html.Attributes exposing (class)
import Maybe.Extra
import Tile exposing (Tile)
type alias JSON =
{ tiles : List String
}
type alias Model =
{ tiles : List Tile
}
fromJSON : JSON -> Model
fromJSON j =
{ tiles =
j.tiles
|> List.map Tile.fromString
|> Maybe.Extra.values
}
view : Model -> Html a
view model =
div [ class "hand" ]
[ div [ class "tiles open" ] <|
List.map Tile.view model.tiles
]

View file

@ -1,10 +1,17 @@
module Riichi exposing (..)
import Hand
import Html exposing (..)
import Html.CssHelpers
import Stylesheets as S
{ id, class, classList } =
Html.CssHelpers.withNamespace "riichi"
type alias Model =
{}
{ hand : Hand.Model }
type Msg
@ -13,7 +20,24 @@ type Msg
init : ( Model, Cmd Msg )
init =
( {}, Cmd.none )
( { hand =
Hand.fromJSON
{ tiles =
[ "4 pin"
, "5 pin"
, "6 pin"
, "4 sou"
, "5 sou"
, "6 sou"
, "4 man"
, "5 man"
, "6 man"
, "red dragon"
]
}
}
, Cmd.none
)
update : Msg -> Model -> ( Model, Cmd Msg )
@ -33,5 +57,7 @@ main =
view : Model -> Html Msg
view model =
div []
[ h1 [] [ text "Riichi Mahjong" ] ]
div [ class [ S.Tileset S.White ] ]
[ h1 [] [ text "Riichi Mahjong" ]
, Hand.view model.hand
]

105
priv/src/Stylesheets.elm Normal file
View file

@ -0,0 +1,105 @@
port module Stylesheets exposing (..)
import Css exposing (..)
import Css.Elements exposing (..)
import Css.Namespace exposing (namespace)
import Css.File exposing (CssFileStructure, CssCompilerProgram)
type Tileset
= White
| Black
type Class
= Tile String
| Tileset Tileset
riichi : Stylesheet
riichi =
(stylesheet << namespace "riichi") <|
List.concat
[ List.map tile tiles
, List.map (tileset White) tiles
, List.map (tileset Black) tiles
]
applyTileset : Tileset -> String -> Style
applyTileset set tile =
batch
[ backgroundImage (tileImage set "Front")
, children
[ span
[ backgroundImage (tileImage set tile) ]
]
]
tile : String -> Snippet
tile tile =
class (Tile tile)
[ display inlineBlock
, applyTileset White tile
, margin (px 10)
, width (px 60)
, height (px 80)
, backgroundSize (pct 100)
, children
[ span
[ display block
, height (pct 100)
, width (pct 100)
, backgroundSize (pct 80)
, backgroundRepeat noRepeat
, backgroundPosition center
]
]
]
tileset : Tileset -> String -> Snippet
tileset set tile =
class (Tileset set)
[ descendants
[ class (Tile tile)
[ applyTileset set tile ]
]
]
tiles : List String
tiles =
List.concat
[ [ "Chun"
, "Hatsu"
, "Haku"
, "Ton"
, "Nan"
, "Shaa"
, "Pei"
]
, List.range 1 9 |> List.map toString |> List.map (String.append "Pin")
, List.range 1 9 |> List.map toString |> List.map (String.append "Sou")
, List.range 1 9 |> List.map toString |> List.map (String.append "Man")
]
tileImage : Tileset -> String -> BackgroundImage {}
tileImage set tile =
url (String.concat [ "../images/", toString set, "/", tile, ".png" ])
port files : CssFileStructure -> Cmd msg
fileStructure : CssFileStructure
fileStructure =
Css.File.toFileStructure
[ ( "riichi.css", Css.File.compile [ riichi ] ) ]
main : CssCompilerProgram
main =
Css.File.compiler files fileStructure

159
priv/src/Tile.elm Normal file
View file

@ -0,0 +1,159 @@
module Tile exposing (..)
import Dict
import Html exposing (Html, span, text)
import Html.CssHelpers
import List.Extra
import String
import Stylesheets as S
{ id, class, classList } =
Html.CssHelpers.withNamespace "riichi"
type Wind
= East
| South
| West
| North
type Dragon
= Green
| Red
| White
type Suit
= Pin
| Sou
| Man
type Tile
= Wind Wind
| Dragon Dragon
| Suited Suit Int
type CssClass
= Tile Tile
fromString : String -> Maybe Tile
fromString s =
let
parts =
String.toLower s
|> String.split " "
in
case parts of
[ value, suit ] ->
make suit value
_ ->
Nothing
make : String -> String -> Maybe Tile
make suit value =
let
winds =
Dict.fromList
[ ( "east", East )
, ( "south", South )
, ( "west", West )
, ( "north", North )
]
dragons =
Dict.fromList
[ ( "green", Green )
, ( "red", Red )
, ( "white", White )
]
suits =
Dict.fromList
[ ( "pin", Pin )
, ( "sou", Sou )
, ( "man", Man )
]
in
case suit of
"wind" ->
Dict.get value winds
|> Maybe.map Wind
"dragon" ->
Dict.get value dragons
|> Maybe.map Dragon
_ ->
let
s =
Dict.get suit suits
v =
String.toInt value
|> Result.toMaybe
|> Maybe.andThen
(\x ->
if (x >= 1) && (x <= 9) then
Just x
else
Nothing
)
in
Maybe.map2 Suited s v
tiles : List Tile
tiles =
List.concat
[ List.map Wind [ East, South, West, North ]
, List.map Dragon [ Red, Green, White ]
, List.Extra.lift2 Suited
[ Man, Sou, Pin ]
(List.range 1 9)
]
cssName : Tile -> String
cssName tile =
case tile of
Dragon Red ->
"Chun"
Dragon Green ->
"Hatsu"
Dragon White ->
"Haku"
Wind East ->
"Ton"
Wind South ->
"Nan"
Wind West ->
"Shaa"
Wind North ->
"Pei"
Suited Pin v ->
String.concat [ "Pin", (toString v) ]
Suited Sou v ->
String.concat [ "Sou", (toString v) ]
Suited Man v ->
String.concat [ "Wan", (toString v) ]
view : Tile -> Html a
view tile =
span [ class [ (S.Tile (cssName tile)) ] ] [ span [] [] ]

View file

@ -11,7 +11,11 @@
start(_StartType, _StartArgs) ->
Dispatch = cowboy_router:compile(
[{'_', [{"/", cowboy_static, {priv_file, riichi, "index.html"}}]}
[{'_', [{"/", cowboy_static, {priv_file, riichi, "index.html"}},
{"/js/[...]", cowboy_static, {priv_dir, riichi, "js"}},
{"/css/[...]", cowboy_static, {priv_dir, riichi, "css"}},
{"/images/[...]", cowboy_static, {priv_dir, riichi, "images"}}
]}
]),
{ok, _} = cowboy:start_http(
my_http_listener,