// MOBILITY heuristic: safe squares around king of color color.
int mobility(position_t *p, color_t color) {
  char* laser_map;
  if (color == WHITE) {
    laser_map = laser_map_black;
  } else {
    laser_map = laser_map_white;
  }
  int mobility = 0;
  square_t king_sq = p->kloc[color];
  tbassert(ptype_of(p->board[king_sq]) == KING,
           "ptype: %d\n", ptype_of(p->board[king_sq]));
  tbassert(color_of(p->board[king_sq]) == color,
           "color: %d\n", color_of(p->board[king_sq]));

  if (laser_map[king_sq] == 0) {
    mobility++;
  }
  for (int d = 0; d < 8; ++d) {
    square_t sq = king_sq + dir_of(d);
    if (laser_map[sq] == 0) {
      mobility++;
    }
  }
  return mobility;
}
// KFACE heuristic: bonus (or penalty) for King facing toward the other King
ev_score_t kface(position_t *p, fil_t f, rnk_t r) {
  square_t sq = square_of(f, r);
  piece_t x = p->board[sq];
  color_t c = color_of(x);
  square_t opp_sq = p->kloc[opp_color(c)];
  int delta_fil = fil_of(opp_sq) - f;
  int delta_rnk = rnk_of(opp_sq) - r;
  int bonus;

  switch (ori_of(x)) {
    case NN:
      bonus = delta_rnk;
      break;

    case EE:
      bonus = delta_fil;
      break;

    case SS:
      bonus = -delta_rnk;
      break;

    case WW:
      bonus = -delta_fil;
      break;

    default:
      bonus = 0;
      tbassert(false, "Illegal King orientation.\n");
  }

  return (bonus * KFACE) / (abs(delta_rnk) + abs(delta_fil));
}
示例#3
0
// KAGGRESSIVE heuristic: bonus for King with more space to back
ev_score_t kaggressive(position_t *p, rnk_t r, fil_t f, full_board_t* board) {
  piece_t x = get_piece(p, r, f, board);
  color_t c = color_of(x);
  tbassert(ptype_of(x) == KING, "ptype_of(x) = %d\n", ptype_of(x));

  square_t opp_sq = board->pieces[opp_color(c)][0];
  fil_t of = fil_of(opp_sq);
  rnk_t _or = (rnk_t) rnk_of(opp_sq);

  int delta_fil = of - f;
  int delta_rnk = _or - r;

  int bonus = 0;

  if (delta_fil >= 0 && delta_rnk >= 0) {
    bonus = (f + 1) * (r + 1);
  } else if (delta_fil <= 0 && delta_rnk >= 0) {
    bonus = (BOARD_WIDTH - f) * (r + 1);
  } else if (delta_fil <= 0 && delta_rnk <= 0) {
    bonus = (BOARD_WIDTH - f) * (BOARD_WIDTH - r);
  } else if (delta_fil >= 0 && delta_rnk <= 0) {
    bonus = (f + 1) * (BOARD_WIDTH - r);
  }

  return (KAGGRESSIVE * bonus) / (BOARD_WIDTH * BOARD_WIDTH);
}
示例#4
0
// KFACE heuristic: bonus (or penalty) for King facing toward the other King
ev_score_t kface(position_t *p, rnk_t r, fil_t f, full_board_t* board) {
  piece_t x = get_piece(p, r, f, board);
  color_t c = color_of(x);
  square_t opp_sq = board->pieces[opp_color(c)][0];
  int delta_fil = fil_of(opp_sq) - f;
  int delta_rnk = rnk_of(opp_sq) - r;
  int bonus;

  switch (ori_of(x)) {
    case NN:
      bonus = delta_rnk;
      break;

    case EE:
      bonus = delta_fil;
      break;

    case SS:
      bonus = -delta_rnk;
      break;

    case WW:
      bonus = -delta_fil;
      break;

    default:
      bonus = 0;
      tbassert(false, "Illegal King orientation.\n");
  }

  return (bonus * KFACE) / (abs(delta_rnk) + abs(delta_fil));
}
// KAGGRESSIVE heuristic: bonus for King with more space to back
ev_score_t kaggressive_old(position_t *p, fil_t f, rnk_t r) {
  square_t sq = square_of(f, r);
  piece_t x = p->board[sq];
  color_t c = color_of(x);
  tbassert(ptype_of(x) == KING, "ptype_of(x) = %d\n", ptype_of(x));

  square_t opp_sq = p->kloc[opp_color(c)];
  fil_t of = fil_of(opp_sq);
  rnk_t _or = (rnk_t) rnk_of(opp_sq);

  int delta_fil = of - f;
  int delta_rnk = _or - r;

  int bonus = 0;

  if (delta_fil >= 0 && delta_rnk >= 0) {
    bonus = (f + 1) * (r + 1);
  } else if (delta_fil <= 0 && delta_rnk >= 0) {
    bonus = (BOARD_WIDTH - f) * (r + 1);
  } else if (delta_fil <= 0 && delta_rnk <= 0) {
    bonus = (BOARD_WIDTH - f) * (BOARD_WIDTH - r);
  } else if (delta_fil >= 0 && delta_rnk <= 0) {
    bonus = (f + 1) * (BOARD_WIDTH - r);
  }

  return (KAGGRESSIVE * bonus) / (BOARD_WIDTH * BOARD_WIDTH);
}
示例#6
0
文件: polybook.c 项目: syzygy1/Cfish
static Key polyglot_key(const Pos *pos)
{
  Key key = 0;
  Bitboard b = pieces();

  while (b) {
    Square s = pop_lsb(&b);
    Piece p = piece_on(s);

    // PolyGlot pieces are: BP = 0, WP = 1, BN = 2, ... BK = 10, WK = 11
    key ^= PG.Zobrist.psq[2 * (type_of_p(p) - 1) + (color_of(p) == WHITE)][s];
  }

  b = can_castle_any();

  while (b)
    key ^= PG.Zobrist.castle[pop_lsb(&b)];

  if (ep_square())
    key ^= PG.Zobrist.enpassant[file_of(ep_square())];

  if (pos_stm() == WHITE)
    key ^= PG.Zobrist.turn;

  return key;
}
示例#7
0
void
signal_printer_message_public_highlight(gpointer *params)
{
	session *sess   = params[0];
	gchar *from     = params[1];
	gchar *message  = params[2];
	gchar *nickchar = params[3];
	gchar *idtext   = params[4];
	gint nickcolor  = color_of(from);
	gchar *temp = g_strdup_printf("\x03%d%s\x03", nickcolor, from);
	gchar *nick;

	if (prefs.coloredhnicks)
	{
		nick = g_strdup(temp);
		g_free(temp);
	}
	else
	{
		nick = g_strdup(from);
	}

	session_print_format(sess, "channel msg hilight", nick, nickchar, idtext, message);
	g_free(nick);
}
示例#8
0
void
signal_printer_message_private(gpointer *params)
{
	session *sess  = params[0];
	gchar *from    = params[1];
	gchar *message = params[2];
	gchar *idtext  = params[3];
	gint nickcolor  = color_of(from);
	gchar *temp = g_strdup_printf("\x03%d%s\x03", nickcolor, from);
	gchar *nick;

	if (prefs.colorednicks)
	{
		nick = g_strdup(temp);
		g_free(temp);
	}
	else
	{
		nick = g_strdup(from);
	}

	if (sess->type == SESS_DIALOG) {
		session_print_format(sess, "private message to dialog", nick, message, idtext);
	} else {
		session_print_format(sess, "private message", nick, message, idtext);
	}
        g_free(nick);
}
// Marks the path of the laser until it hits a piece or goes off the board. 
// Returns the number of unpinned pawns.
//
// p : current board state
// laser_map : end result will be stored here. Every square on the
//             path of the laser is marked with mark_mask
// c : color of king shooting laser
// mark_mask: what each square is marked with
int mark_laser_path(position_t *p, char *laser_map, color_t c,
                     char mark_mask) {
  int pinned_pawns = 0;
  uint8_t total_pawns;
  color_t color = opp_color(c);
  square_t o_king_sq = p->kloc[color];

  if (c == WHITE) { // opposing king pins our pawns 
    total_pawns = p->pawn_count[BLACK];
  } else {
    total_pawns = p->pawn_count[WHITE];
  }

  // Fire laser, recording in laser_map
  square_t sq = p->kloc[c];
  int bdir = ori_of(p->board[sq]);
  int beam = beam_of(bdir);

  tbassert(ptype_of(p->board[sq]) == KING,
           "ptype: %d\n", ptype_of(p->board[sq]));
  laser_map[sq] |= mark_mask;

  // we update h_attackable here
  h_attackable = h_dist(sq, o_king_sq);

  while (true) {
    sq += beam;
    laser_map[sq] |= mark_mask;
    tbassert(sq < ARR_SIZE && sq >= 0, "sq: %d\n", sq);

    switch (ptype_of(p->board[sq])) {
      case EMPTY:  // empty square
        h_attackable += h_dist(sq, o_king_sq);
        break;
      case PAWN:  // Pawn
        h_attackable += h_dist(sq, o_king_sq);
        if (color_of(p->board[sq]) == color) {
          pinned_pawns += 1;
        }
        bdir = reflect_of(bdir, ori_of(p->board[sq]));
        if (bdir < 0) {  // Hit back of Pawn
          return total_pawns - pinned_pawns;
        }
        beam = beam_of(bdir);
        break;
      case KING:  // King
        h_attackable += h_dist(sq, o_king_sq);
          return total_pawns - pinned_pawns;
        break;
      case INVALID:  // Ran off edge of board
        return total_pawns - pinned_pawns;
        break;
      default:  // Shouldna happen, man!
        tbassert(false, "Not cool, man.  Not cool.\n");
        break;
    }
  }
}
示例#10
0
MoveStack* generate<EVASIONS>(const Position& pos, MoveStack* mlist) {

  assert(pos.checkers());

  Square from, checksq;
  int checkersCnt = 0;
  Color us = pos.side_to_move();
  Square ksq = pos.king_square(us);
  Bitboard sliderAttacks = 0;
  Bitboard b = pos.checkers();

  assert(pos.checkers());

  // Find squares attacked by slider checkers, we will remove them from the king
  // evasions so to skip known illegal moves avoiding useless legality check later.
  do
  {
      checkersCnt++;
      checksq = pop_lsb(&b);

      assert(color_of(pos.piece_on(checksq)) == ~us);

      switch (type_of(pos.piece_on(checksq)))
      {
      case BISHOP: sliderAttacks |= PseudoAttacks[BISHOP][checksq]; break;
      case ROOK:   sliderAttacks |= PseudoAttacks[ROOK][checksq];   break;
      case QUEEN:
          // If queen and king are far or not on a diagonal line we can safely
          // remove all the squares attacked in the other direction becuase are
          // not reachable by the king anyway.
          if (between_bb(ksq, checksq) || !(PseudoAttacks[BISHOP][checksq] & ksq))
              sliderAttacks |= PseudoAttacks[QUEEN][checksq];

          // Otherwise we need to use real rook attacks to check if king is safe
          // to move in the other direction. For example: king in B2, queen in A1
          // a knight in B1, and we can safely move to C1.
          else
              sliderAttacks |= PseudoAttacks[BISHOP][checksq] | pos.attacks_from<ROOK>(checksq);

      default:
          break;
      }
  } while (b);

  // Generate evasions for king, capture and non capture moves
  b = pos.attacks_from<KING>(ksq) & ~pos.pieces(us) & ~sliderAttacks;
  from = ksq;
  SERIALIZE(b);

  if (checkersCnt > 1)
      return mlist; // Double check, only a king move can save the day

  // Generate blocking evasions or captures of the checking piece
  Bitboard target = between_bb(checksq, ksq) | pos.checkers();

  return generate_all<EVASIONS>(pos, mlist, us, target);
}
示例#11
0
static void
parse_nondirective(char *s)
{
    char *base = s;
    char *t;
    const char *attr0 = Ident_attr;
    const char *attr1 = Ident2_attr;
    char *attr2 = Literal_attr;

    if (FltOptions('c')) {
	t = skip_ident(s = base);
	if (t != s) {
	    int save = *t;

	    /* this parses one of
	     * "name"
	     * "name:class"
	     * "name:color"
	     */
	    parse_keyword(s, 0);

	    *t = 0;
	    attr0 = actual_color(s, abbr_len(s), 0);
	    *t = (char) save;
	}
	if (skip_eqls_ch(&t)) {
	    s = skip_ident(t);
	    if (s != t) {
		attr1 = actual_color(t, (int) (s - t), 1);
	    }
	}
    }

    t = skip_ident(s = base);
    flt_puts(s, (int) (t - s), attr0);
    if (parse_eqls_ch(&t)) {
	s = skip_ident(t);
	if (s != t) {
	    int save = *s;
	    *s = 0;
	    if (!FltOptions('c')) {
		if (*(attr1 = color_of(t, 0)) == '\0')
		    attr1 = Action_attr;
	    }
	    flt_puts(t, (int) strlen(t), attr1);
	    *s = (char) save;
	}
	if (parse_eqls_ch(&s)) {
	    flt_puts(s, (int) strlen(s), attr2);
	} else if (*s) {
	    flt_puts(s, (int) strlen(s), Error_attr);
	}
    } else if (*t) {
	flt_puts(t, (int) strlen(t), Error_attr);
    }
}
示例#12
0
// MOBILITY heuristic: safe squares around king of color color.
int mobility(position_t *p, color_t color, char* laser_map, full_board_t* board) {
  int mobility = 0;
  square_t king_sq = board->pieces[color][0];
  tbassert(ptype_of(board->board[king_sq]) == KING,
           "ptype: %d\n", ptype_of(board->board[king_sq]));
  tbassert(color_of(board->board[king_sq]) == color,
           "color: %d\n", color_of(board->board[king_sq]));

  if (laser_map[king_sq] == 0) {
    mobility++;
  }
  for (int d = 0; d < 8; ++d) {
    square_t sq = king_sq + dir_of(d);
    if (in_bounds(sq) && laser_map[sq] == 0) {
      mobility++;
    }
  }
  return mobility;
}
示例#13
0
int pawnpin(position_t *p, color_t color, square_t* laser_list, int laser_list_len, full_board_t* board) {
  int unpinned_pawns = board->pawn_count[color];

  for(int i = 1; i < laser_list_len; i++) {
    if (color_of(board->board[laser_list[i]]) == color && ptype_of(board->board[laser_list[i]]) == PAWN) {
      unpinned_pawns--;
    }
  }

  return unpinned_pawns;
}
示例#14
0
// H_SQUARES_ATTACKABLE heuristic: for shooting the enemy king
int h_squares_attackable(position_t *p, color_t c) {
  char* laser_map;
  if (c == WHITE) {
    laser_map = laser_map_white;
  } else {
    laser_map = laser_map_black;
  }
  square_t o_king_sq = p->kloc[opp_color(c)];
  tbassert(ptype_of(p->board[o_king_sq]) == KING,
           "ptype: %d\n", ptype_of(p->board[o_king_sq]));
  tbassert(color_of(p->board[o_king_sq]) != c,
           "color: %d\n", color_of(p->board[o_king_sq]));

  float h_attackable_temp = 0;
  for (fil_t f = 0; f < BOARD_WIDTH; f++) {
    for (rnk_t r = 0; r < BOARD_WIDTH; r++) {
      square_t sq = square_of(f, r);
      if (laser_map[sq] != 0) {
        h_attackable_temp += h_dist(sq, o_king_sq);
      }
    }
  }
  return h_attackable_temp;
}
示例#15
0
static score_t get_game_over_score(victims_t victims, int pov, int ply) {
  tbassert(ptype_of(victims.stomped) != KING, "Stomped a king.\n");
  score_t score;
  if (color_of(victims.zapped) == WHITE) {
    score = -WIN * pov;
  } else {
    score = WIN * pov;
  }
  if (score < 0) {
    score += ply;
  } else {
    score -= ply;
  }
  return score;
}
示例#16
0
// Translate a position struct into a fen string
// NOTE: When you use the test framework in search.c, you should modify this
// function to match your optimized board representation in move_gen.c
//
// Input:   (populated) position struct
//          empty string where FEN characters will be written
// Output:   null
int pos_to_fen(position_t *p, char *fen) {
  int pos = 0;
  int i;

  for (rnk_t r = BOARD_WIDTH - 1; r >=0 ; --r) {
    int empty_in_a_row = 0;
    for (fil_t f = 0; f < BOARD_WIDTH; ++f) {
      piece_t piece = get_piece(p, r, f, &base_board);
      if (ptype_of(piece) == INVALID) {     // invalid square
        tbassert(false, "Bad news, yo.\n");        // This is bad!
      }

      if (ptype_of(piece) == EMPTY) {       // empty square
        empty_in_a_row++;
        continue;
      } else {
        if (empty_in_a_row) fen[pos++] = '0' + empty_in_a_row;
        empty_in_a_row = 0;
        int ori = ori_of(piece);  // orientation
        color_t c = color_of(piece);

        if (ptype_of(piece) == KING) {
          for (i = 0; i < 2; i++) fen[pos++] = king_ori_to_rep[c][ori][i];
          continue;
        }

        if (ptype_of(piece) == PAWN) {
          for (i = 0; i < 2; i++) fen[pos++] = pawn_ori_to_rep[c][ori][i];
          continue;
        }
      }
    }
    // assert: for larger boards, we need more general solns
    tbassert(BOARD_WIDTH <= 10, "BOARD_WIDTH = %d\n", BOARD_WIDTH);
    if (empty_in_a_row == 10) {
      fen[pos++] = '1';
      fen[pos++] = '0';
    } else if (empty_in_a_row) {
      fen[pos++] = '0' + empty_in_a_row;
    }
    if (r) fen[pos++] = '/';
  }
  fen[pos++] = ' ';
  fen[pos++] = 'W';
  fen[pos++] = '\0';

  return pos;
}
示例#17
0
static const char *
actual_color(const char *param, int len, int arg)
{
    const char *result;
    char *s = strmalloc(param);

    if (len > 0) {		/* if not null-terminated, set it now */
	s[len] = '\0';
    }

    result = color_of(s, arg);
    if (*result == 0)
	result = keyword_attr(s);

    if (result != 0 && *result != 0 && !is_color(result)) {
	result = Literal_attr;
    }

    free(s);
    return result;
}
示例#18
0
ExtMove* generate<EVASIONS>(const Position& pos, ExtMove* mlist) {

  assert(pos.checkers());

  int checkersCnt = 0;
  Color us = pos.side_to_move();
  Square ksq = pos.king_square(us), from = ksq /* For SERIALIZE */, checksq;
  Bitboard sliderAttacks = 0;
  Bitboard b = pos.checkers();

  assert(pos.checkers());

  // Find all the squares attacked by slider checkers. We will remove them from
  // the king evasions in order to skip known illegal moves, which avoids any
  // useless legality checks later on.
  do
  {
      ++checkersCnt;
      checksq = pop_lsb(&b);

      assert(color_of(pos.piece_on(checksq)) == ~us);

      if (type_of(pos.piece_on(checksq)) > KNIGHT) // A slider
          sliderAttacks |= LineBB[checksq][ksq] ^ checksq;

  } while (b);

  // Generate evasions for king, capture and non capture moves
  b = pos.attacks_from<KING>(ksq) & ~pos.pieces(us) & ~sliderAttacks;
  SERIALIZE(b);

  if (checkersCnt > 1)
      return mlist; // Double check, only a king move can save the day

  // Generate blocking evasions or captures of the checking piece
  Bitboard target = between_bb(checksq, ksq) | checksq;

  return us == WHITE ? generate_all<WHITE, EVASIONS>(pos, mlist, target)
                     : generate_all<BLACK, EVASIONS>(pos, mlist, target);
}
示例#19
0
static void
ExecClass(char *param)
{
    char *t = strmalloc(param);
    char *s;
    const char *attr = "";

    parse_keyword(t, 1);
    free(t);
    t = flt_put_blanks(param);
    s = skip_ident(t);
    if (FltOptions('c')) {
	attr = actual_color(param, (int) (s - param), 1);
    } else {
	attr = Ident2_attr;
    }
    flt_puts(param, (int) (s - param), attr);
    if (parse_eqls_ch(&s)) {
	t = s;
	s = skip_ident(t);
	if (FltOptions('c')) {
	    attr = actual_color(t, (int) (s - t), 1);
	} else {
	    if (*(attr = color_of(t, 0)) == '\0')
		attr = Action_attr;
	}
	flt_puts(t, (int) (s - t), attr);
	if (parse_eqls_ch(&s)) {
	    flt_puts(s, (int) strlen(s), Literal_attr);
	} else if (*s) {
	    flt_puts(s, (int) strlen(s), Error_attr);
	}
    } else if (*s) {
	flt_puts(s, (int) strlen(s), Error_attr);
    }
}
示例#20
0
void
signal_printer_action_private_hilight(gpointer *params)
{
	session *sess   = params[0];
	gchar *from     = params[1];
	gchar *text     = params[2];
	gchar *nickchar = params[3];
	gint nickcolor  = color_of(from);
	gchar *temp = g_strdup_printf("\x03%d%s\x03", nickcolor, from);
	gchar *nick;

	if (prefs.coloredhnicks)
	{
		nick = g_strdup(temp);
		g_free(temp);
	}
	else
	{
		nick = g_strdup(from);
	}

	session_print_format(sess, "query action hilight", nick, nickchar, text);
	g_free(nick);
}
示例#21
0
bool move_is_legal(const Position& pos, Move move)
{

	Move m = move;
	assert(is_ok(m));	

	Color us = pos.side_to_move();
	Square from = from_sq(m);
	Square to   = to_sq(m);

	assert(color_of(pos.piece_moved(m)) == us);
	assert(pos.piece_on(pos.king_square(us)) == make_piece(us, KING));

	PieceType pfr = type_of(pos.piece_on(from));
	PieceType pto= type_of(pos.piece_on(to));

	Bitboard pawns   = pos.pieces(~us, PAWN);
	Bitboard knights = pos.pieces(~us, KNIGHT);
	Bitboard cannons = pos.pieces(~us, CANNON);
	Bitboard rooks = pos.pieces(~us, ROOK);

	Bitboard  occ    = pos.pieces();
	Bitboard  occl90 = pos.piecesl90();

	occl90 ^= square_rotate_l90_bb(from);
	occ    ^= from;

	if(pto == NO_PIECE_TYPE)
	{
		occl90 ^= square_rotate_l90_bb(to);
		occ    ^= to;
	}

	Square ksq = pos.king_square(us);
	if(ksq == from)
		ksq = to;

	if (pto != NO_PIECE_TYPE)
	{
		switch(pto)
		{
		case PAWN:
			pawns ^= to;
			break;
		case KNIGHT:
			knights ^= to;
			break;
		case ROOK:
			rooks ^= to;
			break;
		case CANNON:
			cannons ^= to;
			break;
		}
	}



	if((PseudoAttacks[ROOK][ksq]& cannons) &&(cannon_control_bb(ksq, occ,occl90) & cannons)) return false;
	if((PseudoAttacks[ROOK][ksq]& rooks) && (rook_attacks_bb(ksq,occ,occl90)& rooks) ) return false;
	if( knight_attackers_to_bb(ksq, knights, occ) ) return false;
	if( pos.attacks_from_pawn_nomask(ksq, us) & pawns ) return false;

	if((PseudoAttacks[ROOK][ksq]& pos.king_square(~us)) && (rook_attacks_bb(ksq,occ,occl90)& pos.king_square(~us))) return false;//╤таЁ

	return true;
}
示例#22
0
// Static evaluation.  Returns score
score_t eval(position_t *p, bool verbose) {
  // seed rand_r with a value of 1, as per
  // http://linux.die.net/man/3/rand_r
  static __thread unsigned int seed = 1;
  // verbose = true: print out components of score
  ev_score_t score[2] = { 0, 0 };
  //  int corner[2][2] = { {INF, INF}, {INF, INF} };
  ev_score_t bonus;

  //char buf[MAX_CHARS_IN_MOVE];
  color_t c;
  for (fil_t f = 0; f < BOARD_WIDTH; f++) {
    for (rnk_t r = 0; r < BOARD_WIDTH; r++) {
      square_t sq = square_of(f, r);
      piece_t x = p->board[sq];

      //if (verbose) {
      //  square_to_str(sq, buf, MAX_CHARS_IN_MOVE);
      //}

      switch (ptype_of(x)) {
        case EMPTY:
          break;
        case PAWN:
          c = color_of(x);

          // MATERIAL heuristic: Bonus for each Pawn
          bonus = PAWN_EV_VALUE;
          // if (verbose) {
          //  printf("MATERIAL bonus %d for %s Pawn on %s\n", bonus, color_to_str(c), buf);
          // }
          score[c] += bonus;

          // PBETWEEN heuristic
          bonus = pbetween(p, f, r);
          // if (verbose) {
          //   printf("PBETWEEN bonus %d for %s Pawn on %s\n", bonus, color_to_str(c), buf);
          // }
          score[c] += bonus;

          // PCENTRAL heuristic
          bonus = pcentral(f, r);
          // if (verbose) {
          //   printf("PCENTRAL bonus %d for %s Pawn on %s\n", bonus, color_to_str(c), buf);
         //  }
          score[c] += bonus;
          break;

        case KING:
          c = color_of(x);

          // KFACE heuristic
          bonus = kface(p, f, r);
          // if (verbose) {
          //   printf("KFACE bonus %d for %s King on %s\n", bonus,
          //          color_to_str(c), buf);
          // }
          score[c] += bonus;

          // KAGGRESSIVE heuristic
          color_t othercolor = opp_color(c);
          square_t otherking = p->kloc[othercolor];
          fil_t otherf = fil_of(otherking);
          rnk_t otherr = rnk_of(otherking);
          bonus = kaggressive(f, r, otherf, otherr);
          assert(bonus == kaggressive_old(p, f, r));

          // if (verbose) {
          //   printf("KAGGRESSIVE bonus %d for %s King on %s\n", bonus, color_to_str(c), buf);
         //  }
          score[c] += bonus;
          break;
        case INVALID:
          break;
        default:
          tbassert(false, "Jose says: no way!\n");   // No way, Jose!
      }
      laser_map_black[sq] = 0;
      laser_map_white[sq] = 0;
    }
  }
   
  int black_pawns_unpinned = mark_laser_path(p, laser_map_white, WHITE, 1);  // 1 = path of laser with no moves
  
  ev_score_t w_hattackable = HATTACK * (int) h_attackable;
  score[WHITE] += w_hattackable;
  // if (verbose) {
  //   printf("HATTACK bonus %d for White\n", w_hattackable);
  // }

  // PAWNPIN Heuristic --- is a pawn immobilized by the enemy laser.
  int b_pawnpin = PAWNPIN * black_pawns_unpinned;
  score[BLACK] += b_pawnpin;

  int b_mobility = MOBILITY * mobility(p, BLACK);
  score[BLACK] += b_mobility;
  // if (verbose) {
  //   printf("MOBILITY bonus %d for Black\n", b_mobility);
  // }

  int white_pawns_unpinned = mark_laser_path(p, laser_map_black, BLACK, 1);  // 1 = path of laser with no moves
  
  ev_score_t b_hattackable = HATTACK * (int) h_attackable;
  score[BLACK] += b_hattackable;
  // if (verbose) {
  //   printf("HATTACK bonus %d for Black\n", b_hattackable);
  // }

  int w_mobility = MOBILITY * mobility(p, WHITE);
  score[WHITE] += w_mobility;
  // if (verbose) {
  //   printf("MOBILITY bonus %d for White\n", w_mobility);
  // }
  int w_pawnpin = PAWNPIN * white_pawns_unpinned;
  score[WHITE] += w_pawnpin;


  // score from WHITE point of view
  ev_score_t tot = score[WHITE] - score[BLACK];

  if (RANDOMIZE) {
    ev_score_t  z = rand_r(&seed) % (RANDOMIZE*2+1);
    tot = tot + z - RANDOMIZE;
  }

  if (color_to_move_of(p) == BLACK) {
    tot = -tot;
  }

  return tot / EV_SCORE_RATIO;
}
示例#23
0
void
inbound_chanmsg (server *serv, char *chan, char *from, char *text, char fromme)
{
	struct User *user;
	session *sess;
	int hilight = FALSE;
	char nickchar[2] = "\000";

	if (chan)
	{
		sess = find_channel (serv, chan);
		if (!sess && !is_channel (serv, chan))
			sess = find_dialog (serv, chan);
	} else
	{
		sess = find_dialog (serv, from);
	}
	if (!sess)
		return;

	if (sess != current_tab)
	{
		sess->msg_said = TRUE;
		sess->new_data = FALSE;
	}

	user = find_name (sess, from);
	if (user)
	{
		nickchar[0] = user->prefix[0];
		user->lasttalk = time (0);
	}

	if (fromme)
	{
  		if (prefs.auto_unmark_away && serv->is_away)
			sess->server->p_set_back (sess->server);
		EMIT_SIGNAL (XP_TE_UCHANMSG, sess, from, text, nickchar, NULL, 0);
		return;
	}

	if (sess->type != SESS_DIALOG)
		if (prefs.beepchans || sess->beep)
			fe_beep ();

	if (is_hilight (text, sess, serv))
	{
		hilight = TRUE;
		if (prefs.beephilight)
			fe_beep ();
	}
	if (sess->type == SESS_DIALOG)
		EMIT_SIGNAL (XP_TE_DPRIVMSG, sess, from, text, NULL, NULL, 0);
	else if (hilight)
		EMIT_SIGNAL (XP_TE_HCHANMSG, sess, from, text, nickchar, NULL, 0);
	else if (prefs.colorednicks)
	{
		char tbuf[NICKLEN + 4];
		snprintf (tbuf, sizeof (tbuf), "\003%d%s", color_of (from), from);
		EMIT_SIGNAL (XP_TE_CHANMSG, sess, tbuf, text, nickchar, NULL, 0);
	}
	else
		EMIT_SIGNAL (XP_TE_CHANMSG, sess, from, text, nickchar, NULL, 0);
}
示例#24
0
static score_t get_game_over_score(victims_t* victims, int pov, int ply) {
  tbassert(ptype_of(victims->stomped) != KING, "Stomped a king.\n");
  // score negative when victims.zapped == WHITE
  score_t score = -1*(1 - 2*(color_of(victims->zapped)))*WIN*pov;
  return score + (1 - 2*(score >= 0))*ply;
}
示例#25
0
// Translate a fen string into a board position struct
//
int fen_to_pos(position_t *p, char *fen) {
  static position_t dmy1, dmy2;

  // these sentinels simplify checking previous
  // states without stepping past null pointers.
  dmy1.key = 0;
  dmy1.victims.stomped = 1;
  dmy1.victims.zapped = 1;
  dmy1.history = NULL;

  dmy2.key = 0;
  dmy2.victims.stomped = 1;
  dmy2.victims.zapped = 1;
  dmy2.history = &dmy1;


  p->key = 0;          // hash key
  p->victims.stomped = 0;       // piece destroyed by stomper
  p->victims.zapped = 0;       // piece destroyed by shooter
  p->history = &dmy2;  // history

  memset(&base_board, 0, sizeof(full_board_t));

  if (fen[0] == '\0') {  // Empty FEN => use starting position
    fen = "ss3nw5/3nw2nw3/2nw7/1nw6SE1/nw9/9SE/1nw6SE1/7SE2/3SE2SE3/5SE3NN W";
  }

  int c_count = 0;  // Invariant: fen[c_count] is next char to be read

  for (int i = 0; i < ARR_SIZE; ++i) {
    base_board.board[i] = INVALID_PIECE;
  }

  c_count = parse_fen_board(p, fen);
  if (!c_count) {
    return 1;  // parse error of board
  }

  // King check

  int Kings[2] = {0, 0};
  for (fil_t f = 0; f < BOARD_WIDTH; ++f) {
    for (rnk_t r = 0; r < BOARD_WIDTH; ++r) {
      square_t sq = square_of(r, f);
      piece_t x = base_board.board[sq];
      ptype_t typ = ptype_of(x);
      if (typ == KING) {
        Kings[color_of(x)]++;
      }
    }
  }

  if (Kings[WHITE] == 0) {
    fen_error(fen, c_count, "No White Kings");
    return 1;
  } else if (Kings[WHITE] > 1) {
    fen_error(fen, c_count, "Too many White Kings");
    return 1;
  } else if (Kings[BLACK] == 0) {
    fen_error(fen, c_count, "No Black Kings");
    return 1;
  } else if (Kings[BLACK] > 1) {
    fen_error(fen, c_count, "Too many Black Kings");
    return 1;
  }

  char c;
  bool done = false;
  // Look for color to move and set ply accordingly
  while (!done && (c = fen[c_count++]) != '\0') {
    switch (c) {
      // ignore whitespace until the end
      case ' ':
      case '\t':
      case '\n':
      case '\r':
        break;

        // White to move
      case 'W':
      case 'w':
        p->ply = 0;
        base_board.ply = 0;
        done = true;
        break;

        // Black to move
      case 'B':
      case 'b':
        p->ply = 1;
        base_board.ply = 1;
        done = true;
        break;

      default:
        fen_error(fen, c_count, "Must specify White (W) or Black (B) to move");
        return 1;
        break;
    }
  }

  // Look for last move, if it exists
  int lm_from_sq, lm_to_sq, lm_rot;
  if (get_sq_from_str(fen, &c_count, &lm_from_sq) != 0) {  // parse error
    return 1;
  }
  if (lm_from_sq == 0) {   // from-square of last move
    p->last_move = 0;  // no last move specified
    p->key = compute_zob_key(p, &base_board);
    return 0;
  }

  c = fen[c_count];

  switch (c) {
    case 'R':
    case 'r':
      lm_to_sq = lm_from_sq;
      lm_rot = RIGHT;
      break;
    case 'U':
    case 'u':
      lm_to_sq = lm_from_sq;
      lm_rot = UTURN;
      break;
    case 'L':
    case 'l':
      lm_to_sq = lm_from_sq;
      lm_rot = LEFT;
      break;

    default:  // Not a rotation
      lm_rot = NONE;
      if (get_sq_from_str(fen, &c_count, &lm_to_sq) != 0) {
        return 1;
      }
      break;
  }
  p->last_move = move_of(EMPTY, lm_rot, lm_from_sq, lm_to_sq);
  p->key = compute_zob_key(p, &base_board);

  return 0;  // everything is okay
}
示例#26
0
// Evaluate the move by performing a search.
void evaluateMove(searchNode *node, move_t mv, move_t killer_a,
                  move_t killer_b, searchType_t type,
                  uint64_t *node_count_serial, moveEvaluationResult* result) {
  int ext = 0;  // extensions
  bool blunder = false;  // shoot our own piece

  result->next_node.subpv[0] = 0;
  result->next_node.parent = node;

  // Make the move, and get any victim pieces.
  bool isko = make_move(&(node->position), &(result->next_node.position), mv);

  // Check whether this move changes the board state.
  //   such moves are not legal.
  if (isko) {
    result->type = MOVE_ILLEGAL;
    return;
  }

  victims_t* victims = &result->next_node.position.victims;

  // Check whether the game is over.
  if (is_game_over(victims, node->pov, node->ply)) {
    // Compute the end-game score.
    result->type = MOVE_GAMEOVER;
    result->score = get_game_over_score(victims, node->pov, node->ply);
    return;
  }

  // Ignore noncapture moves when in quiescence.
  if (zero_victims(victims) && node->quiescence) {
    result->type = MOVE_IGNORE;
    return;
  }

  // Check whether the board state has been repeated, this results in a draw.
  if (is_repeated(&(result->next_node.position), node->ply)) {
    result->type = MOVE_GAMEOVER;
    result->score = get_draw_score(&(result->next_node.position), node->ply);
    return;
  }

  tbassert(victims->stomped == 0
           || color_of(victims->stomped) != node->fake_color_to_move,
           "stomped = %d, color = %d, fake_color_to_move = %d\n",
           victims->stomped, color_of(victims->stomped),
           node->fake_color_to_move);


  // Check whether we caused our own piece to be zapped. This isn't considered
  //   a blunder if we also managed to stomp an enemy piece in the process.
  if (victims->stomped == 0 &&
      victims->zapped > 0 &&
      color_of(victims->zapped) == node->fake_color_to_move) {
    blunder = true;
  }

  // Do not consider moves that are blunders while in quiescence.
  if (node->quiescence && blunder) {
    result->type = MOVE_IGNORE;
    return;
  }

  // Extend the search-depth by 1 if we captured a piece, since that means the
  //   move was interesting.
  if (victim_exists(victims) && !blunder) {
    ext = 1;
  }

  // Late move reductions - or LMR. Only done in scout search.
  int next_reduction = 0;
  if (type == SEARCH_SCOUT && node->legal_move_count + 1 >= LMR_R1 && node->depth > 2 &&
      zero_victims(victims) && mv != killer_a && mv != killer_b) {
    if (node->legal_move_count + 1 >= LMR_R2) {
      next_reduction = 2;
    } else {
      next_reduction = 1;
    }
  }

  result->type = MOVE_EVALUATED;
  int search_depth = ext + node->depth - 1;

  // Check if we need to perform a reduced-depth search.
  //
  // After a reduced-depth search, a full-depth search will be performed if the
  //  reduced-depth search did not trigger a cut-off.
  if (next_reduction > 0) {
    search_depth -= next_reduction;
    int reduced_depth_score = -scout_search(&(result->next_node), search_depth,
                                            node_count_serial);
    if (reduced_depth_score < node->beta) {
      result->score = reduced_depth_score;
      return;
    }
    search_depth += next_reduction;
  }

  // Check if we should abort due to time control.
  if (abortf) {
    result->score = 0;
    result->type = MOVE_IGNORE;
    return;
  }


  if (type == SEARCH_SCOUT) {
    result->score = -scout_search(&(result->next_node), search_depth,
                                 node_count_serial);
  } else {
    if (node->legal_move_count == 0 || node->quiescence) {
      result->score = -searchPV(&(result->next_node), search_depth, node_count_serial);
    } else {
      result->score = -scout_search(&(result->next_node), search_depth,
                            node_count_serial);
      if (result->score > node->alpha) {
        result->score = -searchPV(&(result->next_node), node->depth + ext - 1, node_count_serial);
      }
    }
  }
}
示例#27
0
void
inbound_action (session *sess, char *chan, char *from, char *text, int fromme)
{
	session *def = sess;
	server *serv = sess->server;
	int beep = FALSE;
	int hilight = FALSE;

	if (!fromme)
	{
		if (is_channel (serv, chan))
		{
			sess = find_channel (serv, chan);
			beep = prefs.beepchans;
		} else
		{
			/* it's a private action! */
			beep = prefs.beepmsg;
			/* find a dialog tab for it */
			sess = find_dialog (serv, from);
			/* if non found, open a new one */
			if (!sess && prefs.autodialog)
				sess = new_ircwindow (serv, from, SESS_DIALOG);
		}
	}

	if (!sess)
		sess = def;

	if (sess != current_tab)
	{
		if (fromme)
		{
			sess->msg_said = FALSE;
			sess->new_data = TRUE;
		} else
		{
			sess->msg_said = TRUE;
			sess->new_data = FALSE;
		}
	}

	if (!fromme)
	{
		hilight = is_hilight (text, sess, serv);
		if (hilight && prefs.beephilight)
			beep = TRUE;

		if (beep || sess->beep)
			fe_beep ();

		if (hilight)
		{
			EMIT_SIGNAL (XP_TE_HCHANACTION, sess, from, text, NULL, NULL, 0);
			return;
		}
	}

	if (prefs.colorednicks)
	{
		char tbuf[NICKLEN + 4];
		snprintf (tbuf, sizeof (tbuf), "\003%d%s", color_of (from), from);
		EMIT_SIGNAL (XP_TE_CHANACTION, sess, tbuf, text, NULL, NULL, 0);
	} else
	{
		EMIT_SIGNAL (XP_TE_CHANACTION, sess, from, text, NULL, NULL, 0);
	}
}