Knight's tour: Difference between revisions

Undo revision 310917 by Dmcbane (talk)
(Undo revision 310918 by Dmcbane (talk))
(Undo revision 310917 by Dmcbane (talk))
Line 2,522:
 
=={{header|Elm}}==
<lang elm>moduleimport MainList exposing (mainconcatMap, foldl, head,member,filter,length,minimum,concat,map,map2,tail)
 
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 String exposing (join)
import Html as H
import Html.Attributes as HA
import TimeHtml.App exposing (Posix, everyprogram)
import BrowserTime exposing (elementTime,every, second)
import Svg exposing (rect, line, svg, g)
import Svg.Events exposing (onClick)
Line 2,539 ⟶ 2,537:
rowCount=20
colCount=20
dt = 0.03
 
type alias Cell = (Int, Int)
 
type alias Model =
{ path : List Cell
, board : List Cell
}
 
type Msg = NoOp | Tick Time | SetStart Cell
type Msg
= NoOp
| Tick Time.Posix
| SetStart Cell
 
init : () -> (Model,Cmd Msg)
init _ =
let board = (List.range [0 (..rowCount-1))] `andThen` \r ->
[0..colCount-1] `andThen` \c |-> andThen
[(\r, ->c)]
(List.range 0 (colCount-1))
|> andThen
(\c ->
[(r, c)]
)
)
path = []
in (Model path board, Cmd.none)
 
view : Model -> H.Html Msg
view model =
let
showChecker row col =
rect [ x <| String.fromInttoString col
, y <| String.fromInttoString row
, width "1"
, height "1"
, fill <| if modBy 2 (row + col) % 2 == 0 then "blue" else "grey"
, onClick <| SetStart (row, col)
]
[]
 
showMove (row0,col0) (row1,col1) =
line [ x1 <| String.fromFloattoString ((toFloat col0) + 0.5)
, y1 <| String.fromFloattoString ((toFloat row0) + 0.5)
, x2 <| String.fromFloattoString ((toFloat col1) + 0.5)
, y2 <| String.fromFloattoString ((toFloat row1) + 0.5)
, style "stroke:yellow;stroke-width:0.05"
]
[]
 
render mdlmodel =
let checkers = mdlmodel.board `andThen` \(r,c) ->
[showChecker r |> andThenc]
moves = case List.tail model.path (\(r,c) ->of
[showChecker r c]
)
moves = case List.tail mdl.path of
Nothing -> []
Just tl -> List.map2 showMove mdlmodel.path tl
in checkers ++ moves
 
unvisited = length model.board - length model.path
 
center = [ HA.style [ ( "text-align", "center") ]
 
in
H.div
[]
[ H.h2 [center] [H.text "Knight's Tour"]
, H.h2 [center] [H.text <| "Unvisited count : " ++ String.fromInttoString unvisited ]
, H.h2 [center] [H.text "(pick a square)"]
, H.div
[center]
[ svg
[ version "1.1"
, width (String.fromInttoString w)
, height (String.fromInttoString h)
, viewBox (join " "
[ String.fromInttoString 0
, String.fromInttoString 0
, String.fromInttoString colCount
, String.fromInttoString rowCount ])
]
[ g [] <| render model]
]
]
 
nextMoves : Model -> Cell -> List Cell
nextMoves model (stRow,stCol) =
let c = [ 1, 2, -1, -2]
 
km = c `andThen` \cRow ->
c |`andThen` \cCol -> andThen
if abs(cRow) == abs(cCol) then [] else [(\cRow ->,cCol)]
c
|> andThen
(\cCol ->
if abs(cRow) == abs(cCol) then [] else [(cRow,cCol)]
)
)
 
jumps = List.map (\(kmRow,kmCol) -> (kmRow + stRow, kmCol + stCol)) km
Line 2,644 ⟶ 2,625:
 
bestMove : Model -> Maybe Cell
bestMove model =
case List.head (model.path) of
Nothing -> Nothing
Line 2,652 ⟶ 2,633:
update msg model =
let mo = case msg of
SetStart start ->
{model | path = [start]}
Tick posixt ->
case model.path of
[] -> model
Line 2,664 ⟶ 2,645:
 
subscriptions : Model -> Sub Msg
subscriptions _ =
Time.every 10(dt * second) Tick
 
main =
program
element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}</lang>
 
 
Link to live demo: http://dc25.github.io/knightsTourElm/
Anonymous user