/*
 * Copyright 1996 by Michel D. Grimminck
 *
 * All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <stdio.h>
#include "functions.h"
#include <string.h>
#include <time.h>
#include <math.h>
#include "var.h"
#include <signal.h>

extern int abc_1,abc_2;

#ifdef RIP
#define N 10316
int brother[N],child[N];
unsigned char move[N][2];
int path[100];

void rip(int q,int l)
{
  int i,b;
  if (move[q][0]==0 || q==1) {
    for(i=0;i<l;i++) {
      if (i%8==0) printf("\n");
      if (i%2==0) printf("%i. ",i/2+1);
      printf("%i-%i ",move[path[i]][0],move[path[i]][1]);
      
    }
    printf("* \n");
    return;
  }
  /* for me and all my brothers: rip */
  b=q;
  do {
    path[l]=b;
    rip(child[b]+1,l+1);
    b=brother[b]+1;
  } while(b!=1);
  return;
}

void rip_opening(void)
{
  int i,j;
  FILE *in;
  in=fopen("/dos/games/dammen/dam.opn","r");
  
  for(i=0;i<6*N;i+=6) {
    int x[6],j,n1,n2;
    for(j=0;j<6;j++) x[j]=fgetc(in);
    /*printf("%i   ",i/6);*/
    n1=x[0]+256*x[1]; n2=x[2]+256*x[3];
    /*printf("%6i(%i) %6i(%i) %3i %3i",n1/3,n1%3,n2/3,n2%3,x[5],x[4]);*/
    brother[i/6]=n1/3; child[i/6]=n2/3;
    /*printf("%i %i\n",i/6,brother[i/6]);*/
    move[i/6][0]=x[5]; move[i/6][1]=x[4];
    /*printf("\n");*/
  }
  fclose(in);
  rip(2,0);
}
#endif

#ifdef WIEGER
void read_wieger(void)
{
  FILE *in,*out;
  char buffer[500][3][200],filename[200];
  int i,j;

  in=fopen("test/wieger","r");
  if (in==NULL) {
    printf("wieger error\n");
    return;
  }
  init_board();
  for(i=0;i<490;i++) {
    fgets(buffer[i][0],200,in);
    fgets(buffer[i][1],200,in);
    fgets(buffer[i][2],200,in);
    for(j=0;j<50;j++) {
      if (buffer[i][0][j]=='.') board[map[j]]=empty;
      if (buffer[i][0][j]=='w') board[map[j]]=white|man;
      if (buffer[i][0][j]=='z') board[map[j]]=black|man;
      if (buffer[i][0][j]=='W') board[map[j]]=white|crown;
      if (buffer[i][0][j]=='Z') board[map[j]]=black|crown;
    }
    printf("%i\n",i);
    display_board();
    printf("%s\n%s\n",buffer[i][1],buffer[i][2]);
    sprintf(filename,"wieger/%.3i",i);
    save_board(2,filename);
    out=fopen(filename,"a");
    if (out==NULL) {printf("append error %i\n",i); continue;}
    fprintf(out,"%s\n%s\n",buffer[i][1],buffer[i][2]);
    fclose(out);
  }
  fclose(in);
}
#endif

void stopprogram(int sig)
{
  char a[10];

  printf("\nReally quit? "); fflush(stdout);
  scanf("%s",a);
  if (a[0]=='y' || a[0]=='Y') exit(0);
}

int main(int argc,char* argv[])
{
    int i;
    int in1,in2;
    char input[1024],buffer[100];
    int alfa=-INF,beta=INF,fitdepth=-999;
    int asa=false,dbssize=0;
    FILE *in;
    int my_color=black;
    extern int bytesize[4096],npattree,npat;

    printf("%s\n",VERSION);
    init_var();
    init_databases();
    read_all_databases();
    init_patterns();
    init_board();
    set_position(parameters[13],parameters[14]);
    init_stats();
    init_tables();
    init_tpat();
#ifdef RIP
    rip_opening();
#endif
#ifdef WIEGER
    read_wieger();
#endif
    
    for(i=0;i<4096;i++) if (database[i]!=NULL) dbssize+=bytesize[i]; 
    printf("hashtables:%.1f Mb\n",(float) tablesize*sizeof(transpos[0])/1024/1024);
    printf("evaltables:%.1f Mb\n",(float) MAXEVAL*sizeof(evalcache[0])/1024/1024);
    printf("patterns:%.1f Mb\n",(float) (npattree*28+npat*sizeof(tpat[0]))/1024/1024);
    printf("databases:%.1f Mb\n",(float) dbssize/1024/1024);
    for(i=1;i<16;i++) printf("%i ",param_a[i]); printf("\n");
    for(i=1;i<16;i++) printf("%i ",param_b[i]); printf("\n");
    for(i=1;i<16;i++) printf("%i ",param_c[i]); printf("\n");
    i=1;
    while(i<argc) {
        if (strcmp(argv[i],"-in")==0) {
            load_board(argv[++i]);
	    init_stats();
            }
        if (strcmp(argv[i],"-ref")==0) {
	  int score;
	  sscanf(argv[++i],"%s",pdnfile);
	  parameters[0]=-2;
	  search_min=0;
	  search_max=40;
	  perc=1;
	  score=check_database(pdnfile,search_min,search_max);
	  printf("score:%i\n",score);
	}
        if (strcmp(argv[i],"-cbook")==0) {
	    int sizes[NTABLE],j;
            sscanf(argv[++i],"%s",pdnfile);
	    for(j=0;j<NTABLE;j++) sscanf(argv[++i],"%i",sizes[i]);
            parameters[0]=-3;
            search_min=0;
            search_max=40;
            perc=1;
            }
        if (strcmp(argv[i],"-pdn")==0) {
            sscanf(argv[++i],"%s",pdnfile);
            sscanf(argv[++i],"%i",&fitdepth);
            sscanf(argv[++i],"%i",&search_min);
            sscanf(argv[++i],"%i",&search_max);
            sscanf(argv[++i],"%f",&perc);
            parameters[0]=fitdepth;
	    if (asa==false) {
	      int score;
	      score=check_database(pdnfile,search_min,search_max);
	      printf("score:%i\n",score);
	    }
	    if (asa==true) {
	      parameters[0]=fitdepth;
	      /*asa_main();*/
	    }
	  }
        if  (strcmp(argv[i],"-asa")==0) {
            asa=true;
            }
	if  (strcmp(argv[i],"-asa")==0) {
	    char name[256];
	    sscanf(argv[++i],"%i",name);
            save_board(white,name);
            }
        if  (strcmp(argv[i],"-x")==0) {
            /*Xboard(1,argv)*/;
            }
        if  (strcmp(argv[i],"-v")==0) {
            printf("%s\n",VERSION);
	    exit(0);
            }
	if  (strcmp(argv[i],"-dir")==0) {
	    sscanf(argv[++i],"%i",workdir);
            }
        if  (strcmp(argv[i],"-nocolor")==0) {
            usecol=false;
            }
        if  (strcmp(argv[i],"-xv")==0) {
            usexv=true;
	    save_board(white,"/tmp/board");
	    system("dtp -in /tmp/board -out /tmp/board.ppm");
	    system("xv -wloop -wait 10 /tmp/board.ppm &");
            }
        if (strcmp(argv[i],"-evaltype")==0) {
            sscanf(argv[++i],"%i",&eval_type);
            }
        if (strcmp(argv[i],"-mycolor")==0) {
            sscanf(argv[++i],"%i",&my_color);
            }
        if (strcmp(argv[i],"-settime")==0) {
            sscanf(argv[++i],"%f",&time_left[0]);
	    time_left[1]=time_left[0];
	    time_reserve=0.05*time_left[0];
            }
        if (strcmp(argv[i],"-mailplay")==0) {
            mailplay(argv[i+1]);
            }
        if (strcmp(argv[i],"-quit")==0) {
            exit(0);
            }
        i++;
        }
    display_board();
    do {
        signal(SIGINT,stopprogram);
        /*fflush(stdout);*/
	printf("dragon> ");
	/*fflush(stdout);*/
        scanf("%s",input);
	signal(SIGINT,SIG_DFL);
        if (input[0]=='!') system(&input[1]);
        else if (strcmp(input,"pn")==0) {
            int target;
            scanf("%i%i%i",&in1,&in2,&target);

            init_stats();
            do_pn_search(in1,in2,target,1);
            print_stats();
            print_pv();
            }
        else if (strcmp(input,"pn2")==0) {
            int target;
            scanf("%i%i%i",&in1,&in2,&target);

            init_stats();
            do_pn_search(in1,in2,target,2);
            print_stats();
            print_pv();
            }
        else if (strcmp(input,"load")==0 || strcmp(input,"get")==0) {
            scanf("%s",buffer);
            load_board(buffer);
	    init_stats();
            display_board();
            game_history_nr=0;
            }
        else if (strcmp(input,"initboard")==0) {
            init_board();
            display_board();
            game_history_nr=0;
            }
        else if (strcmp(input,"eval")==0) {
            scanf("%i",&in1);
	    set_eval();
            printf("score:%i\n",evalboard(in1,-INF,INF));
            }
        else if (strcmp(input,"mobil")==0) {
	    int act,block;
	    set_eval();
            printf("moves:%i\n",mobility_w(board,&act,&block));
	    printf("active:%i\n",act);
	    printf("blocked:%i\n",block);
            }
	else if (strcmp(input,"oneman")==0) {
            scanf("%i",&in1);
            printf("score:%i\n",one_man(in1));
            }
	else if (strcmp(input,"tablestats")==0) {
            tablestats();
            }
	else if (strcmp(input,"savetables")==0) {
            save_tables();
            }
	else if (strcmp(input,"make_pat_tree")==0) {
            make_pat_tree();
            }
	else if (strcmp(input,"save_pat_tree")==0) {
            save_pat_tree();
            }
	else if (strcmp(input,"load_pat_tree")==0) {
            load_pat_tree();
            }
	else if (strcmp(input,"make_bin_book")==0) {
            make_bin_book();
            }
        else if (strcmp(input,"history")==0) {
            scanf("%i",&in1);
            show_history(in1);
            }
        else if (strcmp(input,"index")==0) {
            scanf("%i",&in1);
            database_linear_index(in1);
            }
        else if (strcmp(input,"maxpv")==0) {
            scanf("%i",&in1);
            if (maxpv>0) maxpv=in1;
	    if (maxpv>MPV) maxpv=MPV;
	    printf("mpv set to %i\n",maxpv);
            }
	else if (strcmp(input,"saveboard")==0) {
	    char name[100];
            scanf("%i %s",&in1,name);
            save_board(in1,name);
            }
        else if (strcmp(input,"write_pdn")==0) {
            char file[256];
            scanf("%s",file);
	    printf("whiteplayer:");
	    scanf("%s",pdn_info.whitepl);
	    printf("blackplayer:");
	    scanf("%s",pdn_info.blackpl);
	    printf("result:");
	    scanf("%s",pdn_info.result);
            write_pdn(file);
            }
	else if (strcmp(input,"reverse")==0) {
	  BTYPE temp[93];
	  copy_board(temp,board);
	  reverse_board(board,temp);
	  display_board();
	}
        else if (strcmp(input,"control")==0) {
            scanf("%i",&in1);
            printf("score:%i\n",field_control(in1));
            }
        else if (strcmp(input,"patternstats")==0) {
            printf("score:%i\n",print_pattern_stats());
            }
        else if (strcmp(input,"patternsave")==0) {
            save_pattern_stats();
            }
        else if (strcmp(input,"patternload")==0) {
            load_pattern_stats();
            }
        else if (strcmp(input,"pattern")==0) {
            /*scanf("%i",&in1);*/
            printf("score:%i\n",handle_pattern(0,board,0));
            }
        else if (strcmp(input,"seed")==0) {
            scanf("%i",&in1);
            srand(in1);
            }
        else if (strcmp(input,"alfa")==0) {
            scanf("%i",&alfa);
            }
        else if (strcmp(input,"beta")==0) {
            scanf("%i",&beta);
            }
        else if (strcmp(input,"stats")==0) {
            print_stats();
            }
        else if (strcmp(input,"bd")==0) {
            display_board();
            }
        else if (strcmp(input,"back")==0) {
            take_back(1);
            }
        else if (strcmp(input,"movescore")==0) {
            int i,n;

            n=move_list(0,0);
            for(i=0;i<n;i++) {
                print_move(movescore[i].move);
                printf(": %i\n",movescore[i].value);
                }
            }
        else if (strcmp(input,"dopv")==0) {
            scanf("%i",&in1);
            xstore_history(PV[0][in1],"pv");
	    do_move(PV[0][in1]);
            display_board();
            }
        else if (strcmp(input,"mback")==0) {
            scanf("%i",&in1);
            take_back(in1);
	    }
        else if (strcmp(input,"followpv")==0) {
            scanf("%i",&in1);
	    for(i=0;i<in1;i++) {
	      xstore_history(PV[0][i],"pv");
	      do_move(PV[0][i]);
	      }
            display_board();
	    }
        else if (strcmp(input,"plearn")==0) {
            scanf("%i",&in1);
	    plearn(white,in1);
            }
	else if (strcmp(input,"plearn_test")==0) {
	    int i,ok;
	    char filename[256];
	    for(i=0;i<490;i++) {
	      sprintf(filename,"wieger/%.3i",i);
	      ok=load_board(filename);
	      if (ok==false) {
		printf("pattern not found\n");
		break;
	      }
	      plearn(white,800);
	    }
	  }
        else if (strcmp(input,"psave")==0) {
	    save_tpat();
            }
        else if (strcmp(input,"pstats")==0) {
	    tpat_stats();
            }
        else if (strcmp(input,"show_test")==0) {
            double s_e2,s_t2;
            s_e2=(test_e2-test_e*test_e/test_nr)/(test_nr-1)/test_nr;
            s_t2=(test_t2-test_t*test_t/test_nr)/(test_nr-1)/test_nr;
	   
            printf("%.0lf test done, av. eval=%.0lf, av. time=%.2lf (%.2lf)\n",
                   test_nr,test_e/test_nr,test_t/test_nr);
            }
        else if (strcmp(input,"ab")==0) {
            int score,t,d;
            double cl;
            scanf("%i%i",&in1,&in2);
            init_stats(); set_eval();
                t=-clock();
                init_hash();
	        for(d=0;d<=in2;d+=100) score=alfabeta(alfa,beta,in1,0,d,0);
                t+=clock();
                cl=(double) t/CLOCKS_PER_SEC;
                print_pv();
                print_stats();
                test_e+=neval; test_e2+=neval*neval;
                test_t+=cl; test_t2+=cl*cl;
                test_nr+=1;
                printf("score:%.3f time:%.2f\n",score/1000.0F,(float) t/CLOCKS_PER_SEC);
                }
        else if (strcmp(input,"?")==0) {
            int n;
            n=move_list(0,0);
            printf("White: "); print_movelist(0,n);
            n=move_list(0,1);
            printf("Black: "); print_movelist(0,n);
            }
        else if (strcmp(input,"go")==0) {
            scanf("%i %i",&in1,&in2);
	    if (in1==0 || in1==1) play(in1,in2,9);
	    else printf("error\n");
            display_board();
            }
	else if (strcmp(input,"auto")==0) {
	    int exact,mat;
	    scanf("%i %i",&in1,&in2);
	    do {
	      mat=xmaterial(in1,&exact);
	      if (exact==true) {
		printf("game ended, score:%i\n",mat);
		break;
	      }
	      play(in1,in2,9);
	      display_board();
	      in1=1-in1;
	    } while(1==1);
	  }
	    
	else if (strcmp(input,"makef")==0) {
	    int i;
	    for(i=0;i<50;i++) printf("#define F%i %i\n",i+1,map[i]);
	  }
	else if (strcmp(input,"white")==0) {
	    my_color=white;
	  }
	else if (strcmp(input,"black")==0) {
	    my_color=black;
	  }
        else if (strcmp(input,"play")==0) {
	    float at;
	    int nmoves;
	    time_t start,end;
	    
	    scanf("%i-%i",&in1,&in2);
	    if (in1!=0 || in2!=0) {
	      if (try_move(game_history_nr%2,in1,in2)==true) goto play_error;
	      display_board();
	    }
	    if (game_history_nr%2!=my_color) {
	      printf("Its not my turn\n");
	      goto play_error;
	    }
	    printf("white timeleft:%.2f  black timeleft:%.2f\n",time_left[white],time_left[black]);
	    at=alloc_time(my_color);
	    printf("allocated time:%.2f\n",at);

	    time(&start);
            play(my_color,at,9);
            display_board();
  	    time(&end);

	    time_left[my_color]-=difftime(end,start)+operator_time;
	    printf("actual time used:%.2f\n",difftime(end,start));
	    if (game_history_nr%10==0) {
	      printf("please update timers with 'timecommand'\n");
	    }
	    do {
	      nmoves=move_list(0,game_history_nr%2);
	      if (nmoves==1) {
		printf("forced move:");
		print_move(movelist[0][0]);
		printf("\n");
		xstore_history(movelist[0][0],"forced");
		do_move(movelist[0][0]);
		display_board();
	      }
	    } while(nmoves==1);
	    play_error:
	  }
	else if (strcmp(input,"timecommand")==0) {
	    scanf("%f %f %f %i",&time_left[white],&time_left[black],&operator_time,&timecontrolply);
	    printf("%f %f %f %i\n",time_left[white],time_left[black],operator_time,timecontrolply);
	  }
        else if (strcmp(input,"set")==0) {
            scanf("%i %i",&in1,&in2);
            board[map[in1-1]]=in2;
            }
	else if (strcmp(input,"hplus")==0) {
	    char nullmove[32]={4,0,0,0,0};  
	    xstore_history(nullmove,"hplus");
	  }
        else if (strcmp(input,"help")==0) {
            printf("\
            help                        generate this mesage\n\
            history {verbose 0,1,2}     show played moves\n\
            ?                           show available moves\n\
            go {player}{time}           computer thinks and does a move\n\
            do {move}                   enter a move\n\
            analyse {player}{time}      computer thinks\n\
            bd                          draw board\n\
            dopv {n}                    do best known move\n\
       	    ! {command}                 shell escape\n\
       	    eval                        static evaluation\n\
       	    movescore                   show score of all moves\n\
       	    kill {0,1,2,3}              set killer method\n\
       	    bestfit\n\
       	    bookmove                    try to do move from book\n\
       	    test                        speed tests\n\
       	    get {file}                  load position\n\
       	    quit                        quit\n\
       	    pn {color}{nodes}{type}     do pn1 search\n\
       	    selective {boolean}         selective search\n\
       	    load {file}                 load position\n\
            write_pdn {file}            save game\n\
	    saveboard {color}{file}     save position\n\
            maxpv {n}                   set maxpv\n\
            followpv {n}                play out pv\n\
            plearn {plusscore}          learn pattern\n\
            psave                       save patterns\n\
            back                        take back\n\
            mback {n}                   multiple takeback\n\
            reverse                     reverse black/white\n\
            timecommand {time white}    set timers\n\
              {time black} {optime}\n\
              {timecontrolply}\n\
            hplus                       increase history\n\
            make_pat_tree\n\
            save_pat_tree\n\
            load_pat_tree\n\
            make_bin_book\n\
            auto {color} {time}         autoplayer\n\
	    initboard                   new board\n");
        }
        else if (strcmp(input,"kill")==0) {
            scanf("%i",&kill_method);
            }
        else if (strcmp(input,"selective")==0) {
            scanf("%i",&selective);
            if (selective==false) printf("not selective\n");
            else if (selective==true) printf("selective search\n");
            else printf("selective error\n");
            }
        else if (strcmp(input,"bestfit")==0) {
            best_fit();
            }
        else if (strcmp(input,"bookmove")==0) {
            int s;
            scanf("%i",&in1);
            printf("bookscore:%i\n",book_score(in1));
            s=try_book(0,in1);
            display_board();
            printf("score:%i\n",s);
            }

        else if (strcmp(input,"hist")==0) {
            scanf("%i %i",&in1,&in2);
            for(i=0;i<150;i++) printf("%4i ",history[in1][i][in2]);
            printf("\n");
            }
        else if (strcmp(input,"test")==0) {
            int i,x=100000,t,n;
	    int dummy1,dummy2,dummy3;
	    char dummymove[32];
            t=clock();
            for(i=0;i<x;i++) field_control(0);
            printf("field_control:%3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) store_hash(0,0,0,0,movelist[0][0]);
            printf("store_hash:   %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) retreive_hash(0,&dummy1,&dummy2,&dummy3,dummymove);
            printf("retreive_hash:%3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);
	    
            t=clock();
            for(i=0;i<x;i++) theoretic(0);
            printf("theoretic:    %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) material(0);
            printf("material:     %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) evalboard(0,-INF,INF);
            printf("evalboard:    %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) n=move_list(0,0);
            printf("move_list:    %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) do_move(movelist[0][0]);
            printf("do_move(0):   %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) storemove(0,movelist[0][0]);
            printf("storemove:    %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) findkiller(0,n);
            printf("findkiller:   %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            t=clock();
            for(i=0;i<x;i++) quiet(1);
            printf("quiet:        %3.1f\n",1.0E6*(clock()-t)/CLOCKS_PER_SEC/x);

            }
	else if (strcmp(input,"xedit")==0) {
	  char xinput[16];
	  int field;
	  int piece;
	  int color=white;

	  for(field=0;field<50;field++) board[map[field]]=empty;
	  do {
	    scanf("%s",xinput);
	    
	    if (xinput[0]=='.') break;
	    else if (xinput[0]=='c') color=black-color;
	    else {
	      if (xinput[0]=='P') piece=man;
	      else if (xinput[0]=='K') piece=crown;
	      else printf("never get here\n");
	      field=xparse(xinput[1],xinput[2]);
	      if (field!=-1) board[map[field-1]]=color|piece;
	    }
	  } while(1==1);
	  display_board();fflush(stdout);
	}
	else if (strcmp(input,"xdomove")==0) {
            char move[32];
	    char xmove[8];
	    int from,to,r;
	    scanf("%s",xmove);
	    if (strcmp(xmove,"null")==0) {
	      r=false;
	      goto scipmovein;
	    }
	    from=xparse(xmove[0],xmove[1]);
	    to=xparse(xmove[2],xmove[3]);
	    r=try_move(game_history_nr%2,from,to);
	    if (r==true) {
	      fflush(stdout);
	    }
	    if (move_list(0,game_history_nr%2)==0) { /* it's now my turn */
	      printf("opponent mates!\n");fflush(stdout);
	      goto end_xdomove;
	    }
	  scipmovein:
	    if (r==false) {
	      /* accept move */
	      printf("xsetboard "); xprintboard();
	      fflush(stdout);
	      play(my_color,alloc_time(game_history_nr%2),9);
	      xprint_move(game_history[game_history_nr-1].move);
	      display_board();
	      if (move_list(0,game_history_nr%2)==0) { /* it's now oppy turn */
		printf("computer mates!\n");fflush(stdout);
		goto end_xdomove;
	      }
	    }
	  end_xdomove:
	  }
	else if (strcmp(input,"time")==0) {
	    scanf("%i",&in1);
	    /*printf("command not supported\n");*/
	     
	    fflush(stdout);
	  }
	else if (strcmp(input,"otim")==0) {
	    scanf("%i",&in1);
	    /*printf("command not supported\n");*/
	      printf("otim 30000 40 netlag 4302 4302 0\n");
	    fflush(stdout);
	  }
        else if (strcmp(input,"do")==0) {
            int c,nr,nmoves,found=0;
            char move[32];

            scanf("%i-%i",&in1,&in2);
            in1=map[in1-1]; in2=map[in2-1];
            for(c=white;c<=black;c++) {
                nmoves=move_list(0,c);
                for(nr=0;nr<nmoves;nr++) {
                    if (in1==movelist[0][nr][1] && in2==movelist[0][nr][movelist[0][nr][0]-1]) {
                        found++;
                        movecopy(move,movelist[0][nr]);
                        }
                    }
                }
            if (found==0) printf("Illegal move\n");
            else if (found>1) printf("Ambigious move\n");
            else {
                xstore_history(move,"user");
                do_move(move);
                display_board();
                }
            }
        else if (strcmp(input,"active")==0) {
            int depth,score;
            scanf("%i%i",&in1,&in2);
            for(depth=200;depth<1200;depth+=200) {
                init_stats();
                score=active(in2,in1,0,depth);
                print_pv();
                print_stats();
                printf("score:%.3f\n",score/1000.0F);
            }
        }
        else if (strcmp(input,"solve")==0) {
            int score,t;
            scanf("%i%i",&in1,&in2);
            init_stats();
            init_hash();
            t=-clock();
            score=solve(-INF,INF,in1,0,in2);
            t+=clock();
            print_pv();
            print_stats();
            printf("score:%.3f time:%.2f\n",score/1000.0F,(float) t/CLOCKS_PER_SEC);
        }
        else if (strcmp(input,"analyse")==0) {
            int t,time,score,d;
            char temp[32]="";

            scanf("%i%i",&in1,&in2);
            d=100; time=clock();init_hash();set_eval();
            while((clock()-time)<CLOCKS_PER_SEC*in2) {
                printf("\ndepth:%.1f\n",d/100.0F);
                init_stats();
                t=-clock();
                /**/
                movecopy(killer[0],temp);
                score=alfabeta(alfa,beta,in1,0,d,0);
                movecopy(temp,PV[0][0]);
                t+=clock();
                print_pv();
                print_stats();
                printf("score:%.3f time:%.2f\n",score/1000.0F,(float) t/CLOCKS_PER_SEC);
                d+=100;
                }
           }
        else if (strcmp(input,"+db")==0) use_db=true;
        else if (strcmp(input,"-db")==0) use_db=false;
        else if (strcmp(input,"+order")==0) do_order=true;
        else if (strcmp(input,"-order")==0) do_order=false;
        else if (strcmp(input,"quit")==0) ;
        else if (strcmp(input,"+hash")==0) use_hash=true;
        else if (strcmp(input,"-hash")==0) use_hash=false;
        else if (strcmp(input,"default_search")==0) {
            scanf("%i",&default_search);
            }
        else if (strcmp(input,"default_eval")==0) {
            scanf("%i",&default_eval);
            }
        else if (strcmp(input,"learn")==0) {
            int d1,d2,e1,e2;
            scanf("%i%i%i%i%i",&in1,&d1,&e1,&d2,&e2);
            randomgame(in1,d1,e1,d2,e2,true);
            }
        else if (strcmp(input,"match")==0) {
            int d1,d2,e1,e2;
            scanf("%i%i%i%i%i",&in1,&d1,&e1,&d2,&e2);
            randomgame(in1,d1,e1,d2,e2,false);
            }
        else printf("error\n");
        } while(strcmp(input,"quit")!=0 && strcmp(input,"q")!=0 && strcmp(input,"exit")!=0);
    return(0);
}
