aboutsummaryrefslogtreecommitdiff
path: root/randino.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'randino.cpp')
-rw-r--r--randino.cpp169
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;
+}