diff options
Diffstat (limited to 'randino.cpp')
-rw-r--r-- | randino.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/randino.cpp b/randino.cpp new file mode 100644 index 0000000..e9b5abb --- /dev/null +++ b/randino.cpp @@ -0,0 +1,169 @@ +#include <iostream> +#include <fstream> +#include <sstream> +#include <vector> +#include <sys/time.h> + +#define S (5) + +using namespace std; + +int index_deltas[8][2]={{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}}; + +class Move{ +public: + int neudir,from,dir; + string str(void){ + stringstream ss; + ss<<neudir<<' '<<from<<' '<<dir; + return ss.str(); + } +}; + +class Board{ +public: + int grid[S*S]; + int neuidx; + Board(void):neuidx(0){ + memset(grid,0,S*S*sizeof(int)); + grid[S*(S/2)+S/2]=3; + for(int i=0;i<S;i++){ + grid[i]=1; + grid[S*(S-1)+i]=2; + } + } + int moved(int at,int dir){ + int x=at%S,y=at/S,x2,y2; + while(true){ + x2=x+index_deltas[dir][0]; + y2=y+index_deltas[dir][1]; + if(x2<0||x2>=S||y2<0||y2>=S||grid[S*y2+x2]!=0)return S*y+x; + x=x2; + y=y2; + } + } + bool move(int at,int dir){ + int newat=moved(at,dir); + if(newat==at)return false; + grid[newat]=grid[at]; + grid[at]=0; + if(grid[newat]==3)neuidx=newat; + return true; + } + void undomove(int at,int dir){ + int movedidx=moved(at,dir); + movedidx+=S*index_deltas[dir][1]+index_deltas[dir][0]; + grid[at]=grid[movedidx]; + grid[movedidx]=0; + if(grid[at]==3)neuidx=at; + } + bool isvalid(Move mv){ + int oldneuidx=neuidx; + if(!move(oldneuidx,mv.neudir)){ + undomove(oldneuidx,mv.neudir); + return false; + } + if(!move(mv.from,mv.dir)){ + undomove(mv.from,mv.dir); + undomove(oldneuidx,mv.neudir); + return false; + } + undomove(mv.from,mv.dir); + undomove(oldneuidx,mv.neudir); + return true; + } +}; + + +Move calculate_move(Board &bd){ + vector<Move> poss; + Move m; + int nd,fr,d; + int newneu,newidx; + for(nd=0;nd<8;nd++){ + newneu=bd.moved(bd.neuidx,nd); + if(newneu==bd.neuidx)continue; + for(fr=0;fr<S*S;fr++){ + if(bd.grid[fr]!=1)continue; + for(d=0;d<8;d++){ + newidx=bd.moved(fr,d); + if(newidx==fr)continue; + m.neudir=nd; + m.from=fr; + m.dir=d; + poss.push_back(m); + } + } + } + return poss[rand()%poss.size()]; +} + + +bool should_flip_board=false; + +inline int flip_index(int idx){ + return S*(S-1-idx/S)+S-1-idx%S; +} +inline int flip_dir(int dir){ + return (dir+4)%8; +} + +Move protocol_get_move(void){ + Move m; + cin>>m.neudir>>m.from>>m.dir; + if(should_flip_board){ + m.from=flip_index(m.from); + m.dir=flip_dir(m.dir); + } + return m; +} + +void protocol_put_move(Move m){ + if(should_flip_board){ + cout<<m.neudir<<' '<<flip_index(m.from)<<' '<<flip_dir(m.dir)<<endl; + } else { + cout<<m.neudir<<' '<<m.from<<' '<<m.dir<<endl; + } +} + +int main(void){ + Board bd; + Move mv; + string line; + struct timeval tv; + gettimeofday(&tv,NULL); + cerr<<"seed="<<(1000000*tv.tv_sec+tv.tv_usec)<<endl; + srand(1000000*tv.tv_sec+tv.tv_usec); + getline(cin,line); + if(line=="go"){ + should_flip_board=false; + mv.neudir=-1; mv.from=0; mv.dir=4; + protocol_put_move(mv); + } else { + if(line!="nogo")cerr<<"no0b "<<line<<" not in (go,nogo)"<<endl; + should_flip_board=true; + mv=protocol_get_move(); + bd.move(mv.from,mv.dir); + mv=calculate_move(bd); + if(!bd.isvalid(mv)){ + cerr<<"calculate_move gave invalid move "<<mv.str()<<endl; + return 1; + } + bd.move(bd.neuidx,mv.neudir); + bd.move(mv.from,mv.dir); + protocol_put_move(mv); + } + while(true){ + mv=protocol_get_move(); + bd.move(mv.from,mv.dir); + mv=calculate_move(bd); + if(!bd.isvalid(mv)){ + cerr<<"calculate_move gave invalid move "<<mv.str()<<endl; + return 1; + } + bd.move(bd.neuidx,mv.neudir); + bd.move(mv.from,mv.dir); + protocol_put_move(mv); + } + return 0; +} |