;;; ;;; ICFPC 2012 Simulator ;;; (define $RobotState (type {[,$val [] {[$tgt (if (eq? tgt val) {[]} {})]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [_ [Something] {[$tgt {tgt}]}] })) (define $Tile (type {[ [] {[ (if ((= RobotState) pState state) {[]} {})] [_ {}]}] [ [RobotState] {[ {state}] [_ {}]}] [ [] {[ (if (eq? pFlag flag) {[]} {})] [_ {}]}] [ [Bool] {[ {[flag]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [_ [Something] {[$tgt {tgt}]}] })) (define $show-tile (lambda [$tile] (match tile Tile {[ "R"] [ "*"] [ "#"] [ "\\"] [ "."] [ " "] [ "O"] [ "L"]}))) (define $char-to-tile (lambda [$c] (match c Char {[,'R' >] [,'*' ] [,'#' ] [,'\\' ] [,'.' ] [,' ' ] [,'O' ] [,'L' ] }))) (define $Mine (Array Tile)) (define $Move (type {[ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [ [] {[ {[]}] [_ {}]}] [_ [Something] {[$tgt {tgt}]}] })) (define $char-to-move (lambda [$c] (match c Char {[,'L' ] [,'R' ] [,'U' ] [,'D' ] [,'W' ] [,'A' ] [,'h' ] [,'l' ] [,'k' ] [,'j' ] }))) (define $Point [Integer Integer]) (define $GameState (type {[ [Mine Integer Integer Integer] {[ {[mine step score lambda-count]}]}] [_ [Something] {[$tgt {tgt}]}] })) (define $get-mine (lambda [$game-state] (match game-state GameState {[ mine]}))) (define $show-mine (lambda [$mine] (let {[$kss (keys-for-display (array-range mine))]} (foldl string-append "" (map (lambda [$ks] (string-append (foldl string-append "" (map (lambda [$k] (show-tile (array-ref k mine))) ks)) "\n")) kss))))) (define $get-robot-state (lambda [$mine] (let {[$rp ((find-from-value-with-pattern Tile) mine)]} (match (array-ref rp mine) Tile {[ state]})))) (define $move-robot (lambda [$mine $move] (generate-array (lambda [$x $y] (match move Move {[ (match mine Mine { [ _>> ] [ _>> >] [ _>> ] [ _>> >] [ (| ^ ) _> _>>)> ] [ (| ^ ) _> _>>)> >] [ _>>> ] [ _> >] [ tile]})] [ (match mine Mine { [ _>> ] [ _>> >] [ _>> ] [ _>> >] [ (| ^ ) _> _>>)> ] [ (| ^ ) _> _>>)> >] [ _>>> ] [ _> >] [ tile]})] [ (match mine Mine { [ _>> ] [ _>> >] [ _>> ] [ _>> >] [ ^ ) _>> ] [ ^ ) _>> >] [ _> >] [ tile]})] [ (match mine Mine { [ _>> ] [ _>> >] [ _>> ] [ _>> >] [ ^ ) _>> ] [ ^ ) _>> >] [ _> >] [ tile]})] [ (match mine Mine {[ _> >] [ tile]})] [ (match mine Mine {[ _> >] [ tile]})] })) (array-range mine)))) (define $update-map (lambda [$mine] (generate-array (lambda [$x $y] (match mine Mine {[ _>> ] [ _>> ] [ ) _>>>> ] [ ) _>>>> ] [ (& (| _> _>) _>>)>> ] [ (& (| _> _>) _>>)>> ] [ _> (if (eq? 0 (size (lambda-stones mine))) )] [ _> ] [ tile] })) (array-range mine)))) (define $lambda-stones (lambda [$mine] (concat (map (lambda [$x $y] (match mine Mine {[ _> {[x y]}] [_ {}]})) (array-keys mine))))) (define $ending-update (lambda [$mine] (generate-array (lambda [$x $y] (match mine Mine {[> _>> >] [ tile] })) (array-range mine)))) (define $ending? (lambda [$mine] (match (get-robot-state mine) RobotState {[(| ) #t] [_ #f]}))) (define $calc-score (lambda [$game-state] (match game-state GameState {[ (match (get-robot-state mine) RobotState {[ (+ score (* 25 lambda-count))] [ score] [ 0]})]}))) (define $generate-mine (lambda [$lines] (do {[$tss (map (lambda [$line] (map char-to-tile (string-to-chars line))) (reverse lines))] [$mx (max (map size tss))] [$my (size tss)] [$tss2 (map (lambda [$cs] {@cs @(loop $l $i (between 1 (- mx (size cs))) { @l} {})}) tss)] } (letrec {[$rotate (lambda [$tss] (match (car tss) (List Something) {[ {}] [_ {(map car tss) @(rotate (map cdr tss))}]}))]} (let {[$tss3 (rotate tss2)]} (generate-array (lambda [$x $y] (nth y (nth x tss3))) [mx my])))))) (define $main (lambda [$: $argv] (match argv (List String) {[> (do {[[$: $port] (open-input-file : file)] } (letrec {[$readMapLoop (lambda [$: $lines] (do {[[$: $line] (read-line-from-port : port)]} (if (or (eof? line) (eq-s? line "")) [: lines] (readMapLoop : {@lines line}))))] } (do {[[$: $lines] (readMapLoop : {})] [$init-mine (generate-mine lines)] [$init-state ]} (letrec {[$interactive (lambda [$: $game-state] (match game-state GameState {[ (do { [$: (write-string : (show-mine mine))] [$: (write-char : '\n')] [$: (write-string : "robot-state: ")] [$: (write : (get-robot-state mine))] [$: (write-char : '\n')] [$: (write-string : "lambda-count: ")] [$: (write : lambda-count)] [$: (write-char : '\n')] [$: (write-string : "score: ")] [$: (write : score)] [$: (write-char : '\n')] [$: (write-string : "command: ")] [$: (flush :)] [[$: $cmd] (read-char :)] [$: (write-char : '\n')] [$: (flush :)] [$move (char-to-move cmd)] [$mine2 (ending-update (update-map (move-robot mine move)))] [$game-state2 (get-robot-state mine2)) (- (+ 50 score) 1) (- score 1)) (if ((= RobotState) (get-robot-state mine2)) (+ 1 lambda-count) lambda-count) >] } (if (ending? mine2) (do { [$: (write-string : (show-mine mine2))] [$: (write-char : '\n')] [$: (write-string : "robot-state: ")] [$: (write : (get-robot-state mine2))] [$: (write-char : '\n')] [$: (write-string : "score: ")] [$: (write : (calc-score game-state2))] [$: (write-char : '\n')] } :) (interactive : game-state2)))]}))]} (interactive : init-state)))))] [_ (do { [$: (write-string : "usage: mine FILENAME (specify map file)\n")] } :)]})))