#include "chess.h"
 
#include "data.h"
 
/* last modified 02/24/14 */
 
/*
 
 *******************************************************************************
 
 *                                                                             *
 
 *   ResignOrDraw() is used to determine if the program should either resign   *
 
 *   or offer a draw.  This decision is based on two criteria:  (1) current    *
 
 *   search evaluation and (2) time remaining on opponent's clock.             *
 
 *                                                                             *
 
 *   The evaluation returned by the last search must be less than the resign   *
 
 *   threshold to trigger the resign code, or else must be exactly equal to    *
 
 *   the draw score to trigger the draw code.                                  *
 
 *                                                                             *
 
 *   The opponent must have enough time to be able to win or draw the game if  *
 
 *   it were played out as well.                                               *
 
 *                                                                             *
 
 *******************************************************************************
 
 */
 
void ResignOrDraw(TREE * RESTRICT tree, int value) {
 
  int v, result = 0;
 
 
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  If the game is a technical draw, where there are no     *
 
 *  pawns and material is balanced, then offer a draw.      *
 
 *                                                          *
 
 ************************************************************
 
 */
 
  if (Drawn(tree, value) == 1)
 
    result = 2;
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  First check to see if the increment is 2 seconds or     *
 
 *  more.  If so, then the game is being played slowly      *
 
 *  enough that a draw offer or resignation is worth        *
 
 *  consideration.  Otherwise, if the opponent has at least *
 
 *  30 seconds left, he can probably play the draw or win   *
 
 *  out.                                                    *
 
 *                                                          *
 
 *  If the value is below the resignation threshold, then   *
 
 *  Crafty should resign and get on to the next game. Note  *
 
 *  that it is necessary to have a bad score for            *
 
 *  <resign_count> moves in a row before resigning.         *
 
 *                                                          *
 
 *  Note that we don't resign for "deep mates" since we do  *
 
 *  not know if the opponent actually saw that result.  We  *
 
 *  play on until it becomes obvious he "sees it."          *
 
 *                                                          *
 
 ************************************************************
 
 */
 
  if ((tc_increment > 200) || (tc_time_remaining[Flip(root_wtm)] >= 3000)) {
 
    if (resign) {
 
      if (value < -(MATE - 15)) {
 
        if (++resign_counter >= resign_count)
 
          result = 1;
 
      } else if (value < -resign * 100 && value > -32000) {
 
        if (++resign_counter >= resign_count)
 
          result = 1;
 
      } else
 
        resign_counter = 0;
 
    }
 
  }
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  If the value is almost equal to the draw score, then    *
 
 *  Crafty should offer the opponent a draw.  Note that it  *
 
 *  is necessary that the draw score occur on exactly       *
 
 *  <draw_count> moves in a row before making the offer.    *
 
 *  Note also that the draw offer will be repeated every    *
 
 *  <draw_count> moves so setting this value too low can    *
 
 *  make the program behave "obnoxiously."                  *
 
 *                                                          *
 
 ************************************************************
 
 */
 
  if ((tc_increment > 200) || (tc_time_remaining[Flip(root_wtm)] >= 3000)) {
 
    if (Abs(Abs(value) - Abs(DrawScore(game_wtm))) < 2 &&
 
        moves_out_of_book > 3) {
 
      if (++draw_counter >= draw_count) {
 
        draw_counter = 0;
 
        result = 2;
 
      }
 
    } else
 
      draw_counter = 0;
 
  }
 
/*
 
 ************************************************************
 
 *                                                          *
 
 *  Now print the draw offer or resignation if appropriate  *
 
 *  but be sure and do it in a form that ICC/FICS will      *
 
 *  understand if the "xboard" flag is set.                 *
 
 *                                                          *
 
 *  Note that we also use the "speak" facility to verbally  *
 
 *  offer draws or resign if the "speech" variable has been *
 
 *  set to 1 by entering "speech on".                       *
 
 *                                                          *
 
 ************************************************************
 
 */
 
  if (result == 1) {
 
    learn_value = (crafty_is_white) ? -300 : 300;
 
    LearnBook();
 
    if (xboard)
 
      Print(4095, "resign\n");
 
    if (audible_alarm)
 
    if (speech) {
 
      char announce[128];
 
 
 
      if (v <= 0)
 
        perror("ResignOrDraw() system() error: ");  
    }
 
    if (crafty_is_white) {
 
      Print(4095, "0-1 {White resigns}\n");
 
    } else {
 
      Print(4095, "1-0 {Black resigns}\n");
 
    }
 
  }
 
  if (offer_draws && result == 2) {
 
    draw_offered = 1;
 
    if (!xboard) {
 
      Print(1, "\nI offer a draw.\n\n");
 
      if (audible_alarm)
 
      if (speech) {
 
        char announce[128];
 
 
 
        strcat(announce
, "Drawoffer");  
        if (v <= 0)
 
          perror("ResignOrDraw() system() error: ");  
      }
 
    } else if (xboard)
 
      Print(4095, "offer draw\n");
 
    else
 
      Print(4095, "\n*draw\n");
 
  } else
 
    draw_offered = 0;
 
}