/*>>> x_sc1.c: the SC1 (Stanback Chess Program [external]) subsystem */

/* Revised: 1993.05.16 */

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

#include "sandef.h"
#include "sanvar.h"

#include "sanfen.h"
#include "sanmne.h"
#include "sanutl.h"

#include "x_sc1.h"

/**** Locals */

/* interface control point */

liT SC1 (sepT sep, charptrT av[]);

/* interface string argument storage */

static charptrT sc1av[8];

/*--> SC1: test */
nonstatic
liT
SC1 (sepT sep, charptrT av[])
{
  liT result;
  charptrT s;
  siT i;

#if (1)
/*DEBUG */
  {
    mptrT mptr;

    if (sep != sep_select)
      result = 0;
    else
      {
	mptr = curr_g.g_base + (rand () % curr_g.g_gmvc);
	result = ((mptr->m_tosq << sqQ) | mptr->m_frsq);
	switch (mptr->m_scmv)
	  {
	  case scmv_ppq:
	    result |= (1 << sqsqQ);
	    break;

	  case scmv_ppr:
	    result |= (2 << sqsqQ);
	    break;

	  case scmv_ppb:
	    result |= (3 << sqsqQ);
	    break;

	  case scmv_ppn:
	    result |= (4 << sqsqQ);
	    break;

	  default:
	    break;
	  };
      };
    return (result);
  }
#endif

  i = 0;
  printf ("SC1: sep: %hd\n", sep);
  while ((s = av[i++]) != NULL)
    printf ("arg: %s\n", s);
  printf ("enter result\n");
  scanf ("%ld", &result);

  return (result);
}

/*--> SC1Init: one time call to initialize the SC1 subsystem */
nonstatic
void
SC1Init (void)
{
  sc1av[0] = NULL;
  SC1 (sep_init, sc1av);

  return;
}

/*--> SC1Term: one time call to terminate the SC1 subsystem */
nonstatic
void
SC1Term (void)
{
  sc1av[0] = NULL;
  SC1 (sep_term, sc1av);

  return;
}

/*--> SC1NewGame: send "new game" request to the SC1 subsystem */
nonstatic
void
SC1NewGame (void)
{
  sc1av[0] = NULL;
  SC1 (sep_newgame, sc1av);

  return;
}

/*--> SC1SelectMove: select a move */
nonstatic
void
SC1Select (void)
{
  liT move;

  sc1av[0] = NULL;
  move = SC1 (sep_select, sc1av);

/* bits: 14-12: promotion, 11-6: tosq, 5-0: frsq */

  select_m.m_flag = 0;

  select_m.m_frsq = move & sqM;
  select_m.m_frcp = gb.bv[select_m.m_frsq];

  select_m.m_tosq = (move >> sqQ) & sqM;
  select_m.m_tocp = gb.bv[select_m.m_tosq];

/* construct special cased move code */

  switch ((move >> sqsqQ) & 0x07)
    {
    case 0:
      switch (select_m.m_frcp)
	{
	case cp_wp:
	case cp_bp:
	  if ((select_m.m_tosq == curr_e.e_epsq) &&
	      (map_file_sq (select_m.m_frsq) !=
	       map_file_sq (select_m.m_tosq)))
	    select_m.m_scmv = scmv_epc;
	  else
	    select_m.m_scmv = scmv_reg;
	  break;

	case cp_wk:
	  if ((select_m.m_frsq == sq_e1) &&
	      (select_m.m_tosq == sq_g1))
	    select_m.m_scmv = scmv_cks;
	  else if ((select_m.m_frsq == sq_e1) &&
		   (select_m.m_tosq == sq_c1))
	    select_m.m_scmv = scmv_cqs;
	  else
	    select_m.m_scmv = scmv_reg;
	  break;

	case cp_bk:
	  if ((select_m.m_frsq == sq_e8) &&
	      (select_m.m_tosq == sq_g8))
	    select_m.m_scmv = scmv_cks;
	  else if ((select_m.m_frsq == sq_e8) &&
		   (select_m.m_tosq == sq_c8))
	    select_m.m_scmv = scmv_cqs;
	  else
	    select_m.m_scmv = scmv_reg;
	  break;

	default:
	  select_m.m_scmv = scmv_reg;
	  break;
	};
      break;

    case 1:
      select_m.m_scmv = scmv_ppq;
      break;

    case 2:
      select_m.m_scmv = scmv_ppr;
      break;

    case 3:
      select_m.m_scmv = scmv_ppb;
      break;

    case 4:
      select_m.m_scmv = scmv_ppn;
      break;
    };

  return;
}

/*--> SC1Play: send "play move" request to the SC1 subsystem */
nonstatic
void
SC1Play (void)
{
  siT move;
  char b0v[16];
  char b1v[16];

/* SAN goes first */

  SANEncode (&prev_m, b0v);

/* bits: 14-12: promotion, 11-6: tosq, 5-0: frsq */

  move = prev_m.m_frsq | (prev_m.m_tosq << sqQ);
  switch (prev_m.m_scmv)
    {
    case scmv_ppq:
      move |= (1 << sqsqQ);
      break;

    case scmv_ppr:
      move |= (2 << sqsqQ);
      break;

    case scmv_ppb:
      move |= (3 << sqsqQ);
      break;

    case scmv_ppn:
      move |= (4 << sqsqQ);
      break;

    default:
      break;
    };
  sprintf (b1v, "%hd", move);

/* set arguments */

  sc1av[0] = b0v;
  sc1av[1] = b1v;
  sc1av[2] = NULL;
  SC1 (sep_play, sc1av);

  return;
}

/*--> SC1Unplay: send "unplay move" request to the SC1 subsystem */
nonstatic
void
SC1Unplay (void)
{
  sc1av[0] = NULL;
  SC1 (sep_unplay, sc1av);

  return;
}

/*--> SC1SetPos: send "set position" request to the SC1 subsystem */
nonstatic
void
SC1SetPos (void)
{
  charptrT fenptr;
  sqT sq;
  cpT cp;
  char b0v[tL];
  char b1v[(sqL * 2) + 1];
  char b2v[2];
  char b3v[(rcL * flankL) + 1];
  char b4v[3];
  char b5v[4];
  char b6v[4];

/* FEN first */

  fenptr = SANFENGen ();
  strcpy (b0v, fenptr);
  SANMemFree (fenptr);

/* easy scan board */

  for (sq = sq_a1; sq <= sq_h8; sq++)
    {
      cp = gb.bv[sq];
      if (cp == cp_v0)
	{
	  b1v[(sq * 2) + 0] = ' ';
	  b1v[(sq * 2) + 1] = ' ';
	}
      else
	{
	  b1v[(sq * 2) + 0] = map_lower (accv[cv_c_cpv[cp]]);
	  b1v[(sq * 2) + 1] = map_upper (acpv[cv_p_cpv[cp]]);
	};
    };
  b1v[sqL * 2] = '\0';

/* active color */

  sprintf (b2v, "%c", map_upper (accv[curr_e.e_actc]));

/* castling availability */

  sprintf (b3v, "%1hd%1hd%1hd%1hd",
	   ((curr_e.e_cast & cast_wk) ? 1 : 0),
	   ((curr_e.e_cast & cast_wq) ? 1 : 0),
	   ((curr_e.e_cast & cast_bk) ? 1 : 0),
	   ((curr_e.e_cast & cast_bq) ? 1 : 0));

/* en passant target square */

  sprintf (b4v, "%hd", curr_e.e_epsq);

/* halfmove clock */

  sprintf (b5v, "%hd", curr_e.e_hmvc);

/* fullmove number */

  sprintf (b6v, "%hd", curr_e.e_fmvn);

/* set arguments */

  sc1av[0] = b0v;
  sc1av[1] = b1v;
  sc1av[2] = b2v;
  sc1av[3] = b3v;
  sc1av[4] = b4v;
  sc1av[5] = b5v;
  sc1av[6] = b6v;
  sc1av[7] = NULL;
  SC1 (sep_setpos, sc1av);

  return;
}

/*--> SC1Config: send "re-configuration" request to the SC1 subsystem */
nonstatic
void
SC1Config (void)
{
  char b0v[16];
  char b1v[16];

  sprintf (b0v, "%ld", artsec);
  sprintf (b1v, "%hd", level);

/* set arguments */

  sc1av[0] = b0v;
  sc1av[1] = b1v;
  sc1av[2] = NULL;
  SC1 (sep_config, sc1av);

  return;
}

/* x_sc1.c: EOF */
