Mercurial > repos > icfp2014
view code/dotScanner.lm @ 36:c0b3922646d8
Fill in readme
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 26 Jul 2014 03:18:10 -0700 |
parents | 8c26981aae8c |
children | d5ccb66ae98b |
line wrap: on
line source
#{ length <- :lst { len <- [] while: { not: (lst isInteger?)} do: { lst <- lst tail len <- len + 1 } len } reverse <- :lst { new <- [] while: { not: (lst isInteger?)} do: { new <- (lst value) | new lst <- lst tail } new } split:at <- :lst :pos { first <- [] i <- 0 while: { i < pos } do: { first <- (lst value) | first lst <- lst tail i <- i + 1 } #[(reverse: first) lst] } map <- :lst fun { new <- [] while: { not: (lst isInteger?) } do: { new <- (fun: (lst value)) | new lst <- lst tail } reverse: new } fold:with <- :lst acc :fun { while: { not: (lst isInteger?) } do: { acc <- fun: acc (lst value) lst <- lst tail } acc } filter <- :lst pred { new <- [] while: { not: (lst isInteger?) } do: { if: (pred: (lst value)) { new <- (lst value) | new } else: {} lst <- lst tail } reverse: new } flatten <- :lst { fold: lst [] with: :acc el { fold: el acc with: :iacc iel { iel | iacc } } } makeTree:size <- :lst :size { ret <- 0 sub <- 0 half <- size / 2 if: size = 2 { ret <- #[(lst value) ((lst tail) value)] } else: { if: size = 1 { ret <- lst } else: { sub <- split: lst at: half ret <- #[ (makeTree: (sub value) size: half) (makeTree: (sub tail) size: size-half) ] } } ret } makeTree <- :lst { size <- lst length #[size (makeTree: lst size: size)] } get:fromTree:size <- :idx :tree :size { ret <- 0 half <- size / 2 if: size <= 2 { if: idx = 0 { ret <- tree value } else: { ret <- tree tail } } else: { if: idx < half { ret <- get: idx fromTree: (tree value) size: half } else: { ret <- get: idx-half fromTree: (tree tail) size: size-half } } ret } get:fromTree <- :idx :tree { size <- tree value get: idx fromTree: (tree tail) size: size } treeMap:size <- :tree fun :size { ret <- 0 half <- size / 2 if: size = 2 { ret <- #[(fun: (tree value)) (fun: (tree tail))] } else: { if: size = 1 { ret <- #[(fun: (tree value)) 0] } else: { ret <- #[ (treeMap: (tree value) fun size: half) (treeMap: (tree tail) fun size: size-half) ] } } ret } treeMap <- :tree fun { #[(tree value) (treeMap: (tree tail) fun size: (tree value))] } tree:size:update:with <- :tree :size :idx :fun { ret <- 0 half <- size / 2 if: size = 2 { if: idx = 0 { ret <- #[(fun: (tree value)) (tree tail)] } else: { ret <- #[(tree value) (fun: (tree tail))] } } else: { if: size = 1 { ret <- #[(fun: (tree value)) 0] } else: { if: (idx < half) { ret <- #[ (tree: (tree value) size: half update: idx with: fun) (tree tail) ] } else: { ret <- #[ (tree value) (tree: (tree tail) size: size-half update: idx-half with: fun) ] } } } ret } tree:update:with <- :tree :idx :fun { #[(tree value) (tree: (tree tail) size: (tree value) update: idx with: fun)] } tree:set:to <- :tree :idx :val { tree: tree update: idx with: :el { val } } grid:get <- :grid :pos { x <- pos value y <- pos tail get: x fromTree: (get: y fromTree: grid) } grid:update:with <- :grid :pos :fun { x <- pos value y <- pos tail tree: grid update: y with: :row { tree: row update: x with: fun } } grid:set:to <- :grid :pos :val { grid: grid update: pos with: :el { val } } grid:inBounds? <- :grid :pos { x <- pos value y <- pos tail maxY <- grid value maxX <- (get: 0 fromTree: grid) value ((x >= 0) + (y >= 0) + (x < maxX) + (y < maxY)) > 0 } visited <- 0 advancer <- :continuations { notdone <- 1 while: { notdone } do: { if: (continuations isInteger?) { notdone <- 0 } else: { continuations <- fold: continuations [] with: :acc el{ ret <- acc if: notdone { ret <- el: if: (ret isInteger?) { ret <- acc } else: { if: (ret value) { notdone <- 0 ret <- (ret tail) } else: { ret <- (ret tail) | acc } } } else: {} ret } if: notdone { continuations <- flatten: continuations } else: {} } } continuations } calcPos <- :move from { x <- from value y <- from tail if: move { if: move = 1 { x <- x + 1 } else: { if: move = 2 { y <- y + 1 } else: { x <- x - 1 } } } else: { y <- y - 1 } #[x y] } makeContClos <- :grid myLoc path { { ret <- [] move <- 0 atpos <- 0 if: (grid: grid inBounds?: myLoc) { if: (grid: visited get: myLoc) { } else: { atpos <- grid: grid get: myLoc if: (atpos = 2) + (atpos = 3) + (atpos = 4) { //pellet, power pellet, fruit ret <- #[1 (reverse: path)] } else: { visited <- grid: visited set: myLoc to: 1 if: atpos { //empty space move <- 0 while: { move < 4 } do: { ret <- (makeContClos: grid (calcPos: move myLoc) move | path) | ret move <- move + 1 } ret <- #[0 ret] } else: {} } } } else: { } ret } } step <- :myState world { lmState <- (world tail) value myLoc <- (lmState tail) value ghostState <- ((world tail) tail) value fruitState <- ((world tail) tail) tail grid <- makeTree: (map: (world value) :row { if: fruitState >= 127 { } else: { row <- map: row :el { //remove fruit if it is not enabled if: el = 4 { el <- 1 } else: {} el } } makeTree: row }) grid <- fold: ghostState grid with: :acc ghost { vitality <- ghost value loc <- (ghost tail) value dir <- (ghost tail) tail nextloc <- 0 move <- 0 if: vitality = 1 { //treat fright mode ghosts as a pellet for now acc <- grid: acc set: loc to: 2 } else: { if: vitality = 0 { //treat normal mode ghosts as a wall for now acc <- grid: acc set: loc to: 0 while: { move < 4 } do: { nextloc <- calcPos: move loc if: (grid: acc inBounds?: nextloc) { acc <- grid: acc set: nextloc to: 0 } else: {} move <- move + 1 } } else: {} } acc } //make sure my location is marked clear even if there is a ghost nearby grid <- grid: grid set: myLoc to: 1 visited <- treeMap: grid :row { treeMap: row :el { 0 } } path <- advancer: [(makeContClos: grid myLoc [])] if: (path isInteger?) { print: 42 path <- [0] } else: {} #[0 (path value)] } main <- :initWorld ghostCode { /* print: (step: 0 #[ //grid [ [0 0 0 0] [0 2 2 0] [0 1 0 0] [0 0 0 0] ] //lmstate #[0 #[1 2] 2 3 0] //ghost state [] //fruit state 0 ]) */ #[0 step] } }