/*
        feld.c    -   Ein Teil von Gambler

        (c) by Guido Appenzeller - Landessternwarte - 6900 Heidelberg

*/

#include "gambler.h"

extern struct Spielregeln SR;
extern char               Compressed[350];
extern char               BestMove[350];
extern int                CLength;
extern int                Slt[2];

/* --- Kopiert eine Stellung in eine andere ------------------------- */

CopyStellung(St1,St2)
int St1[50][50];
int St2[50][50];
{
    int t,g;

    for(t=0;t<SR.Brettbreite;t++)
        for(g=0;g<SR.Bretthoehe;g++) St2[t][g]=St1[t][g];

}

LoescheFeld(St1)
int St1[50][50];
{
    int t,g;
    for( t=0; t<50; t++)
        for( g=0; g<50; g++ ) St1[t][g] = SR.AusgangsBrett[t][g];
}

/* --- Stellt die Ausgangsstellung wie sie in SR definiert wurde her --- */

InitStellung(St1)
int St1[50][50];
{
    int spieler,t;

    LoescheFeld(St1);

    Slt[0] = SR.Steine[0] - SR.ASteine[0];
    Slt[1] = SR.Steine[1] - SR.ASteine[1];
}

SaveBest()
{
    int t;

    for(t=0; t<CLength; t++ ) BestMove[t] = Compressed[t];

    return();
}

LoadBest()
{
    int t;

    for(t=0; t<CLength; t++ ) Compressed[t] = BestMove[t];

    return();
}

/* --- Komprimiert die Stellung in sowenige Bytes wie moeglich --------- */

CompressStellung(St1)
int St1[50][50];
{
    int t,g,ptr;

    ptr = 0;

    for( g=0; g<SR.Bretthoehe; g++ )
    {
      if( SR.SteinTypen<4 )
      {
        for( t=0; t<SR.Brettbreite; t=t+4 )
           Compressed[ptr++] =
                    St1[t][g]+St1[t+1][g]*4+St1[t+2][g]*16+St1[t+3][g]*64;
      }
      else
      {
        for( t=0; t<SR.Brettbreite; t=t+2 )
        Compressed[ptr++] = St1[t][g]+St1[t+1][g]*16;
      }
    }

    Compressed[ptr] = 0;
    CLength = ptr+1;
}

/* --- Dekomprimiert die in Compress[] gespeicherte Stellung ----------- */

char ExpandStellung(St1)
int St1[50][50];
{
    int ptr,t,g;

    ptr = 0;

    for( g=0; g<SR.Bretthoehe; g++ )
    {
      if( SR.SteinTypen<3 )
      {
        for( t=0; t<SR.Brettbreite; t=t+4 )
            {
                St1[ t ][g] = ( Compressed[ptr] & 3   );
                St1[t+1][g] = ( Compressed[ptr] & 12  ) >> 2;
                St1[t+2][g] = ( Compressed[ptr] & 48  ) >> 4;
                St1[t+3][g] = ( Compressed[ptr++] & 192 ) >> 6;
            }
      }
      else
      {
        for( t=0; t<SR.Brettbreite; t=t+2 )
            {
                St1[ t ][g] = ( Compressed[ptr] & 15   );
                St1[t+1][g] = ( Compressed[ptr++] & 240  ) >> 4;
            }
      }
    }
    return( Compressed[ptr] );

}

/* --- Fügt eine Stellung zum Stellungsspeicher hinzu ------------------ */

AddStellung(ptr)
char *ptr;
{
    int t;

    for(t=0; t <= CLength; t++) *ptr++ = Compressed[t];
}

/* --- Sucht eine Stellung im Stellunsspeicher ------------------------- */

char *FindStellung(minptr,maxptr)
char *minptr,*maxptr;
{
  char *SearchPos;

  for(SearchPos=minptr;SearchPos<maxptr; SearchPos=SearchPos+CLength )
    {
        if( BCompare(SearchPos,Compressed,(CLength-1)) == 1 )
            {
                return( SearchPos );
            }
    }
  return(0L);
}

BCompare(p1,p2,l)
char *p1,*p2;
int l;
{
    int t;

    for( t=0; t<l; t++ ) if( *p1++ != *p2++ ) return(0);
    return(1);
}

GetCompressed(p1)
char *p1;
{
    int ptr;

    if( p1 == NULL ) { return(); }

    ptr = 0;

    for( ptr=0; ptr<=CLength; ptr++ )
        Compressed[ptr] = *p1++;
}

