Пример #1
0
void Position::UnmakeMove()
{
	if (m_undoSize == 0) return;

	Undo& undo = m_undos[--m_undoSize];
	Move mv = undo.m_mv;
	m_ep = undo.m_ep;
	m_castlings = undo.m_castlings;
	m_fifty = undo.m_fifty;

	FLD from = mv.From();
	FLD to = mv.To();
	PIECE piece = mv.Piece();
	PIECE captured = mv.Captured();
	COLOR side = m_side ^ 1;

	m_hash ^= s_hashSide[1];

	Remove(to);
	Put(from, piece);
	if (captured)
	{
		if (to == m_ep)
			Put(to + 8 - 16 * side, captured);
		else
			Put(to, captured);
	}

	--m_ply;
	m_side ^= 1;

	if (piece == KW)
	{
		m_Kings[WHITE] = from;
		if (from == E1 && to == G1)
		{
			Remove(F1);
			Put(H1, RW);
		}
		else if (from == E1 && to == C1)
		{
			Remove(D1);
			Put(A1, RW);
		}
	}
	else if (piece == KB)
	{
		m_Kings[BLACK] = from;
		if (from == E8 && to == G8)
		{
			Remove(F8);
			Put(H8, RB);
		}
		else if (from == E8 && to == C8)
		{
			Remove(D8);
			Put(A8, RB);
		}
	}
}
Пример #2
0
bool Position::MakeMove(Move mv)
{
  Undo& undo = _undos[_undoSize++];
  undo.m_castlings = m_castlings;
  undo.m_ep = m_ep;
  undo.m_fifty = m_fifty;
  undo.m_hash = m_hash;
  undo.m_mv = mv;

  FLD from = mv.From();
  FLD to = mv.To();
  PIECE piece = mv.Piece();
  PIECE captured = mv.Captured();
  PIECE promotion = mv.Promotion();

  COLOR side = m_side;
  COLOR opp = side ^ 1;
  m_hash ^= s_hashSide[1];

  ++m_fifty;
  if (captured)
  {
    m_fifty = 0;
    if (to == m_ep)
      Remove(to + 8 - 16 * side);
    else
      Remove(to);
  }
  Remove(from);
  Put(to, piece);

  m_ep = NF;
  switch (piece)
  {
  case PW:
  case PB:
    m_fifty = 0;
    if (to - from == -16 + 32 * side)
      m_ep = to + 8 - 16 * side;
    else if (promotion)
    {
      Remove(to);
      Put(to, promotion);
    }
    break;

  case KW:
    m_Kings[WHITE] = to;
    if (from == E1)
    {
      if (to == G1)
      {
        Remove(H1);
        Put(F1, RW);
        m_castlings ^= WHITE_DID_O_O;
      }
      else if (to == C1)
      {
        Remove(A1);
        Put(D1, RW);
        m_castlings ^= WHITE_DID_O_O_O;        
      }
    }
    break;

  case KB:
    m_Kings[BLACK] = to;
    if (from == E8)
    {
      if (to == G8)
      {
        Remove(H8);
        Put(F8, RB);
        m_castlings ^= BLACK_DID_O_O;        
      }
      else if (to == C8)
      {
        Remove(A8);
        Put(D8, RB);
        m_castlings ^= BLACK_DID_O_O_O;        
      }
    }
    break;

  default:
    break;
  }

  static const U8 castlingDelta[64] =
  {
    0xf7, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xfb,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xfe
  };

  m_castlings &= castlingDelta[from];
  m_castlings &= castlingDelta[to];

  ++m_ply;
  m_side ^= 1;
  
  if (IsAttacked(m_Kings[side], opp))
  {
    UnmakeMove();
    return false;
  }

  return true;
}
Пример #3
0
string MoveToStrShort(Move mv, Position& pos, MoveList* mvlist)
{
  if (mv.Piece() == KW && mv.From() == E1 && mv.To() == G1) return "O-O";
  if (mv.Piece() == KW && mv.From() == E1 && mv.To() == C1) return "O-O-O";
  if (mv.Piece() == KB && mv.From() == E8 && mv.To() == G8) return "O-O";
  if (mv.Piece() == KB && mv.From() == E8 && mv.To() == C8) return "O-O-O";

  FLD from = mv.From();
  FLD to = mv.To();
  PIECE piece = mv.Piece();
  PIECE captured = mv.Captured();
  PIECE promotion = mv.Promotion();

  string strPiece, strFrom, strTo, strCapture, strPromotion;
  switch (piece)
  {
    case PW: case PB: break;
    case NW: case NB: strPiece = "N"; break;
    case BW: case BB: strPiece = "B"; break;
    case RW: case RB: strPiece = "R"; break;
    case QW: case QB: strPiece = "Q"; break;
    case KW: case KB: strPiece = "K"; break;
    default: break;
  }

  strTo = FldToStr(to);
  if (captured)
  {
    strCapture = "x";
    if (piece == PW || piece == PB)
      strFrom = FldToStr(from).substr(0, 1);
  }

  switch (promotion)
  {
    case QW: case QB: strPromotion += "=Q"; break;
    case RW: case RB: strPromotion += "=R"; break;
    case BW: case BB: strPromotion += "=B"; break;
    case NW: case NB: strPromotion += "=N"; break;
  }

  bool ambiguity = false;
  bool uniqRow = true;
  bool uniqCol = true;

  if (piece != PW && piece != PB)
  {
    for (MoveList* ptr = mvlist; ptr->mv; ++ptr)
    {
      Move mv1 = ptr->mv;

      if (mv1 == mv) continue;
      if (mv1.To() != to) continue;
      if (mv1.Piece() != piece) continue;

      if (!pos.MakeMove(mv1)) continue;
      pos.UnmakeMove();

      ambiguity = true;
      if (Row(mv1.From()) == Row(from)) uniqRow = false;
      if (Col(mv1.From()) == Col(from)) uniqCol = false;
    }
  }

  if (ambiguity)
  {
    if (uniqCol)
      strFrom = FldToStr(from).substr(0, 1);
    else if (uniqRow)
      strFrom = FldToStr(from).substr(1, 1);
    else
      strFrom = FldToStr(from);
  }

  return strPiece + strFrom + strCapture + strTo + strPromotion;
}
Пример #4
0
std::string MoveToStrShort(Move mv, Position& pos)
{
	if (mv == Move(E1, G1, KW) || mv == Move(E8, G8, KB))
		return "O-O";
	if (mv == Move(E1, C1, KW) || mv == Move(E8, C8, KB))
		return "O-O-O";

	PIECE piece = mv.Piece();
	FLD from = mv.From();
	FLD to = mv.To();
	PIECE captured = mv.Captured();
	PIECE promotion = mv.Promotion();
	std::string strFrom, strTo, strPiece, strCaptured, strPromotion;

	switch (piece)
	{
	case PW: case PB:
		if (captured)
			strFrom = FldToStr(from).substr(0, 1);
		break;
	case NW: case NB: strPiece = "N"; break;
	case BW: case BB: strPiece = "B"; break;
	case RW: case RB: strPiece = "R"; break;
	case QW: case QB: strPiece = "Q"; break;
	case KW: case KB: strPiece = "K"; break;
	default: break;
	}

	if (captured)
		strCaptured = "x";

	strTo = FldToStr(to);

	switch (promotion)
	{
	case QW: case QB: strPromotion = "=Q"; break;
	case RW: case RB: strPromotion = "=R"; break;
	case BW: case BB: strPromotion = "=B"; break;
	case NW: case NB: strPromotion = "=N"; break;
	default: break;
	}

	// resolve ambiguity

	int uniq_col = 1;
	int uniq_row = 1;
	bool ambiguity = false;

	int row0 = Row(from);
	int col0 = Col(from);

	MoveList mvlist;
	mvlist.GenAllMoves(pos);

	for (int i = 0; i < mvlist.Size(); ++i)
	{
		Move mvi = mvlist[i].m_mv;

		if (mvi.To() != to)
			continue;
		if (mvi.Piece() != piece)
			continue;
		if (mvi.From() == from)
			continue;
		if (!pos.MakeMove(mvi))
			continue;
		pos.UnmakeMove();

		ambiguity = true; // two or more pieces of the same type can move to field
		int row1 = Row(mvi.From());
		int col1 = Col(mvi.From());

		if (row0 == row1)
			uniq_row = 0;

		if (col0 == col1)
			uniq_col = 0;
	}

	if (ambiguity)
	{
		if (uniq_col)
			strFrom = FldToStr(from).substr(0, 1);
		else if (uniq_row)
			strFrom = FldToStr(from).substr(1, 1);
		else
			strFrom = FldToStr(from);
	}

	return strPiece + strFrom + strCaptured + strTo + strPromotion;
}