/* Pepito v1.59  -- file: main.c --
   Copyright (c) 2000-01 Carlos del Cacho

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   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.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Contact the author: guggenjaimito@yahoo.com
*/

#ifndef UNIQUE_SOURCE_FILE
#  include <string.h>
#  include <signal.h>
#  include "datos.h"
#endif

#define JUG   tab.jug_stack

static int book_flag;

//--------------------------------
/*void termina(int sig)
{
  tab.time_up = 1;
  signal(SIGTERM, termina);
} */
//-----------------------------------------------------------------------
void            PintaBitBoard(register entero64 bb)
{
    register entero64 b = 1;
    register char   contador = 1;

    while (b) {
        if (b & bb)
            Print("1");
        else
            Print("0");
        if (!(contador++ % 8))
            Print("\n");
        b <<= 1;
    }

    Print("\n");
    return;
}
//------------------------------------
void AnunciaJugada(entero32 jug)
{
    Print("move ");
    PintaJugadaCoord(jug);
    Print("\n");
}
//------------------------------------
void MueveEnRaiz(entero32 jug, int book_flag)
{
    Mueve(jug);
    RNumJug = NumJug;
    Historial[NumJug-1].status |= book_flag;
    CambiaTurno();
    GeneraValidas(1);

    tab.rpiezasB = PiezasB;
    tab.rpiezasN = PiezasN;
    tab.rmat_diff = MaterialB - MaterialN;
}
//------------------------------------
void ParseInput(entero32 jug)
{
    if (!xb_info.active)
        Print("\r%s", prompt);
    ReadString(entrada);
    if (*entrada == '?')
    {
        AnunciaJugada(jug);
        MueveEnRaiz(jug, book_flag);
    }
    else if (!ParseCommandLine(entrada)) {
           if ((Turno != xb_info.my_color || xb_info.force) && LeeJugada(entrada, &jug))
              MueveEnRaiz(jug, NO_BOOK_MOVES);
           else
              Print("Illegal move: %s\n", entrada);
    }
}

//-------------------------------------------------------------------------
int             main()
{
    int             num,
                    i;
    entero32        jug = 0;

    srand(time(NULL));
    tab.trans_tab = NULL;
    tab.trans_tab_p = NULL;

    prompt = "Pepito> ";

    signal(SIGINT, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    setbuf(stdout, NULL);
    setbuf(stdin, NULL);

    Config();

    if ((tab.trans_tab = (entrada_hash *) malloc((long) sizeof(entrada_hash) * HASH_SIZE)) == NULL)
        exit(1);

    if ((tab.trans_tab_p = (entrada_hash_p *) malloc((long) sizeof(entrada_hash_p) * PAWN_HASH_SIZE)) == NULL)
        exit(1);

    if ((tab.eval_cache = (ecache *) malloc((long) sizeof(ecache) * CACHE_SIZE)) == NULL)
        exit(1);

    InitDirec(DIRECCION);
    InitMasks(MASK, FILA, COLUMNA, ENTRE, IZQUIERDA, DERECHA);
    Init_MSB(MSB, LSB);
    InitMaskPeones(AISLADO, PASADO);
    InitPasAlejados(PAS_ALEJA_D, PAS_ALEJA_I);

    InitRayos(RAYO_N, RAYO_S, RAYO_O, RAYO_E, RAYO_SE, RAYO_SO, RAYO_NE, RAYO_NO);
    InitTaxiCab(TAXI_CAB);
    InitValores();

    InitAtqTorreFil(ATAQUES_TORRE_FIL);
    InitAtqTorreCol(ATAQUES_TORRE_COL, ATAQUES_TORRE_FIL);
    InitAtqAlfil315(ATAQUES_ALFIL_315, ATAQUES_TORRE_FIL);
    InitAtqAlfil45(ATAQUES_ALFIL_45, ATAQUES_TORRE_FIL);
    InitAtqCaballo(ATAQUES_CABALLO);
    InitAtqRey(ATAQUES_REY, ATAQUES_TORRE_FIL, ATAQUES_TORRE_COL,
               ATAQUES_ALFIL_315, ATAQUES_ALFIL_45);
    InitAtqPeones(ATAQUES_PEON_B, ATAQUES_PEON_N);
    InitCasillaPeon();

    for (num = 0; num < 64; num++) {
        VACIO_ALFIL[num] = AtaquesTeoricosAlfil(num);
        VACIO_TORRE[num] = AtaquesTeoricosTorre(num);
    }

    PosicionInicial();
    InitPos(1);

    xb_info.force = 1;
    xb_info.my_clock = xb_info.opp_clock = xb_info.base;
    xb_info.ponder_on = 0;
    xb_info.post = 1;

    tab.analyzing = 0;
    for (;;) {

        while (UCI_MODE) {
            ReadString(entrada);
            ParseCommandLine(entrada);
        }

        if (!xb_info.force)
        {
           if (Turno == xb_info.my_color) {
                Itera(&jug, 0, AllocTime(xb_info.mv_ctrl, NumJug, xb_info.my_clock, xb_info.inc), &book_flag);
                if (tab.time_up == 2)
                  ;
                else if (tab.time_up == 3) {
                   Print("resign\n");
                   xb_info.force = 1;
                } else {
                   AnunciaJugada(jug);
                   MueveEnRaiz(jug, book_flag);
                }
           }

           if (xb_info.ponder_on && NumJug && !book_flag && !xb_info.force) {
                 CONTROL_INC = 50000;
                 if (ProbeHash(&tab.ponder_mv.jug, &i, &i, &i, &i) && tab.ponder_mv.jug) {
                       tab.guessed = 0;
                       tab.ponder_mv.pieza_mov = Tablero[tab.ponder_mv.jug & 0x3f];
                       Kibitz("Pondering: ");
                       PintaJugada(&tab.ponder_mv, Kibitz);
                       Kibitz("\n");
                       Mueve(tab.ponder_mv.jug);
                       CambiaTurno();
                       GeneraValidas(0);
                       if (tab.max_stack[0] != JugStack)
                           Itera(&jug, 1, ~(1 << 31), &book_flag);

                       if (!tab.guessed) {
                           CambiaTurno();
                           DesMueve();
                           GeneraValidas(1);
                       } else
                       {
                          AnunciaJugada(jug);
                          MueveEnRaiz(jug, book_flag);
                       }
                 }
           }
        }

        do
          ParseInput(jug);
        while (FullInput());
    }                           // for (;;)
}                               // main


