Dylan:
define function parsetelemetry (string :: <string>) => (world :: <world>)
let strings = split(string, ' ');
let index :: <integer> = 1;
let stat = make(<stretchyvector>);
let mov = make(<stretchyvector>);
//let mov = make(limited(<stretchyvector>, of: <worldobject>));
local method parsef () => (float :: <fp>)
let f = stringtofloat(strings[index]);
index := index + 1;
as(<fp>, f);
end;
local method parseobj () => ()
let f = strings[index][0];
index := index + 1;
if (f == 'b')
add!(stat, make(<boulder>,
x: parsef(),
y: parsef(),
radius: parsef()));
elseif (f == 'c')
add!(stat, make(<crater>,
x: parsef(),
y: parsef(),
radius: parsef()));
elseif (f == 'h') // and drop
make(<homebase>,
x: parsef(),
y: parsef(),
radius: parsef());
elseif (f == 'm')
add!(mov, make(<martian>,
x: parsef(),
y: parsef(),
direction: parsef().degreetoradian,
speed: parsef()));
end;
end;
local method parsectl () => (acc :: <symbol>, turn :: <symbol>)
let acc = strings[index][0];
let tur = strings[index][1];
let a = if (acc == 'a')
#"accelerating"
elseif (acc = 'b')
#"braking"
elseif (acc = '-')
#"rolling"
end;
let t = if (tur == 'L')
#"hard-left"
elseif (tur == 'l')
#"left"
elseif (tur == '-')
#"straight"
elseif (tur == 'r')
#"right"
elseif (tur == 'R')
#"hard-right"
end;
index := index + 1;
values(a, t);
end;
let ts = parsef() / 1000.0s0;
let (acc, tur) = parsectl();
let rov = make(<rover>,
accelerationstate: acc,
turningstate: tur,
x: parsef(),
y: parsef(),
direction: parsef().degreetoradian,
speed: parsef());
while (index < strings.size 1)
parseobj();
end;
telemetry :: Parser Message
telemetry = do ts <- int
state <- accelStateParser
turning <- turningStateParser
spaces
x <- double
y <- double
dir <- double
speed <- double
obstacles <- obstaclesParser
messageEnd
return $ Telemetry ts state turning x y dir speed obstacles
accelStateParser :: Parser AccelState
accelStateParser = (accelerating <|> braking <|> rolling)
accelerating = stateParser 'a' Accelerating
braking = stateParser 'b' Braking
rolling = stateParser '-' Rolling
stateParser :: Char -> a -> Parser a
stateParser c cons = do _ <- char c
return cons
turningStateParser :: Parser TurningState
turningStateParser = hardleft <|> softleft
<|> hardright <|> softright
<|> straight
hardleft = stateParser 'L' HardLeft
softleft = stateParser 'l' SoftLeft
hardright = stateParser 'R' HardRight
softright = stateParser 'r' SoftRight
straight = stateParser '-' Straight
obstaclesParser :: Parser [Object]
obstaclesParser = do l <- many obstacleParser
return l
obstacleParser :: Parser Object
obstacleParser = do code <- oneOf "bchm"
spaces
case code of
'b' -> object Boulder
'c' -> object Crater
'h' -> object Home
'm' -> martian
_ -> error "Can't get here in parser!"
object :: (Circle -> a) -> Parser a
object cons = do x <- double
y <- double
r <- double
spaces
return $ cons (Circle (x:.y) r)
martian :: Parser Object
martian = do x <- double
y <- double
dir <- double
speed <- double
spaces
return $ Martian (Circle (x:.y) 0.4) dir speed