Skip to content

Instantly share code, notes, and snippets.

@danfishgold
Last active June 17, 2020 20:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danfishgold/5b924cc0ac1c3f3e9e59f33b18c80585 to your computer and use it in GitHub Desktop.
Save danfishgold/5b924cc0ac1c3f3e9e59f33b18c80585 to your computer and use it in GitHub Desktop.
for the london elm meetup on June 17th, 2020
module Player exposing (takeTurn)
import Set exposing (Set)
import Warrior exposing (Warrior)
import Warrior.Coordinate exposing (Coordinate)
import Warrior.Direction exposing (Direction(..))
import Warrior.History as History exposing (History)
import Warrior.Map as Map exposing (Map)
import Warrior.Map.Tile exposing (..)
coordinateToTuple : Coordinate -> ( Int, Int )
coordinateToTuple { x, y } =
( x, y )
dirs =
[ Up, Down, Left, Right ]
takeTurn : Warrior -> Map -> History -> Warrior.Action
takeTurn warrior map history =
let
prevPositions =
History.previousStates warrior history
|> List.map Tuple.first
|> List.map Warrior.position
|> List.map coordinateToTuple
|> Set.fromList
_ =
Debug.log "grades" (List.map (\dir -> ( dir, directionRating warrior map history dir )) dirs)
in
dirs
|> List.sortBy (\dir -> -(directionRating warrior map history dir))
|> List.head
|> Maybe.withDefault Right
|> Warrior.Move
directionRating : Warrior -> Map -> History -> Direction -> Int
directionRating warrior map history dir =
let
inFront =
Map.look dir warrior map
positionsInFront =
List.map Tuple.first inFront
in
case inFront of
[] ->
-100000
( _, Wall ) :: tl ->
-100000
_ ->
let
includesExit =
inFront |> List.map Tuple.second |> List.any ((==) Exit)
in
if includesExit then
100000
else
let
minMovesBackInHistory =
positionsInFront
|> List.filterMap (howManyMovesBackInHistory history warrior)
|> List.minimum
in
case minMovesBackInHistory of
Just count ->
count
Nothing ->
10000 + List.length inFront
howManyMovesBackInHistory : History -> Warrior -> Coordinate -> Maybe Int
howManyMovesBackInHistory history warrior coordinate =
let
historyItems =
History.previousStates warrior history
previousCoordinates =
historyItems
|> List.map Tuple.first
|> List.map Warrior.position
in
index coordinate previousCoordinates
|> Maybe.map (\idx -> List.length historyItems - 1 - idx)
index : a -> List a -> Maybe Int
index a xs =
case xs of
[] ->
Nothing
hd :: tl ->
if hd == a then
Just 0
else
index a tl |> Maybe.map (\idx -> idx + 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment