aboutsummaryrefslogtreecommitdiff
path: root/sim.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sim.cpp')
-rw-r--r--sim.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/sim.cpp b/sim.cpp
new file mode 100644
index 0000000..e1e94f8
--- /dev/null
+++ b/sim.cpp
@@ -0,0 +1,149 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include <unistd.h>
+#include <cstdlib>
+#include <cassert>
+#include <sys/time.h>
+#include <cstring>
+
+#include "params.h"
+#include "world.h"
+#include "parse.h"
+
+#ifndef _WIN32
+# include <signal.h>
+#endif
+
+using namespace std;
+
+
+static ScreenBuffer *sb;
+
+#ifndef _WIN32
+static void signalHandler(int sig){
+ if(sig==SIGINT){
+ sb->emergencyDeinit();
+ _exit(130);
+ }
+}
+#endif
+
+
+struct RobotSpec{
+ string fname;
+ bool random;
+ int x,y,heading;
+};
+
+int parseInt(const char *str){
+ char *endp;
+ int v=strtol(str,&endp,10);
+ if(str[0]=='\0'||*endp!='\0'){
+ cerr<<"Invalid number '"<<str<<"'"<<endl;
+ exit(1);
+ }
+ return v;
+}
+
+void usage(char **argv){
+ cerr<<"Usage: "<<argv[0]<<" [-r <fname>]* [-p <fname> <x> <y> <heading>]* [-s <sleeptime>] [-t]"<<endl;
+}
+
+int main(int argc,char **argv){
+ struct timeval tv;
+ gettimeofday(&tv,nullptr);
+ srand(tv.tv_sec*1000000+tv.tv_usec);
+
+ World world;
+ vector<Team> teams;
+
+ vector<RobotSpec> robotSpecs;
+ int sleeptime=3000;
+ bool step = false;
+
+ if(argc<=1){
+ usage(argv);
+ return 1;
+ }
+
+ for(int i=1;i<argc;i++){
+ if(argv[i][0]!='-'||strlen(argv[i])!=2){
+ cerr<<"Unexpected argument '"<<argv[i]<<"'"<<endl;
+ return 1;
+ }
+ switch(argv[i][1]){
+ case 'h':
+ usage(argv);
+ return 0;
+
+ case 'r':
+ if(i>=argc-1){
+ cerr<<"Expected file name after '-r'"<<endl;
+ return 1;
+ }
+ robotSpecs.push_back({argv[i+1],true,0,0,0});
+ i+=1;
+ break;
+
+ case 'p':
+ if(i>=argc-4){
+ cerr<<"Expected file name, x, y and heading after '-p'"<<endl;
+ return 1;
+ }
+ robotSpecs.push_back({argv[i+1],false,parseInt(argv[i+2]),parseInt(argv[i+3]),parseInt(argv[i+4])});
+ i+=4;
+ break;
+
+ case 's':
+ if(i>=argc-1){
+ cerr<<"Expected sleep time after '-s'"<<endl;
+ return 1;
+ }
+ sleeptime=parseInt(argv[i+1]);
+ i+=1;
+ break;
+
+ case 't':
+ step = true;
+ break;
+
+ default:
+ cerr<<"Unknown switch in '"<<argv[i]<<"'"<<endl;
+ return 1;
+ }
+ }
+
+ for(const RobotSpec &rs : robotSpecs){
+ ifstream f(rs.fname);
+ if(!f){
+ cerr<<"Cannot open file '"<<rs.fname<<"'"<<endl;
+ return 1;
+ }
+ teams.push_back(assemble(preprocess(f)));
+ Team &t=teams.back();
+ Robot &r=rs.random ? world.create(&t,2,t.banks.size(),false)
+ : world.create(&t,2,t.banks.size(),false,rs.x,rs.y,rs.heading);
+ for(int i=0;i<(int)t.banks.size();i++){
+ r.load(i,t.banks[i]);
+ r.active=1;
+ }
+ }
+
+ sb=new ScreenBuffer(SIZE*3, SIZE+1);
+#ifndef _WIN32
+ signal(SIGINT,signalHandler);
+#endif
+ world.print(*sb);
+ sb->draw();
+ for(int i=0;i<C::autoTimeout;i++){
+ if(step) cin.get();
+ else usleep(sleeptime);
+ world.tick();
+ world.print(*sb);
+ sb->mvprintf(0, SIZE, "step: %5i", i+2);
+ sb->draw();
+ }
+ delete sb;
+}