#include #include #include #include "world.h" using namespace std; Argument::~Argument(){} Instruction Instruction::make(ins_t op,vector args){ return {op,args}; } void Robot::load(int idx,const Script &scr){ banks[idx]=scr; } void Robot::tick(World &world){ if(active==0)return; // TODO: check whether `waited` needs to be reset waited++; Instruction ins=resolve(world); int dur=calcDuration(ins); if(duractive; else return nullptr; } else { if(arg.type==arg_t::var){ return &vars.at(arg.num-1); } else if(arg.type==arg_t::name){ assert(arg.name=="active"); return &active; } else assert(false); } } Instruction Robot::resolve(World &world){ Instruction ins=banks.at(ip.bank).at(ip.pos); cout<<"Resolving "< dstvar(ins.args.size(),false); if(ins.op==ins_t::set||ins.op==ins_t::add||ins.op==ins_t::sub){ assert(dstvar.size()>0); dstvar[0]=true; } for(size_t i=0;i(int)banks.size()&& ins.args[1].num<1&&ins.args[1].num>(int)r->banks.size()); r->banks[ins.args[1].num-1]=banks[ins.args[0].num-1]; } break; } case ins_t::jump: ip.pos+=ins.args[0].num-1; break; case ins_t::bjump: ip.bank=ins.args[0].num-1; break; case ins_t::die: case ins_t::move: case ins_t::turn: case ins_t::scan: case ins_t::create: assert(false); default: assert(false); } advanceIP(); } void Robot::advanceIP(){ ip.pos++; if(!ipInRange()){ ip.bank=ip.pos=0; assert(ipInRange()); } } bool Robot::ipInRange() const { if(ip.bank<0||ip.bank>=(int)banks.size())return false; if(ip.pos<0||ip.pos>=(int)banks[ip.bank].size())return false; return true; } World::World(){ memset(&board[0][0],0,SIZE*SIZE*sizeof(Robot*)); } World::~World(){ for(int y=0;yteam=team; board[y][x]->banks.resize(nbanks); board[y][x]->iset=iset; board[y][x]->mobile=mobile; board[y][x]->heading=rand()%4; return *board[y][x]; } void World::tick(){ for(int y=0;ytick(*this); } } } Robot* World::targetbot(const Robot *r){ for(int y=0;yheading%4){ case 0: return board[(y+SIZE-1)%SIZE][x]; case 1: return board[y][(x+1)%SIZE]; case 2: return board[(y+1)%SIZE][x]; case 3: return board[y][(x+SIZE-1)%SIZE]; } } } assert(false); } ostream& operator<<(ostream &os,const Argument &arg){ if(arg.remote){ switch(arg.type){ case arg_t::number: return os<