icfp15/main.cpp

131 lines
3.0 KiB
C++

#include "io.h"
#include "mine.h"
#include <iostream>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void runMoves(Mine &m, const char *moves) {
while (*moves) {
// m.show(std::cout);
// std::cout << *moves << "\n";
switch(*moves++) {
case 'L': m.move(Mine::Left); break;
case 'R': m.move(Mine::Right); break;
case 'U': m.move(Mine::Up); break;
case 'D': m.move(Mine::Down); break;
case 'W': m.move(Mine::Wait); break;
case 'A': m.move(Mine::Abort); break;
default: break;
}
}
}
void simulate(Mine &m, const char *moves) {
runMoves(m, moves);
m.show(std::cout);
}
void run_testcase(std::vector<unsigned char> &buf) {
Mine m(buf);
char *sbuf = (char*) &buf.at(0);
sbuf = strchr(sbuf, '!');
if (!sbuf) {
std::cerr << "Not a testcase, missing '!'\n";
exit(1);
}
char *moves = sbuf+1;
char *score = strchr(moves, '\n');
char *state = 0;
if (score) {
if (score[-1] == '\r') score[-1] = '\0';
*score++ = '\0';
state = strchr(score, '\n');
if (state) {
if (state[-1] == '\r') state[-1] = '\0';
*state++ = '\0';
sbuf = strchr(state, '\n');
if (sbuf) {
// remove trailing newline
if (sbuf[-1] == '\r') sbuf[-1] = '\0';
*sbuf++ = '\0';
}
}
}
runMoves(m, moves);
m.show(std::cout);
if (score) {
int n = atoi(score);
if (n != m.score()) {
std::cerr << "Testcase score missmatch: expected " << n << "\n";
exit(10);
}
}
if (state) {
if (0 == strcasecmp(state, "Win")) {
if (m.state() != Mine::Won) {
std::cerr << "Testcase result missmatch: expected to win\n";
exit(10);
}
} else if (0 == strcasecmp(state, "Alive")) {
if (m.state() != Mine::Alive) {
std::cerr << "Testcase result missmatch: expected to be still mining\n";
exit(10);
}
} else if (0 == strcasecmp(state, "Aborted")) {
if (m.state() != Mine::Alive && m.state() != Mine::Aborted) {
std::cerr << "Testcase result missmatch: expected to abort (alive counts too)\n";
exit(10);
}
} else if (0 == strcasecmp(state, "Broken")) {
if (m.state() != Mine::Lost) {
std::cerr << "Testcase result missmatch: expected to break robot\n";
exit(10);
}
} else {
std::cerr << "Unknown expected testcase result '" << state << "'\n";
exit(1);
}
}
}
int main(int argc, char **argv) {
if (argc == 3) {
// simulate: [file] [moves]
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
std::cerr << "opening map '" << argv[1] << "' failed\n";
exit(1);
}
std::vector<unsigned char> buf;
readAll(fd, buf);
close(fd);
Mine m(buf);
buf.clear();
simulate(m, argv[2]);
} else if (argc == 2) {
// simulate: [file with !moves on bottom]
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
std::cerr << "opening map '" << argv[1] << "' failed\n";
exit(1);
}
std::vector<unsigned char> buf;
readAll(fd, buf);
close(fd);
run_testcase(buf);
} else {
// solve puzzle, read map from stdin
std::cerr << "Solving not implemented yet\n";
exit(1);
}
return 0;
}