Knight's tour: Difference between revisions

Content added Content deleted
(Undo revision 310917 by Dmcbane (talk))
(→‎{{header|Elm}}: Updated to Elm 0.19.1)
Line 2,522: Line 2,522:


=={{header|Elm}}==
=={{header|Elm}}==
<lang elm>import List exposing (concatMap, foldl, head,member,filter,length,minimum,concat,map,map2,tail)
<lang elm>module Main exposing (main)

import Browser exposing (element)
import List exposing (concatMap, foldl, head,member,filter,length,minimum,concat,map,map2,tail)
import List.Extra exposing (minimumBy, andThen)
import List.Extra exposing (minimumBy, andThen)
import String exposing (join)
import String exposing (join)
import Html as H
import Html as H
import Html.Attributes as HA
import Html.Attributes as HA
import Html.App exposing (program)
import Time exposing (Posix, every)
import Time exposing (Time,every, second)
import Svg exposing (rect, line, svg, g)
import Svg exposing (rect, line, svg, g)
import Svg.Events exposing (onClick)
import Svg.Events exposing (onClick)
Line 2,537: Line 2,539:
rowCount=20
rowCount=20
colCount=20
colCount=20
dt = 0.03


type alias Cell = (Int, Int)
type alias Cell = (Int, Int)


type alias Model =
type alias Model =
{ path : List Cell
{ path : List Cell
, board : List Cell
, board : List Cell
}
}


type Msg
type Msg = NoOp | Tick Time | SetStart Cell
= NoOp
| Tick Time.Posix
| SetStart Cell


init : (Model,Cmd Msg)
init : () -> (Model,Cmd Msg)
init =
init _ =
let board = [0..rowCount-1] `andThen` \r ->
let board = (List.range 0 (rowCount-1))
[0..colCount-1] `andThen` \c ->
|> andThen
[(r, c)]
(\r ->
(List.range 0 (colCount-1))
|> andThen
(\c ->
[(r, c)]
)
)
path = []
path = []
in (Model path board, Cmd.none)
in (Model path board, Cmd.none)


view : Model -> H.Html Msg
view : Model -> H.Html Msg
view model =
view model =
let
let
showChecker row col =
showChecker row col =
rect [ x <| toString col
rect [ x <| String.fromInt col
, y <| toString row
, y <| String.fromInt row
, width "1"
, width "1"
, height "1"
, height "1"
, fill <| if (row + col) % 2 == 0 then "blue" else "grey"
, fill <| if modBy 2 (row + col) == 0 then "blue" else "grey"
, onClick <| SetStart (row, col)
, onClick <| SetStart (row, col)
]
]
[]
[]


showMove (row0,col0) (row1,col1) =
showMove (row0,col0) (row1,col1) =
line [ x1 <| toString ((toFloat col0) + 0.5)
line [ x1 <| String.fromFloat ((toFloat col0) + 0.5)
, y1 <| toString ((toFloat row0) + 0.5)
, y1 <| String.fromFloat ((toFloat row0) + 0.5)
, x2 <| toString ((toFloat col1) + 0.5)
, x2 <| String.fromFloat ((toFloat col1) + 0.5)
, y2 <| toString ((toFloat row1) + 0.5)
, y2 <| String.fromFloat ((toFloat row1) + 0.5)
, style "stroke:yellow;stroke-width:0.05"
, style "stroke:yellow;stroke-width:0.05"
]
]
[]
[]


render model =
render mdl =
let checkers = model.board `andThen` \(r,c) ->
let checkers = mdl.board
[showChecker r c]
|> andThen
moves = case List.tail model.path of
(\(r,c) ->
[showChecker r c]
)
moves = case List.tail mdl.path of
Nothing -> []
Nothing -> []
Just tl -> List.map2 showMove model.path tl
Just tl -> List.map2 showMove mdl.path tl
in checkers ++ moves
in checkers ++ moves


unvisited = length model.board - length model.path
unvisited = length model.board - length model.path


center = HA.style [ ( "text-align", "center") ]
center = [ HA.style "text-align" "center" ]


in
in
H.div
H.div
[]
[]
[ H.h2 [center] [H.text "Knight's Tour"]
[ H.h2 center [H.text "Knight's Tour"]
, H.h2 [center] [H.text <| "Unvisited count : " ++ toString unvisited ]
, H.h2 center [H.text <| "Unvisited count : " ++ String.fromInt unvisited ]
, H.h2 [center] [H.text "(pick a square)"]
, H.h2 center [H.text "(pick a square)"]
, H.div
, H.div
[center]
center
[ svg
[ svg
[ version "1.1"
[ version "1.1"
, width (toString w)
, width (String.fromInt w)
, height (toString h)
, height (String.fromInt h)
, viewBox (join " "
, viewBox (join " "
[ toString 0
[ String.fromInt 0
, toString 0
, String.fromInt 0
, toString colCount
, String.fromInt colCount
, toString rowCount ])
, String.fromInt rowCount ])
]
]
[ g [] <| render model]
[ g [] <| render model]
]
]
]
]


nextMoves : Model -> Cell -> List Cell
nextMoves : Model -> Cell -> List Cell
nextMoves model (stRow,stCol) =
nextMoves model (stRow,stCol) =
let c = [ 1, 2, -1, -2]
let c = [ 1, 2, -1, -2]


km = c `andThen` \cRow ->
km = c
c `andThen` \cCol ->
|> andThen
if abs(cRow) == abs(cCol) then [] else [(cRow,cCol)]
(\cRow ->
c
|> andThen
(\cCol ->
if abs(cRow) == abs(cCol) then [] else [(cRow,cCol)]
)
)


jumps = List.map (\(kmRow,kmCol) -> (kmRow + stRow, kmCol + stCol)) km
jumps = List.map (\(kmRow,kmCol) -> (kmRow + stRow, kmCol + stCol)) km
Line 2,625: Line 2,644:


bestMove : Model -> Maybe Cell
bestMove : Model -> Maybe Cell
bestMove model =
bestMove model =
case List.head (model.path) of
case List.head (model.path) of
Nothing -> Nothing
Nothing -> Nothing
Line 2,633: Line 2,652:
update msg model =
update msg model =
let mo = case msg of
let mo = case msg of
SetStart start ->
SetStart start ->
{model | path = [start]}
{model | path = [start]}
Tick t ->
Tick posix ->
case model.path of
case model.path of
[] -> model
[] -> model
Line 2,645: Line 2,664:


subscriptions : Model -> Sub Msg
subscriptions : Model -> Sub Msg
subscriptions _ =
subscriptions _ =
Time.every (dt * second) Tick
Time.every 10 Tick


main =
main =
element
program
{ init = init
{ init = init
, view = view
, view = view
, update = update
, update = update
, subscriptions = subscriptions
, subscriptions = subscriptions
}</lang>
}
</lang>


Link to live demo: http://dc25.github.io/knightsTourElm/
Link to live demo: http://dc25.github.io/knightsTourElm/