Knight's tour: Difference between revisions

Content added Content deleted
(Undo revision 310918 by Dmcbane (talk))
(Undo revision 310917 by Dmcbane (talk))
Line 2,522: Line 2,522:


=={{header|Elm}}==
=={{header|Elm}}==
<lang elm>module Main exposing (main)
<lang elm>import List exposing (concatMap, 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 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 Time exposing (Posix, every)
import Html.App exposing (program)
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,539: Line 2,537:
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 = NoOp | Tick Time | SetStart Cell
type Msg
= NoOp
| Tick Time.Posix
| SetStart Cell


init : () -> (Model,Cmd Msg)
init : (Model,Cmd Msg)
init _ =
init =
let board = (List.range 0 (rowCount-1))
let board = [0..rowCount-1] `andThen` \r ->
|> andThen
[0..colCount-1] `andThen` \c ->
(\r ->
[(r, c)]
(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 <| String.fromInt col
rect [ x <| toString col
, y <| String.fromInt row
, y <| toString row
, width "1"
, width "1"
, height "1"
, height "1"
, fill <| if modBy 2 (row + col) == 0 then "blue" else "grey"
, fill <| if (row + col) % 2 == 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 <| String.fromFloat ((toFloat col0) + 0.5)
line [ x1 <| toString ((toFloat col0) + 0.5)
, y1 <| String.fromFloat ((toFloat row0) + 0.5)
, y1 <| toString ((toFloat row0) + 0.5)
, x2 <| String.fromFloat ((toFloat col1) + 0.5)
, x2 <| toString ((toFloat col1) + 0.5)
, y2 <| String.fromFloat ((toFloat row1) + 0.5)
, y2 <| toString ((toFloat row1) + 0.5)
, style "stroke:yellow;stroke-width:0.05"
, style "stroke:yellow;stroke-width:0.05"
]
]
[]
[]


render mdl =
render model =
let checkers = mdl.board
let checkers = model.board `andThen` \(r,c) ->
|> andThen
[showChecker r c]
(\(r,c) ->
moves = case List.tail model.path of
[showChecker r c]
)
moves = case List.tail mdl.path of
Nothing -> []
Nothing -> []
Just tl -> List.map2 showMove mdl.path tl
Just tl -> List.map2 showMove model.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 : " ++ String.fromInt unvisited ]
, H.h2 [center] [H.text <| "Unvisited count : " ++ toString 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 (String.fromInt w)
, width (toString w)
, height (String.fromInt h)
, height (toString h)
, viewBox (join " "
, viewBox (join " "
[ String.fromInt 0
[ toString 0
, String.fromInt 0
, toString 0
, String.fromInt colCount
, toString colCount
, String.fromInt rowCount ])
, toString 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
km = c `andThen` \cRow ->
|> andThen
c `andThen` \cCol ->
(\cRow ->
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
jumps = List.map (\(kmRow,kmCol) -> (kmRow + stRow, kmCol + stCol)) km
Line 2,644: Line 2,625:


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,652: Line 2,633:
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 posix ->
Tick t ->
case model.path of
case model.path of
[] -> model
[] -> model
Line 2,664: Line 2,645:


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


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



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