Ejemplo n.º 1
1
bool
apply_move (Game *g, int from, int to, char promote_in)
{
  if (g->result != IN_PROGRESS) return FALSE;
  Board *board = current_board (g);
  Board *new_board = NEW_BOARD;
  char capture = 0;
  char *move_done = castling (board, castling_type (board, from, to), new_board);
  if (!move_done) // If move is not a castling
    {
      if (!try_move (board, from, to, promote_in, new_board, &move_done, &capture))
        {
          free (new_board);
          return FALSE;
        }
    }
  // Ok move is legal, update the game
  update_castling (new_board, from);
  update_en_passant (new_board, from, to);
  if (new_board->active_color)
    new_board->fullmove_number++;
  new_board->active_color = !new_board->active_color;
  if (capture || toupper (board->placement[from]) == 'P')
    new_board->halfmove_clock = 0;
  else
    new_board->halfmove_clock++;
  g->boards[g->current] = new_board;
  g->moves[g->current] = move_done;
  g->coord_moves[g->current] = ft_to_coord_move (from, to, promote_in);
  g->current++;
  // Test check or checkmate of opponent king
  if (king_in_check (new_board, new_board->active_color))
    {
      if (king_in_checkmate (new_board, new_board->active_color))
        {
          strcat (move_done, "#");
          g->result = !new_board->active_color;
        }
      else
        strcat (move_done, "+");
    }
  // Test insufficient material
  else if (insufficient_material (new_board))
    g->result = DRAW;
  // Test stalemate
  else if (stalemate (new_board, new_board->active_color))
    g->result = DRAW;
  return TRUE;
}
Ejemplo n.º 2
0
bool Board::toFEN(char * fen) const
{
  if ( !fen )
    return false;

  char * s = fen;

  // 1 - write figures
  for (int y = 7; y >= 0; --y)
  {
    int n = 0;
    for (int x = 0; x < 8; ++x)
    {
      Index idx(x, y);
      const Field & field = getField(idx);
      if ( !field )
      {
        ++n;
        continue;
      }

      if ( n > 0 )
      {
        *s++ = '0' + n;
        n = 0;
      }

      char c = fromFtype(field.type());
      if ( field.color() == Figure::ColorBlack )
        c = tolower(c);

      *s++ = c;
    }
    
    if ( n > 0 )
      *s++ = '0' + n;

    if ( y > 0 )
      *s++ = '/';
  }

  // 2 - color to move
  {
    *s++ = ' ';
    if ( Figure::ColorBlack == color_ )
      *s++ = 'b';
    else
      *s++ = 'w';
  }

  // 3 - castling possibility
  {
    *s++ = ' ';
	  if ( !castling() )
    {
      *s++ = '-';
    }
    else
    {
      if ( castling_K() )
      {
        if ( !verifyCastling(Figure::ColorWhite, 0) )
          return false;

        *s++ = 'K';
      }
      if ( castling_Q() )
      {
        if ( !verifyCastling(Figure::ColorWhite, 1) )
          return false;

        *s++ = 'Q';
      }
      if ( castling_k() )
      {
        if ( !verifyCastling(Figure::ColorBlack, 0) )
          return false;
        
        *s++ = 'k';
      }
      if ( castling_q() )
      {
        if ( !verifyCastling(Figure::ColorBlack, 1) )
          return false;

        *s++ = 'q';
      }
    }
  }

  {
    // 4 - en passant
    *s++ = ' ';
    if ( en_passant_ >= 0 )
    {
      Index ep_pos(en_passant_);

      int x = ep_pos.x();
      int y = ep_pos.y();

      if ( color_ )
        y--;
      else
        y++;

      Index pawn_pos(x, y);
      const Field & ep_field = getField(pawn_pos);
      if ( ep_field.color() == color_ || ep_field.type() != Figure::TypePawn )
        return false;

      char cx = 'a' + ep_pos.x();
      char cy = '1' + ep_pos.y();
      *s++ = cx;
      *s++ = cy;
    }
    else
      *s++ = '-';

    // 5 - fifty move rule
    {
      *s++ = ' ';
      char str[8];
      _itoa(fiftyMovesCount_, str, 10);
      char * sf = str;
      for ( ; *sf; ++sf, ++s)
        *s = *sf;
    }

    // 6 - moves counter
    {
      *s++ = ' ';
      char str[8];
      _itoa(movesCounter_, str, 10);
      char * sf = str;
      for ( ; *sf; ++sf, ++s)
        *s = *sf;
    }
  }

  // terminal
  *s++ = 0;

  return true;
}
Ejemplo n.º 3
0
bool Board::validMove(int srcX, int srcY, int destx, int desty) //determines if move is valid
{
		bool collisionLegal = false;
		bool typeMoveLegal = false;
		bool sameTeam = true;

		int idPiece = boardarray[srcX][srcY];
		int srcPiece = idPiece;
		if(srcPiece >= 0 && srcPiece <= 15) //special condition for pawn transformations
		{
			if(pieceArray[srcPiece]->getPawnTrans())
			{
				srcPiece = pieceArray[idPiece]->getPieceRule();
			}

		}
		
		int destPiece = boardarray[destx][desty]; //neccessary variables
		int srcPieceColor = 0;
		int destPieceColor = 0;
		bool whiteColorsrc = pieceArray[srcPiece]->getWhite();
		bool whiteColorDest = false;
		bool checkMove = true;
		int colorTurn = 0;

		if(turn)  //sets piece color, true is white
			colorTurn = 1;
		else
			colorTurn = 2;

		if(whiteColorsrc) srcPieceColor = 1; 
			else srcPieceColor = 2;

		if(colorTurn == srcPieceColor){					//checks for whose turn it is

			
			if(destPiece != -1){						//fixes OutofIndex error
				whiteColorDest = pieceArray[destPiece]->getWhite();

				if(whiteColorDest) destPieceColor = 1;		//checks for friendly fire
				else destPieceColor = 2;
			}
			else destPieceColor = 3;

			if(srcPieceColor == destPieceColor)
				sameTeam = false;
			
			typeMoveLegal = pieceArray[srcPiece]->moveLegal(destx, desty, srcX, srcY, destPiece); 
			collisionLegal = collision(destx, desty, srcX, srcY);		

			
			if(srcPiece == 31 || srcPiece == 30) //special instance for castling
				castling(&typeMoveLegal, srcX, srcY, destx, desty, srcPiece);

		
			if(typeMoveLegal && collisionLegal && turn) //legal move, white turn, checks if king is in check
			{
				if(isCheck(pieceArray[WHITEKING]->getX(), pieceArray[WHITEKING]->getY(), destx, desty, srcX, srcY))
				{
					checkMove = false;
				}
				else
					check = false;
			}
			else if(typeMoveLegal && collisionLegal && !turn) //legal move, black turn, checks if king is in check
			{
				if(isCheck(pieceArray[BLACKKING]->getX(), pieceArray[BLACKKING]->getY(), destx, desty, srcX, srcY))
				{
					checkMove = false;//sets valid move to false if king is still hypothetically in check, preventing your move from happening
				}
				else
					check = false;
			}	

	
			//EN PASSANT
			if((srcPiece >= 0 && srcPiece <= 15))
			//if((srcPiece >= 0 || srcPiece <= 17) && collisionLegal && sameTeam && checkMove)
			{
				enPassant(&typeMoveLegal, srcX, srcY, destx, desty, srcPiece, whiteColorsrc, srcPieceColor);
			}

			if(srcPiece >= 20 && srcPiece <= 23)
				collisionLegal = true;
	
			if(typeMoveLegal && collisionLegal && sameTeam && checkMove)//everything is true - valid move
			{
				if(srcPiece >= 0 && srcPiece <= 15){			//checks if that pawn is moved to other side
					if(whiteColorsrc && desty == 0){			//for white peices
						pieceArray[srcPiece]->setTransform();
					}
					if(!whiteColorsrc && desty == 7){			//for black pieces
						pieceArray[srcPiece]->setTransform();
					}
				}

				if(idPiece == 30 || idPiece == 31 || (idPiece <= 27 && idPiece >= 24) || (idPiece >= 0 && idPiece <= 15))
					pieceArray[srcPiece]->setFirstMoved();	
				moveCount++;
				turn = !turn;
				return true;
			}
		}

		return false; //false if move not valid
	
		
}