#include "scr_Board.h"
#include <fstream.h>

scr_Board::scr_Board(char* filename, scr_Bag* BagIn, scr_Dictionary* DictIn){
char a,b;
ifstream loadboard(filename,ios::in);
 BSIZE=15;
 Board = new Square*[BSIZE];
 for(a=0; a<BSIZE; a++) Board[a] = new Square[BSIZE];
 Bag=BagIn; Dict=DictIn;
 loadboard.unsetf(ios::dec);
 loadboard.setf(ios::hex);
 for(a=0;a<BSIZE;a++)
  for(b=0;b<BSIZE;b++){
   Board[a][b].hasblank=0;
   loadboard>>Board[a][b].letter;
   Board[a][b].letter-=48;
   loadboard>>Board[a][b].wmult;
   Board[a][b].wmult-=48;
   loadboard>>Board[a][b].smult;
   Board[a][b].smult-=48;
   loadboard>>Board[a][b].flags[0];
   loadboard>>Board[a][b].flags[1];
   loadboard>>Board[a][b].adjacent;
   loadboard>>Board[a][b].value[0];
   loadboard>>Board[a][b].value[1];
  }
 loadboard.close();
}
/*
list<scr_CoordList>* scr_Board::Generate(unsigned long int tiles){
register char a,b;
char c,d=0;
list<scr_CoordList>* newlist= new list<scr_CoordList>[BSIZE];

 for(a=0;a<BSIZE;a++){
  for(b=BSIZE-1, c=0,d=0; b>-1; b--){
   if(tiles&Board[a][b].flags[0]){
    if(Board[a][b].adjacent&1) c=d=0;
    else Board[a][b].adjacent&14 ? c=7 : 0;
    if(c){
     c--;
     newlist[7-c+d].push_back(scr_CoordList(a,b,0));
    }
   }
   else{
    c=0;
    d++;
   }
  }
  for(b=BSIZE-1, c=0,d=0; b>-1; b--){
   if(tiles&Board[b][a].flags[1]){
    if(Board[b][a].adjacent&2) c=d=0;
    else Board[b][a].adjacent&13 ? c=7 : 0;
    if(c){
     c--;
     newlist[7-c+d].push_back(scr_CoordList(b,a,1));
    }
   }
   else{
    c=0;
    d++;
   }
  }
  
  for(b=0;b<BSIZE-1;b++){
   if(Board[a][b].letter){
    for(c=b+1;(c<BSIZE)&&(Board[a][c].letter);c++);
    if((c<BSIZE)&&(Board[a][c].flags[0]&tiles)) newlist[c-b+1].push_back(scr_CoordList(a,b,0));
    b=c;
   }
  }
  for(b=0;b<BSIZE-1;b++){
   if(Board[b][a].letter){
    for(c=b+1;(c<BSIZE)&&(Board[c][a].letter);c++);
    if((c<BSIZE)&&(Board[c][a].flags[1]&tiles)) newlist[c-b+1].push_back(scr_CoordList(b,a,1));
    b=c;
   }
  }
 }
 return(newlist);
}
*/

//dx is the perpendicular vector, dy is the word's vector
void scr_Board::Integrate(char x, char y, char dx, char* stringer){
char a,dy=((dx+1)&1),val,rval=0,p,q,r,hold,*xpt,*ypt,spot[BSIZE+1];
char input[BSIZE+1];
 hold = (dx ? x : y);
 spot[BSIZE]='\0';
 for(a=0;stringer[a];a++){
  input[a]=(stringer[a]&63);
  if(input[a]<31) input[a]+=64;
  else input[a] -=32;
 }
 input[a]=0;
 for(a=0;input[a];a++){
  q=Bag->Value(input[a]);
  rval+=q;
  if(Board[x][y].letter==0){
   if(input[a]>63){
    input[a]-=64;
    Board[x][y].hasblank=1;
   }
   Board[x][y].letter=input[a];
   Board[x][y].adjacent=0;
   Board[x][y].wmult=1;
   Board[x][y].smult=1;
   
   if((dx ? y : x)+1<BSIZE){
    val= dx ? x : x+1; p= dx ? y+1 : y;
    if(Board[val][p].letter==0) Board[val][p].adjacent|= dx ? 1 : 2;
   }
   if(dx ? y : x){
    val= dx ? x : x-1; p= dx ? y-1 : y;
    if(Board[val][p].letter==0) Board[val][p].adjacent|= dx ? 8 : 4;
   }

   val=q+Board[x][y].value[dx];
   spot[dx ? y : x]=input[a];

   xpt = dx ? &x : &p; ypt = dy ? &y : &p;   
   for(p=(dx ? y-1 : x-1); (p>-1)&&(Board[*xpt][*ypt].letter); p--) spot[p]=Board[*xpt][*ypt].letter;
   if(p>-1){
    Board[*xpt][*ypt].value[dx]=val;
    spot[p]='\0';
   }
   xpt = dx ? &x : &q; ypt = dy ? &y : &q;
   for(q=(dx ? y+1 : x+1); (q<BSIZE)&&(Board[*xpt][*ypt].letter); q++) spot[q]=Board[*xpt][*ypt].letter;
   if(q<BSIZE) Board[*xpt][*ypt].value[dx]=val;
   spot[q]='\0';

   Board[x][y].value[0]=Board[x][y].value[1]=Bag->Value(input[a]);
   
   Board[x][y].flags[0]=Board[x][y].flags[1]=0;
     
   if(p>-1){
    xpt= dx ? &x : &r; ypt= dy ? &y : &r;
    if(p==0) Board[dx ? x : p][dy ? y : p].flags[dx]=Dict->Bridge(spot,spot+1);
    else{
     spot[p-1]='\0';
     for(r=p-1;(r>-1)&&Board[*xpt][*ypt].letter;r--) spot[r]=Board[*xpt][*ypt].letter;
     if(r>-1) Board[dx ? x : p][dy ? y : p].flags[dx]=Dict->Bridge(spot+r,spot+p+1);
    }
   }
   
   if(q<BSIZE-1){
    xpt= dx ? &x : &r; ypt= dy ? &y : &r;
    spot[q+1]='\0';
    for(r=q+1;(r<BSIZE)&&Board[*xpt][*ypt].letter;r++) spot[r]=Board[*xpt][*ypt].letter;
    if(r<BSIZE+1){
     spot[r]='\0';
     Board[dx ? x : q][dy ? y : q].flags[dx]=Dict->Bridge(spot+p+1,spot+q+1);
    }
   }
   
  }
  x+=dx; y+=dy;
 }
  
 if((dx ? x : y)<BSIZE){
  xpt= dx ? &x : &r; ypt= dy ? &y : &r;
  spot[(dx ? x : y)+1]='\0';
  for(r=(dx ? x : y)+1;(r<BSIZE)&&Board[*xpt][*ypt].letter;r++) spot[r]=Board[*xpt][*ypt].letter;
  if(r<BSIZE+1){
   spot[r]='\0';
   Board[x][y].flags[dy]=Dict->Bridge(input,spot+(dx ? x : y)+1);
  }
 }
 
 if(dx ? (x<BSIZE&&x) : (y<BSIZE&&y)){
  Board[x][y].value[dy]=rval;
  Board[x][y].adjacent|=(dx ? 2 : 1);
 }
 
 if(hold){
  hold--;
  xpt= dx ? &r : &x; ypt= dy ? &r : &y;
  spot[0]='\0';
  if(hold==0) Board[dx ? hold : x][dy ? hold : y].flags[dy]=Dict->Bridge(spot,input);
  else{
   spot[hold-1]='\0';
   for(r=hold-1;(r>-1)&&Board[*xpt][*ypt].letter;r--) spot[r]=Board[*xpt][*ypt].letter;
   if(r>-1) Board[dx ? hold : x][dy ? hold : y].flags[dy]=Dict->Bridge(spot+r,input);
  }
  Board[dx ? hold: x][dy ? hold : y].value[dy]=rval;
  Board[dx ? hold: x][dy ? hold : y].adjacent|=(dx ? 4 : 8);
 }
}

//the following two functions are provided for testing purposes as well as use for human players
//(ie) the computer player does not need to use them

//Error codes for Valid:
//0: Play is ok
//1: A word is not in the dictionary
//2: Play is exectuted incorrectly
//3: Move has the wrong input string
//4: Move is trying to put a tile on a square already having a tile
//5: Move exceeds boundary of board

int scr_Board::Valid(char x, char y, char dx, char* stringer){
char dy=(dx+1)&1,a,p=0,input[BSIZE+1];
 for(a=0;stringer[a];a++) input[a]=(stringer[a]&31);
 input[a]=0;
 if(Dict->Verify(input)==0) return 1;
 if(dx ? x : y)
  if(Letter((dx ? x-1 : x),(dy ? y-1 : y))) return 3;

 for(a=0; input[a]; a++){
  if((x==BSIZE)||(y==BSIZE)) return 5;
  if(Letter(x,y)){
   if(Letter(x,y)!=input[a]) return 4;
  }
  else{
   if(((1<<(input[a]-1))&Board[x][y].flags[dx])==0) return 1;
   else if(Board[x][y].adjacent) p=1;
  }
  x+=dx; y+=dy;
 }
 if((dx ? x : y)<BSIZE)
  if(Board[x][y].letter) return 3;
 if(p) return 0;
 else return 2;
}

//pretty self explanatory what this function does
int scr_Board::Score(char x, char y, char dx, char* stringer){
char dy=(dx+1)&1,a,mult=1;
int total=0;
char input[BSIZE+1];
 for(a=0;stringer[a];a++){
  input[a]=(stringer[a]&63);
  if(input[a]<31) input[a]+=64;
  else input[a]-=32;
 }
 input[a]=0;
 for(a=0;input[a];a++){
  mult*=Board[x][y].wmult;
  if(Board[x][y].letter){
   if(HasBlank(x,y)==0) total+=Bag->Value(input[a]);
  }
  else total+=Bag->Value(input[a]) * Board[x][y].smult * (1 + ((Board[x][y].value[dx]>0) ? 1 : 0))+Board[x][y].value[dx];
  x+=dx; y+=dy;
 }
 return(total*mult);
}
