131 lines
3.0 KiB
C++
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;
|
|
}
|