Cia.cxx

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#include "Cia.hxx"

#define ENDOFREGISTEREDPLAYERS "--- No More ---"

#define TRUE 1
#define FALSE 0

#define NOT_REG_POINTS -20000

#define NUMTESTS_OPP 0 // 1 test of every combination
#define NUMTESTS_US 1 // 2 tests of every combination

#undef LOOSE
//#define LOOSE

CCia::CCia ()
{
  InitZero ();

}

CCia::~CCia ()
{

}

void CCia::InitZero ()
{
  memset (NameOfPlayers,0,sizeof (NameOfPlayers));
  memset (HasChanged,0,sizeof (HasChanged));
  memset (LastChanged,0,sizeof (LastChanged));
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    for (int j = 0; j < MAXNUMPLAYERS; j++)
      for (int k = 0; k < MEETPEROPP; k++)
	{
	  points[i][j][0][k] = points[i][j][1][k] = NOT_REG_POINTS;
	}
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    for (int j = 0; j < NUMMETHODS; j++)
      for (int k = 0; k < MEETPEROPP; k++)
	{
	  points47[i][j][0][k][0][0] = points47[i][j][1][k][0][0] = NOT_REG_POINTS;
	}
  memset (MoveH,0,sizeof (MoveH));
}

void CCia::ClearAgainstUs ()
{
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    for (int j = 0; j < NUMMETHODS; j++)
      for (int k = 0; k < MEETPEROPP; k++)
	{
	  points47[i][j][0][k][0][0] = points47[i][j][1][k][0][0] = NOT_REG_POINTS;
	}
  memset (MoveH,0,sizeof (MoveH));
}

void CCia::LoadFile (char* szFileName) // this will overwrite all internal info
{
  FILE* file;
  char trash[10000];

  InitZero ();


  if ((file = fopen (szFileName,"r")) == NULL)
    {
      printf ("CCia::LoadFile () failed open '%s' for reading\n",szFileName);
      return;
    }
  printf ("Reading file: %s...\n",szFileName);
  fgets (trash,8000,file);
  fgets (trash,8000,file);
  for (;;)
    {
      int num;
      fgets (trash,8000,file);

      if (strstr (trash,ENDOFREGISTEREDPLAYERS) != NULL)
	break;
      num = atoi (trash+16+3);
      if (num+1 < 0 || num > MAXNUMPLAYERS)
	{
	  printf ("CCia::LoadFile () playernumber out of range: '%d'\n",num);
	  continue;
	}
      strncpy (NameOfPlayers[num-1],trash,16);
      LastChanged[num-1][0] = atoi (trash+16+3+2+3);
      LastChanged[num-1][1] = atoi (trash+16+3+2+3+7+3);
    }

  fgets (trash,8000,file);
  fgets (trash,8000,file);
  fgets (trash,8000,file);

  int pl1, pl2;
  int p1, p2, p3, p4;

  for ( ;; )
    {
      fgets (trash,8000,file);
      char* ptr = trash;
      pl1 = (int) strtol (ptr,&ptr,10);
      pl2 = (int) strtol (ptr,&ptr,10);
      if (pl1 < 1 || pl1 > MAXNUMPLAYERS || pl2 < 1 || pl2 > MAXNUMPLAYERS)
	break;
      for (int k = 0; k < 10; k++)
	{
	  ptr++;
	  p1 = (int) strtol (ptr,&ptr,10);
	  ptr++;
	  p2 = (int) strtol (ptr,&ptr,10);
	  ptr++;
	  p3 = (int) strtol (ptr,&ptr,10);
	  ptr++;
	  p4 = (int) strtol (ptr,&ptr,10);

	  points[pl1-1][pl2-1][0][k] = p1;
	  points[pl2-1][pl1-1][0][k] = p2;
	  points[pl1-1][pl2-1][1][k] = p3;
	  points[pl2-1][pl1-1][1][k] = p4;
	  if (*ptr == '\n')
	    break;
	}
    }
  fgets (trash,8000,file);
  fgets (trash,8000,file);
  fgets (trash,8000,file);

  int p5, p6, p7, p8;
  int method;

   for ( ;; )
    {
      fgets (trash,8000,file);
      char* ptr = trash;
      pl1 = (int) strtol (ptr,&ptr,10);
      method = (int) strtol (ptr,&ptr,10);
      if (pl1 < 1 || pl1 > MAXNUMPLAYERS || method < 1 || method > NUMMETHODS)
	break;
      for (int k = 0; k < 10; k++)
	{
	  ptr++; p1 = (int) strtol (ptr,&ptr,10);
	  ptr++; p2 = (int) strtol (ptr,&ptr,10);
	  ptr++; p3 = (int) strtol (ptr,&ptr,10);
	  ptr++; p4 = (int) strtol (ptr,&ptr,10);
	  ptr++; p5 = (int) strtol (ptr,&ptr,10);
	  ptr++; p6 = (int) strtol (ptr,&ptr,10);
	  ptr++; p7 = (int) strtol (ptr,&ptr,10);
	  ptr++; p8 = (int) strtol (ptr,&ptr,10);

	  points47[pl1-1][method-1][0][k][0][0] = p1;
	  points47[pl1-1][method-1][0][k][0][1] = p2;
	  points47[pl1-1][method-1][0][k][1][0] = p3;
	  points47[pl1-1][method-1][0][k][1][1] = p4;
	  points47[pl1-1][method-1][1][k][0][0] = p5;
	  points47[pl1-1][method-1][1][k][0][1] = p6;
	  points47[pl1-1][method-1][1][k][1][0] = p7;
	  points47[pl1-1][method-1][1][k][1][1] = p8;
	  if (*ptr == '\n')
	    break;
	}
    }

  fgets (trash,8000,file);
  fgets (trash,8000,file);
  fgets (trash,8000,file);

  for ( ;; )
    {
      fgets (trash,8000,file);
      char* ptr = trash;
      pl1 = (int) strtol (ptr,&ptr,10);
      if (pl1 < 1 || pl1 > MAXNUMPLAYERS)
	break;
      MoveH[pl1-1].tested = (int) strtol (ptr,&ptr,10);
      
      ptr++; MoveH[pl1-1].exme[0] = (int) strtol (ptr,&ptr,10);
      ptr++; MoveH[pl1-1].exopp[0] = (int) strtol (ptr,&ptr,10);
      ptr++; MoveH[pl1-1].exme[1] = (int) strtol (ptr,&ptr,10);
      ptr++; MoveH[pl1-1].exopp[1] = (int) strtol (ptr,&ptr,10);
      
      for (int i = 0; i < 2; i++)
	for (int j = 0; j < 32; j++)
	  {
	    ptr++; MoveH[pl1-1].list[i][j] = (unsigned long int) strtoul (ptr,&ptr,10);
	  }
    }

  fclose (file);
}

void CCia::SaveFile (char* szFileName)
{
  FILE* file;

  if ((file = fopen (szFileName,"w")) == NULL)
    {
      printf ("CCia::SaveFile () failed open '%s' for writing\n",szFileName);
      return;
    }
  printf ("Writing file: %s...\n",szFileName);
  fprintf (file,"The registered players:\n\n");
  for (int i = 0; i < MAXNUMPLAYERS; i ++)
    if (NameOfPlayers[i][0] != '\0')
      fprintf (file,"%-16s : %2d : %7ld : %7ld\n",NameOfPlayers[i],i+1,LastChanged[i][0],LastChanged[i][1]);
  fprintf (file,"%-16s : %d\n",ENDOFREGISTEREDPLAYERS,0); 
  fprintf (file,"\n");
  fprintf (file,"Points in opponents meetings:\n\n");
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    for (int j = i+1; j < MAXNUMPLAYERS; j++)
      if (points[i][j][0][0] != NOT_REG_POINTS)
	{
	  fprintf (file,"%2d %2d",i+1,j+1);
	  for (int k = 0; k < MEETPEROPP; k++)
	    if (points[i][j][0][k] != NOT_REG_POINTS)
	      fprintf (file,"|%3d:%3d %3d:%3d",points[i][j][0][k],points[j][i][0][k],points[i][j][1][k],points[j][i][1][k]);
	  fprintf (file,"\n");
	}
  fprintf (file,"-1 -1\n");
  fprintf (file,"\n");
  fprintf (file,"Points in meetings with different methods:\n\n");
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    for (int j = 0; j < NUMMETHODS; j++)
      if (points47[i][j][0][0][0][0] != NOT_REG_POINTS)
	{
	  fprintf (file,"%2d %2d",i+1,j+1);
	  for (int k = 0; k < MEETPEROPP; k++)
	    if (points47[i][j][0][k][0][0] != NOT_REG_POINTS)
	      {
		fprintf (file,"|%3d:%3d %3d:%3d",
			 points47[i][j][0][k][0][0],
			 points47[i][j][0][k][0][1],
			 points47[i][j][0][k][1][0],
			 points47[i][j][0][k][1][1]);
		fprintf (file,";%3d:%3d %3d:%3d",
			 points47[i][j][1][k][0][0],
			 points47[i][j][1][k][0][1],
			 points47[i][j][1][k][1][0],
			 points47[i][j][1][k][1][1]);
	      }
	  
	  fprintf (file,"\n");
	}
  fprintf (file,"-1 -1\n");
  fprintf (file,"\n");
  fprintf (file,"Best players moves:\n\n");
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    if (MoveH[i].tested)
      {
	fprintf (file,"%2d %2d",i+1,MoveH[i].tested);
	if (MoveH[i].tested == 1)
	  {
	    fprintf (file,"|%3d %3d %3d %3d|",
		     MoveH[i].exme[0],MoveH[i].exopp[0],
		     MoveH[i].exme[1],MoveH[i].exopp[1]);
	    for (int k = 0; k < 2; k++)
	      {
		for (int j = 0; j < 32; j++)
		  fprintf (file,"%u ",MoveH[i].list[k][j]);
	      }
	    
	  }
	fprintf (file,"\n");
      }
  fprintf (file,"-1 -1\n");
  fprintf (file,"\n\n");

  fclose (file);
}

int CCia::NameToGroup (char* PlayerName)
{
  for (int i = 0; i < MAXNUMPLAYERS; i ++)
    if (strcmp (PlayerName,NameOfPlayers[i]) == 0)
      return i+1;
  return 0; // player not found
}

char* CCia::GroupToName (int num,char* PlayerName) // PlayerName must nut be null
{
  strcpy (PlayerName,NameOfPlayers[num-1]);
  return PlayerName; 
}

void CCia::TestChangedPlayer (int i,char* searchpath)
{
  char buf[200];
  long timeOrgO, timeOrgAli, timeOrgAds;
  long timeCopyO, timeCopyAli, timeCopyAds;

  printf ("Investigating: spelare%d ",i+1);

  sprintf (buf,"ls -l %s/spelare%d.o",searchpath,i+1);
  timeOrgO = lstimetolong(syscall(buf));
  sprintf (buf,"ls -l %s/spelare%d.ali",searchpath,i+1);
  timeOrgAli = lstimetolong(syscall(buf));
  sprintf (buf,"ls -l %s/spelare%d.ads",searchpath,i+1);
  timeOrgAds = lstimetolong(syscall(buf));
  sprintf (buf,"ls -l spelare%d.o",i+1);
  timeCopyO = lstimetolong(syscall(buf),FALSE);
  sprintf (buf,"ls -l spelare%d.ali",i+1);
  timeCopyAli = lstimetolong(syscall(buf),FALSE);
  sprintf (buf,"ls -l spelare%d.ads",i+1);
  timeCopyAds = lstimetolong(syscall(buf),FALSE);

  printf ("(%c%c%c%c%c%c) ",
	  timeOrgO    == -1 ? '-' : timeOrgO    < timeOrgAds  ? '+' : '|',
	  timeOrgAli  == -1 ? '-' : timeOrgAli  < timeOrgAds  ? '+' : '|',
	  timeOrgAds  == -1 ? '-' : '|',
	  timeCopyO   == -1 ? '-' : timeCopyO   < timeCopyAds ? '+' : '|',
	  timeCopyAli == -1 ? '-' : timeCopyAli < timeCopyAds ? '+' : '|',
	  timeCopyAds == -1 ? '-' : '|');
  
  if (timeOrgO < timeOrgAds)
    timeOrgO = -1;
  if (timeOrgAli < timeOrgAds)
    timeOrgAli = -1;
  if (timeCopyO < timeCopyAds)
    timeCopyO = -1;
  if (timeCopyAli < timeCopyAds)
    timeCopyAli = -1;

  if ((timeOrgO  == -1 || timeOrgAli  == -1 || timeOrgAds  == -1) &&
      (timeCopyO == -1 || timeCopyAli == -1 || timeCopyAds == -1))
    {
      NameOfPlayers[i][0] = '\0';
      SetPlayersPointsToZero(i);
      printf ("No originals or copies accessible!\n");
      return;
    }
  if ((timeOrgO != -1 && timeOrgAli != -1 && timeOrgAds != -1) &&
      (timeOrgO != timeCopyO ||
       timeOrgAli != timeCopyAli ||
       timeOrgAds != timeCopyAds))
    {
      printf ("Originals changed, copying...");
      sprintf (buf,"cp -p %s/spelare%d.o spelare%d.o",searchpath,i+1,i+1);
      syscall (buf);
      sprintf (buf,"cp -p %s/spelare%d.ali spelare%d.ali",searchpath,i+1,i+1);
      syscall (buf);
      sprintf (buf,"cp -p %s/spelare%d.ads spelare%d.ads",searchpath,i+1,i+1);
      syscall (buf);

      sprintf (buf,"ls -l spelare%d.o",i+1);
      timeCopyO = lstimetolong(syscall(buf),FALSE);
      sprintf (buf,"ls -l spelare%d.ali",i+1);
      timeCopyAli = lstimetolong(syscall(buf),FALSE);
      sprintf (buf,"ls -l spelare%d.ads",i+1);
      timeCopyAds = lstimetolong(syscall(buf),FALSE);
    }
  if (timeOrgO == -1 || timeOrgAli == -1 || timeOrgAds == -1)
    {
      timeOrgO = -1;
      timeOrgAli = -1;
      timeOrgAds = -1;
    }
  if ((timeCopyO   != -1 && timeCopyO   != LastChanged[i][0]) ||
      (timeOrgO    != -1 && timeOrgO    != LastChanged[i][0]) ||
      (timeCopyAds != -1 && timeCopyAds != LastChanged[i][1]) ||
      (timeOrgAds  != -1 && timeOrgAds  != LastChanged[i][1]))
    {
      printf ("Updating: ");
      LastChanged[i][0] = timeCopyO != -1 ? timeCopyO : timeOrgO;
      LastChanged[i][1] = timeCopyAds != -1 ? timeCopyAds : timeOrgAds;
      HasChanged[i] = TRUE;
      SetPlayersPointsToZero (i);
      if (timeCopyAds != -1)
	sprintf (buf,"cat spelare%d.ads",i+1);
      else
	sprintf (buf,"cat %s/spelare%d.ads",searchpath,i+1);
      char* ptr = syscall (buf);
      char* ptr2 = strstr (strtolower(ptr,'\"'),"playername");
      if (ptr2 != NULL)
	if ((ptr = strchr (ptr2,'\"')) != NULL)	       
	  if ((ptr2 = strchr (++ptr,'\"')) != NULL)
	    {
	      strncpy (NameOfPlayers[i],ptr,ptr2-ptr);
	      NameOfPlayers[i][ptr2-ptr] = '\0';
	      printf ("%s",NameOfPlayers[i]);
	    }	      
    }
  if (NameOfPlayers[i][0] != '\0')
    SayName (NameOfPlayers[i]);
  printf ("\n");
}

void CCia::ActivateAll ()
{
  for (int i = 0; i < MAXNUMPLAYERS; i ++)
    if (i != 46 && NameOfPlayers[i][0] == '\0')
      strcpy (NameOfPlayers[i],"----------------");
}

void CCia::FindChangedPlayers ()
{
  char buf[200];
  int i;

  printf ("Searching for changed players...\n");

  for (i = 0; i < 80; i ++)
    if (NameOfPlayers[i][0] != '\0')
      {
	sprintf (buf,"../../../../f1pt-%d",i+1);
	TestChangedPlayer (i,buf);
      }

  i = 80;
  if (NameOfPlayers[i][0] != '\0')
    TestChangedPlayer (i,"../../../../../spelledaren");

  for (i = 81; i < MAXNUMPLAYERS; i ++)
    if (NameOfPlayers[i][0] != '\0')
      TestChangedPlayer (i,"../../..");
}

void CCia::SetPlayersPointsToZero (int num)
{
  for (int i = 0; i < MAXNUMPLAYERS; i++)
    for (int k = 0; k < MEETPEROPP; k++)
      {
	points[i][num][0][k] = points[num][i][0][k] = NOT_REG_POINTS;
	points[i][num][1][k] = points[num][i][1][k] = NOT_REG_POINTS;
      }
  for (int i = 0; i < NUMMETHODS; i++)
    for (int k = 0; k < MEETPEROPP; k++)
      {
	points47[num][i][0][k][0][0] = points47[num][i][1][k][0][0] = NOT_REG_POINTS;
      }
  memset (MoveH,0,sizeof (MoveH));
}

void CCia::GetActivePlayers (int *players)
{
  for (int i = 0; i < MAXNUMPLAYERS; i++)
      *(players+i) = (NameOfPlayers[i][0] != '\0');
}
/*
int CCia::GetMatchesToPlay (int *activeplayers,int *numplayers,int* buf,int* matches,int *forcetactics)
{
  *numplayers = 0;
  *matches = 0;

  int *bufptr = buf;
  int i, j, l;
  int ii, jj;

  *forcetactics = 0;
  srand ((unsigned) time (NULL));

  int picklist[MAXNUMPLAYERS];

  printf ("Generating a round to play:");

  for (i = 0; i < MAXNUMPLAYERS; i++)
    {
      int pick = rand () % MAXNUMPLAYERS;
      for (j = 0; j < i; j++)
	if (picklist[j] == pick)
	  {
	    pick++;
	    pick %= MAXNUMPLAYERS;
	    j = -1;
	  }
      picklist[i] = pick;      
    }


  for (ii = 0; ii < MAXNUMPLAYERS; ii ++)
    {
      i = picklist[ii];
      if (NameOfPlayers[i][0] != '\0')
	{
	  *//*
	  for (jj = ii+1; jj < MAXNUMPLAYERS; jj ++)
	    {
	      j = picklist[jj];
	      if (NameOfPlayers[j][0] != '\0')
		if (points[i][j][0][NUMTESTS_OPP] == NOT_REG_POINTS)
		break;
		}
		*//*
	  jj = MAXNUMPLAYERS;
	  if (jj == MAXNUMPLAYERS)
	    {
	      int k;
	      for (k = 0; k < NUMMETHODS; k++)
		{
		  if (points47[i][k][0][NUMTESTS_US][0][0] == NOT_REG_POINTS &&
		      (*forcetactics == 0 || *forcetactics == k+1))
		    {
		      *forcetactics = k+1;
		      break;
		    }
		}
	      if (k < NUMMETHODS)
		jj = 0;
	    }
	  if (jj == MAXNUMPLAYERS)
	    continue; // we have all info on this player

	  for (l = 0; l < *numplayers; l++)
	    if (*(activeplayers+l)-1 == i)
	      break;
	  if (l == 10)
	    break;
	  if (l == *numplayers)
	    {
	      *(activeplayers+*numplayers) = i+1;
	      (*numplayers)++;
	      printf (" %d",i+1);
	    }	
	  *//*
	  for (jj = ii+1; jj < MAXNUMPLAYERS; jj ++)
	    {
	      j = picklist[jj];
	      if (NameOfPlayers[j][0] != '\0')
		{
		  if (points[i][j][0][NUMTESTS_OPP] == NOT_REG_POINTS)
		    {
		      for (l = 0; l < *numplayers; l++)
			if (*(activeplayers+l)-1 == j)
			  break;
		      if (l == 10)
			break;
		      if (l == *numplayers)
			{
			  *(activeplayers+*numplayers) = j+1;
			  (*numplayers)++;
			  printf (" %d",j+1);
			  if (*forcetactics == 0)
			    for (int k = 0; k < NUMMETHODS; k++)
			      {
				if (points47[j][k][0][NUMTESTS_US][0][0] == NOT_REG_POINTS)
				  {
				    *forcetactics = k+1;
				    break;
				  }
			      }
			}	
		      *(bufptr++) = i+1;
		      *(bufptr++) = j+1;
		      (*matches)++;
		      // sprintf (buf+strlen (buf),"%d %d",i+1,j+1);
		    }     	      
		}
	    }
	    *//*
	}
    }
  
    if (*forcetactics != 0)
    for (i = 0; i < *numplayers; i++)
      {
	ii = *(activeplayers+i)-1;
	if (points47[ii][*forcetactics-1][0][NUMTESTS_US][0][0] == NOT_REG_POINTS)
	  {	    
	    int pos = (*matches == 0) ? 0 : rand () % (*matches);
	    memmove (buf+pos*2+2,
		     buf+pos*2,
		     (*matches-pos)*sizeof (int)*2);
	    bufptr = buf+pos*2;
	    *(bufptr++) = ii+1;
	    *(bufptr++) = 47;
	    (*matches)++;
	  }
      }
      printf ("\n");

  if (*matches == 0)
{




}

  return (*matches != 0);
}
*/
int CCia::GetMatchesToPlay (int *activeplayers,int *numplayers,int* buf,int* matches,int *forcetactics)
{
  *numplayers = 0;
  *matches = 0;

  int *bufptr = buf;
  int i, j, l;
  int ii, jj;
  int picklist[MAXNUMPLAYERS];

  *forcetactics = 0;
  srand ((unsigned) time (NULL));

  printf ("Generating a round to play:");

  for (i = 0; i < MAXNUMPLAYERS; i++)
    {
      int pick = rand () % MAXNUMPLAYERS;
      for (j = 0; j < i; j++)
	if (picklist[j] == pick)
	  {
	    pick++;
	    pick %= MAXNUMPLAYERS;
	    j = -1;
	  }
      picklist[i] = pick;      
    }

  for (ii = 0; ii < MAXNUMPLAYERS; ii ++)
    {
      i = picklist[ii];
      if (NameOfPlayers[i][0] != '\0')
	{
	  for (jj = ii+1; jj < MAXNUMPLAYERS; jj ++)
	    {
	      j = picklist[jj];
	      if (NameOfPlayers[j][0] != '\0')
		if (points[i][j][0][NUMTESTS_OPP] == NOT_REG_POINTS)
		  break;
	    }
	  if (jj == MAXNUMPLAYERS)
	    {
	      int k;
	      for (k = 0; k < NUMMETHODS; k++)
		{
		  if (points47[i][k][0][NUMTESTS_US][0][0] == NOT_REG_POINTS &&
		      (*forcetactics == 0 || *forcetactics == k+1))
		    {
		      *forcetactics = k+1;
		      break;
		    }
		}
	      if (k < NUMMETHODS)
		jj = 0;
	    }
	  if (jj == MAXNUMPLAYERS)
	    continue; // we have all info on this player

	  for (l = 0; l < *numplayers; l++)
	    if (*(activeplayers+l)-1 == i)
	      break;
	  if (l == 10)
	    break;
	  if (l == *numplayers)
	    {
	      *(activeplayers+*numplayers) = i+1;
	      (*numplayers)++;
	      printf (" %d",i+1);
	    }	
	   
	  for (jj = ii+1; jj < MAXNUMPLAYERS; jj ++)
	    {
	      j = picklist[jj];
	      if (NameOfPlayers[j][0] != '\0')
		{
		  if (points[i][j][0][NUMTESTS_OPP] == NOT_REG_POINTS)
		    {
		      for (l = 0; l < *numplayers; l++)
			if (*(activeplayers+l)-1 == j)
			  break;
		      if (l == 10)
			break;
		      if (l == *numplayers)
			{
			  *(activeplayers+*numplayers) = j+1;
			  (*numplayers)++;
			  printf (" %d",j+1);
			  if (*forcetactics == 0)
			    for (int k = 0; k < NUMMETHODS; k++)
			      {
				if (points47[j][k][0][NUMTESTS_US][0][0] == NOT_REG_POINTS)
				  {
				    *forcetactics = k+1;
				    break;
				  }
			      }
			}	
		      *(bufptr++) = i+1;
		      *(bufptr++) = j+1;
		      (*matches)++;
		      // sprintf (buf+strlen (buf),"%d %d",i+1,j+1);
		    }     	      
		}
	    }
	}
    }
  
  if (*forcetactics != 0)
    for (i = 0; i < *numplayers; i++)
      {
	ii = *(activeplayers+i)-1;
	if (points47[ii][*forcetactics-1][0][NUMTESTS_US][0][0] == NOT_REG_POINTS)
	  {	    
	    int pos = (*matches == 0) ? 0 : rand () % (*matches);
	    memmove (buf+pos*2+2,
		     buf+pos*2,
		     (*matches-pos)*sizeof (int)*2);
	    bufptr = buf+pos*2;
	    *(bufptr++) = ii+1;
	    *(bufptr++) = 47;
	    (*matches)++;
	  }
      }

  if (*matches == 0)
    {
      int tactics[2];
      struct ExpectStruct es;  
      
      int other[5];
      struct ExpectStruct byother[5];
      
      for (i = 0; i < MAXNUMPLAYERS && *matches < 5; i ++)
	if (NameOfPlayers[i][0] != '\0' && !MoveH[i].tested)
	  {
	    GetTacticsForOpponent (i,tactics,&es);
	    
	    memset (other,0,sizeof (other));
	    GetBetterOppForOpponent (i,other,byother,&es);
	    
	    if (other[0] && GoodEnough (byother[0].totme[0]+byother[0].totme[1],es.totme[0]+es.totme[1]))
	      {
		*forcetactics = -1;
				
		*(bufptr++) = other[0];
		*(bufptr++) = i+1;
		(*matches)++;
		printf (" (%d->%d)",other[0],i+1);
	      }
	    /*
		printf ("%16s | %5d %5d |",NameOfPlayers[i],es.totme[0],es.totme[1]);
		for (int j = 0; j < 5 && other[j]; j++)
		printf ("(%2d) %5d %5d ",other[j],byother[j].totme[0],byother[j].totme[1]);
		printf ("\n");
		*/
	  }
    }
  
  printf ("\n");
  return (*matches != 0);
}

void CCia::NoteMatchResults (char* buf)
{
  char *ptr = buf;
  char *ptr2;
  
  int pl1, pl2, method, po1, po2, po3, po4;
  int po5, po6, po7, po8, po9, po10;
  int secondgame;

  if ((ptr2 = strstr (buf,"--==--==--==--==--==--")) != NULL)
    {
      pl1 = atoi (ptr2+strlen ("--==--==--==--==--==--"));
      printf ("Player %d removed from game due to error.\n",pl1);
      NameOfPlayers[pl1-1][0] = '\0';
      SetPlayersPointsToZero(pl1-1);
      return;
    }

  if (strstr (buf,".+<-") == NULL)
    {
      printf ("..............\n\nError reading results...\n\n%s\n..............\n",buf);
      return;
    }

  for ( ;; )
    {
      ptr2 = strstr (ptr,"->+.");
      if (ptr2 == NULL)
	break;
      ptr = ptr2 + 4;

      pl1    = (int) strtol ((ptr2 = ptr),&ptr,10)-1; if (ptr2 == ptr) break;
      pl2    = (int) strtol ((ptr2 = ptr),&ptr,10)-1; if (ptr2 == ptr) break;
      method = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      while (*ptr != '>' && *ptr != '<' && ptr != '\0')
	ptr++;
      if (*ptr == '>')
	{
	  ptr++;
	  secondgame = 0;
	}
      if (*ptr == '<')
	{
	  ptr++;
	  secondgame = 1;
	}
      po1    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po2    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po3    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po4    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      
      if (method == 0)
	{
	  int k;

	  for (k = 0; k < MEETPEROPP; k++)
	    if (points[pl1][pl2][secondgame][k] == NOT_REG_POINTS)
	      break;
	  if (k < MEETPEROPP)
	    {
	      points[pl1][pl2][secondgame][k] = po1;
	      points[pl2][pl1][secondgame][k] = po2;
	    }
	}
      else // method != 0
	{
	  int k;

	  for (k = 0; k < MEETPEROPP; k++)
	    if (points47[pl1][method-1][secondgame][k][0][0] == NOT_REG_POINTS)
	      break;
	  if (k < MEETPEROPP)
	    {
	      points47[pl1][method-1][secondgame][k][0][0] = po1;
	      points47[pl1][method-1][secondgame][k][1][0] = po2;
	      points47[pl1][method-1][secondgame][k][0][1] = po3;
	      points47[pl1][method-1][secondgame][k][1][1] = po4;
	    }
	}
    }
   
  ptr = buf;

  for ( ;; )
    {
      ptr2 = strstr (ptr,"--.;");
      if (ptr2 == NULL)
	return;
      ptr = ptr2 + 4;

      pl2    = (int) strtol ((ptr2 = ptr),&ptr,10)-1; if (ptr2 == ptr) break;
      
      po1    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po2    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po3    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po4    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po5    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po6    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po7    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po8    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po9    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;
      po10    = (int) strtol ((ptr2 = ptr),&ptr,10); if (ptr2 == ptr) break;

      int tactics[2];
      struct ExpectStruct es;  
      
      GetTacticsForOpponent (pl2,tactics,&es);
      
      MoveH[pl2].tested = 1;
      
      if (GoodEnough (po1+po5,es.totme[0]+es.totme[1]) && po9 + po10 > 1500)
	{
	  MoveH[pl2].tested = 1;
	  for (int i = 0; i < 2; i++)
	    {
	      ptr = strchr (ptr,'|'); if (ptr == NULL) return;
	      for (int j = 0; j < 999; j++)
		  MoveH[pl2].list[i][j/32] |= (*(ptr++) == '1') << (j%32);
	    }
	  MoveH[pl2].exme[0] = po3;
	  MoveH[pl2].exopp[0] = po4;
	  MoveH[pl2].exme[1] = po7;
	  MoveH[pl2].exopp[1] = po8;
	}
      else
	MoveH[pl2].tested = 2;
      
      
    }
   
}

int CCia::NumKnownOpponents ()
{
  int count = 0;

  for (int i = 0; i < MAXNUMPLAYERS; i++)
    if (NameOfPlayers[i][0] != '\0')
      count++;
  return count;
}

int CCia::NumKnownMoveSeries ()
{
  int count = 0;

  for (int i = 0; i < MAXNUMPLAYERS; i++)
    if (MoveH[i].tested == 1)
      count++;
  return count;
}

int CCia::GetTacticsForNextOpponent (int* numinlist,
				 char* PlayerName,
				 int* tactics,
				 struct ExpectStruct* es)
{
  for (; *numinlist < MAXNUMPLAYERS; (*numinlist)++)
    if (NameOfPlayers[*numinlist][0] != '\0')
      {
	GroupToName (*numinlist+1,PlayerName);
	while (strlen (PlayerName) < 16)
	  strcat (PlayerName," ");

	if (MoveH[*numinlist].tested == 1)
	  {
	    *tactics = *(tactics+1) = -1;
	    es->exme[0]   = MoveH[*numinlist].exme[0];
	    es->exme[1]   = MoveH[*numinlist].exme[1];
	    es->exopp[0]   = MoveH[*numinlist].exopp[0];
	    es->exopp[1]   = MoveH[*numinlist].exopp[1];
	    es->totme[0]  = es->totme[1]  = NOT_REG_POINTS;
	    es->totopp[0] = es->totopp[1] = NOT_REG_POINTS;
	  }
	else
	  GetTacticsForOpponent (*numinlist,tactics,es);
	
	(*numinlist)++;
	return TRUE;
      }
  return FALSE;
}

void CCia::GetTacticsForOpponent (int o,
				  int* tactics,
				  struct ExpectStruct* es)
{
  es->exme[0]   = es->exme[1]   = NOT_REG_POINTS;
  es->exopp[0]  = es->exopp[1]  = NOT_REG_POINTS;
  es->totme[0]  = es->totme[1]  = NOT_REG_POINTS;
  es->totopp[0] = es->totopp[1] = NOT_REG_POINTS;
  *tactics = 0;
  *(tactics+1) = 0;
  
  if (NameOfPlayers[o][0] != '\0')
    {
      for (int tac = 0; tac < NUMMETHODS; tac++)
	{
	  int tr1m, tr1o, tr2m, tr2o, er1m, er1o, er2m, er2o;
	  tr1m = tr1o = tr2m = tr2o = er1m = er1o = er2m = er2o = 0;
	  int div = 0;
	  
	  for (int k = 0; k < MEETPEROPP; k++)
	    if (points47[o][tac][0][k][0][0] != NOT_REG_POINTS)
	      {
		tr1m += points47[o][tac][0][k][1][0];
		tr1o += points47[o][tac][0][k][0][0];
		tr2m += points47[o][tac][1][k][1][0];
		tr2o += points47[o][tac][1][k][0][0];
		er1m += points47[o][tac][0][k][1][1];
		er1o += points47[o][tac][0][k][0][1];
		er2m += points47[o][tac][1][k][1][1];
		er2o += points47[o][tac][1][k][0][1];
		div++;
	      }
	  if (div > 0)
	    {
	      tr1m /= div;
	      tr1o /= div;
	      tr2m /= div;
	      tr2o /= div;
	      er1m /= div;
	      er1o /= div;
	      er2m /= div;
	      er2o /= div;
	    }
#ifndef LOOSE
	  if (tr1m+tr2m > es->totme[0]+es->totme[1])
#else
	  if (tr1m+tr2m > es->totme[0]+es->totme[1] &&
	      tr1m <= tr1o && tr2m <= tr2o)
#endif // LOOSE
	    {		
	      *tactics = tac+1;
	      *(tactics+1) = tac+1;
	      es->totme[0]    = tr1m;
	      es->totopp[0]   = tr1o;
	      es->totme[1]    = tr2m;
	      es->totopp[1]   = tr2o;
	      es->exme[0]    = er1m;
	      es->exopp[0]   = er1o;
	      es->exme[1]    = er2m;
	      es->exopp[1]   = er2o;
	    }
	}
    }
}

void CCia::GetBetterOppForOpponent (int o,
				    int* other,
				    struct ExpectStruct byother[],
				    struct ExpectStruct* es)
{
  int max = -1; // number of methods found - 1

  for (int i = 0; i < MAXNUMPLAYERS; i++)
    if (i != o && NameOfPlayers[i][0] != '\0')
      {
	int tr1h, tr1o, tr2h, tr2o; // h as in helper (the one I'll 'copy')
	tr1h = tr1o = tr2h = tr2o = 0;
	int div = 0;
	
	for (int k = 0; k < MEETPEROPP; k++)
	  if (points[i][o][0][k] != NOT_REG_POINTS)
	      {
		tr1h += points[i][o][0][k];
		tr2h += points[i][o][1][k];
		tr1o += points[o][i][0][k];
		tr2o += points[o][i][1][k];
		div++;
	      }
	  if (div > 0)
	    {
	      tr1h /= div;
	      tr1o /= div;
	      tr2h /= div;
	      tr2o /= div;
	    }
#ifndef LOOSE
	  if (tr1h+tr2h > es->totme[0]+es->totme[1])
#else
          if (tr1h+tr2h > es->totme[0]+es->totme[1] &&
	      tr1h <= tr1o && tr2h <= tr2o)
#endif // LOOSE
	    {		
	      if (max == -1 ||
		  tr1h+tr2h > byother[max].totme[0]+byother[max].totme[1])
		{
		  int insertat = (max == 4 ? 4 : max+1);
		  for (; insertat > 0; insertat--)
		    if (tr1h+tr2h <= byother[insertat-1].totme[0] + byother[insertat-1].totme[1])
		      break;
		  memmove (byother+insertat+1,byother+insertat,sizeof (byother[0]) * (max-insertat));
		  memmove (other+insertat+1,other+insertat,sizeof (other[0]) * (max-insertat));
		  other[insertat] = i+1;
		  byother[insertat].totme[0] = tr1h;
		  byother[insertat].totme[1] = tr2h;
		  byother[insertat].totopp[0] = tr1o;
		  byother[insertat].totopp[1] = tr2o;
		  max = (max == 4 ? 4 : max+1);
		}
	    }
      }
}


void CCia::CheckBestMethods ()
{
  int tactics[2];
  struct ExpectStruct es;  

  int other[5];
  struct ExpectStruct byother[5];

  for (int i = 0; i < MAXNUMPLAYERS; i++)
    if (NameOfPlayers[i][0] != '\0')
      {
	GetTacticsForOpponent (i,tactics,&es);
	
	memset (other,0,sizeof (other));
	GetBetterOppForOpponent (i,other,byother,&es);

	printf ("%16s | %5d %5d |",NameOfPlayers[i],es.totme[0],es.totme[1]);
	for (int j = 0; j < 5 && other[j]; j++)
	  printf ("(%2d) %5d %5d ",other[j],byother[j].totme[0],byother[j].totme[1]);
	printf ("\n");
      }
}

char syscallbuffer[60000];

void CCia::CheckNameDependence ()
{
  char buf[1000];

  for (int i = 0; i < MAXNUMPLAYERS; i ++)
    if (NameOfPlayers[i][0] != '\0')
      {
	sprintf (buf,"spelare%d.o",i+1);

	FILE* in;
	int k = 0;

	if ((in = fopen (buf,"r")) != NULL)
	  {
	    while (!feof (in) && k < 60000)
	      {
		syscallbuffer[k] = (char) fgetc (in);
		k++;
	      }
	    syscallbuffer[k] = '\0';
	    fclose (in);      
	  }
	for (int j = 0; j < MAXNUMPLAYERS; j ++)
	  if (i != j && NameOfPlayers[j][0] != '\0')
	    {
	      int length = strlen (NameOfPlayers[j]);
	      while (NameOfPlayers[j][length-1] == ' ')
		length--; 
	      for (int l = 0; l < k ; l++)
		if (strncmp (syscallbuffer+l,NameOfPlayers[j],length) == 0)
		  {
		    printf ("%16s -> %16s\n",NameOfPlayers[i],NameOfPlayers[j]);
		    break;
		  }
	    }
	for (int l = 0; l < k ; l++)
	  if (strncmp (syscallbuffer+l,"Mr Gaunt",8) == 0)
	    {
	      printf ("%16s -> %16s\n",NameOfPlayers[i],"Mr Gaunt        ");
	      break;
	    }
      }
}

void CCia::DumpActivePlayerNumbers (char* fileName)
{
  FILE *out;

  if ((out = fopen (fileName,"w")) == NULL)
    return;

  for (int i = 0; i < MAXNUMPLAYERS; i ++)
    if (NameOfPlayers[i][0] != '\0')
      fprintf (out,"%d ",i+1);
  fprintf (out,"47\n");
  fclose (out);
}

// a dirty helper: issue a unix command-line call when I couldn't find the appropriate C-function

// char syscallbuffer[20000];

char* syscall (char* what_to_do)
{
  char buf[1000];

  strcpy (buf,what_to_do);
  strcat (buf," > syscall_dumpfile");
  
  system (buf);
  FILE* in;

  syscallbuffer[0] = '\0';
  
  if ((in = fopen ("syscall_dumpfile","r")) != NULL)
    {
      int i = 0; 
      while ((syscallbuffer[i] = (char) fgetc (in)) != EOF && i < 60000)
	i++;
      syscallbuffer[i] = '\0';
      fclose (in);      
    }
  int i;

  for (i = 0; syscallbuffer[i] != '\0'; i++);
  for (int j = 0; j < 20; j++)
    syscallbuffer[i+j] = '\0';
  system ("rm syscall_dumpfile");
  return syscallbuffer;
}

long lstimetolong (char* lstime,int musthaveallread)
{
  if (*lstime == '\0')
    return -1;
  if (strstr (lstime,"No such file") != NULL)
    return -1;
  if (lstime[7] == '-' && musthaveallread)
    return -1;
  //  if (lstime[9] == '-' && musthaveallread)
  //  return -1;

  lstime += 41;

  int month;
  if (strncmp (lstime,"Jan",3) == 0)
    month = 1;
  else if (strncmp (lstime,"Feb",3) == 0)
    month = 2;
  else if (strncmp (lstime,"Mar",3) == 0)
    month = 3;
  else if (strncmp (lstime,"Apr",3) == 0)
    month = 4;
  else if (strncmp (lstime,"May",3) == 0)
    month = 5;
  else if (strncmp (lstime,"Jun",3) == 0)
    month = 6;
  else if (strncmp (lstime,"Jul",3) == 0)
    month = 7;
  else if (strncmp (lstime,"Aug",3) == 0)
    month = 8;
  else if (strncmp (lstime,"Sep",3) == 0)
    month = 9;
  else if (strncmp (lstime,"Oct",3) == 0)
    month = 10;
  else if (strncmp (lstime,"Nov",3) == 0)
    month = 11;
  else if (strncmp (lstime,"Dec",3) == 0)
    month = 12;
  else
    return -1;
  //    printf ("lstimetolong () unknown month %s",lstime);
  //  printf ("%d %d %d %d\n",month,atoi(lstime+4),atoi(lstime+7),atoi(lstime+10));
  return atoi(lstime+10)+atoi(lstime+7)*60L+atoi(lstime+4)*60L*24L+month*60L*24L*31L;
}

char* strtolower (char* str,char breakchar)
{
  for (int i = 0; str[i] != '\0' && str[i] != breakchar; i++)
    str[i] = (char) tolower (str[i]);
}

void SayName (char* name)
{
  char buf[100];

  //  sprintf (buf,"say %s",name);
  //  syscall (buf);
} 

int GoodEnough (int mP,int oP) // oP as in oldPoints
{
  if (mP > 100 && mP > oP*1.02)
    return TRUE;
  return mP - oP > 7;
}

Tillbaka till huvudsidan