Ejemplo n.º 1
0
/*
 *Validates a move in a given direction from current position
 */
int validateMove(BoardNode currentBoard, int moveRow, int moveCol, int currRow, int currCol, int distance)  {
    if(distance > MAXDISTOCHECK) { return 1;}
    if(checkBounds(currRow+moveRow,currCol+moveCol))    {
        switch(distance)    {
            case    NEIGHDIS:
                    if(getButtonStatus(currentBoard,currRow+moveRow,currCol+moveCol) == ALIVE)  {
                        if(validateMove(currentBoard,moveRow,moveCol,currRow+moveRow,currCol+moveCol,++distance))   {
                            return 1;
                        }
                    }
                    break;
            case    MAXDISTOCHECK:
                    if(getButtonStatus(currentBoard,currRow+moveRow,currCol+moveCol) == DEAD)   {
                        if(validateMove(currentBoard,moveRow,moveCol,currRow+moveRow,currCol+moveCol,++distance))   {
                            return 1;
                        }
                    }
                    break;
            default:

                    return 0;
        }
    }
    return 0;
}
Ejemplo n.º 2
0
/*
 * Calls functions required for generating moves depending on program mode
 */
int generatePossibleMove(BoardNode currentBoard)    {

    int row, col;

    for(row = 0; row < MAXROW; row++)   {
        for(col = 0; col < MAXCOL; col++)   {
            if(getButtonStatus(currentBoard,row,col) == ALIVE)  {

                if(validateMove(currentBoard,DONTMV,MVRIGHT,row, col,NEIGHDIS)) {
					if(getMode() == ZHASH)	{
                   		generateUniqueBoardHash(currentBoard,DONTMV,MVRIGHT,row,col); 		//!extended Zobrist Hash
					} else if(getMode() == BHASH)	{
                   		generateUniqueBoardBitHash(currentBoard,DONTMV,MVRIGHT,row,col); 	//! Extended bit Hash 
					} else {
                   		generateUniqueBoardWithMove(currentBoard,DONTMV,MVRIGHT,row,col); 	//!Basic
					}
                }

				if(validateMove(currentBoard,DONTMV,MVLEFT,row, col,NEIGHDIS))   {
					if(getMode() == ZHASH)	{
                    	generateUniqueBoardHash(currentBoard,DONTMV,MVLEFT,row,col);		//!extended Zobrist Hash
					} else if(getMode() == BHASH)	{
                    	generateUniqueBoardBitHash(currentBoard,DONTMV,MVLEFT,row,col);		//! Extended bit Hash
					} else {
                    	generateUniqueBoardWithMove(currentBoard,DONTMV,MVLEFT,row,col); 	//!Basic 
					}                                                                                            
               	}                                                                       
                                                                                                                 
				if(validateMove(currentBoard,MVUP,DONTMV,row,col,NEIGHDIS))  {         
					if(getMode() == ZHASH)	{
                    	generateUniqueBoardHash(currentBoard,MVUP,DONTMV,row,col);		//!extended Zobrist Hash
					} else if(getMode() == BHASH)	{
                    	generateUniqueBoardBitHash(currentBoard,MVUP,DONTMV,row,col); 	//! Extended bit Hash
					} else {
                    	generateUniqueBoardWithMove(currentBoard,MVUP,DONTMV,row,col);  //!Basic
					}
                }

	 			if(getMode() == LINEAR)	{
					if(validateMove(currentBoard,MVDOWN,DONTMV,row,col,NEIGHDIS))    {
       					   	generateUniqueBoardWithMove(currentBoard,MVDOWN,DONTMV,row,col); //!Basic move down
      				}
				}
            }
        }
    }
    return 1;
}
Ejemplo n.º 3
0
// verify is there draw or mat
void Board::verifyState()
{
  if ( matState() || drawState() )
    return;

#ifndef NDEBUG
  Board board0(*this);
#endif

  MovesGenerator mg(*this);
  bool found = false;
  for ( ; !found; )
  {
    const Move & m = mg.move();
    if ( !m )
      break;

    if ( validateMove(m) )
      found = true;
  }

  if ( !found )
  {
    setNoMoves();

    // update move's state because it is last one
    if ( halfmovesCounter_ > 0 )
    {
      UndoInfo & undo = undoInfo(halfmovesCounter_-1);
      undo.state_ = state_;
    }
  }
}
Ejemplo n.º 4
0
bool ChessBoard::checkIfCanMoveTo( PieceColor color, int to_x, int to_y ) {

  std::vector<Piece*> toCheck;

  if( color == WHITE ) {
    toCheck = whitePieces;
  }
  else {
    toCheck = blackPieces;
  }

  for( std::vector<Piece*>::iterator it = toCheck.begin(); it != toCheck.end(); ++it ) {

    if( (*it)->inPlay ) {

      Move m((*it)->x, (*it)->y, to_x, to_y);
      
      Piece* piece = getPiece( (*it)->x, (*it)->y );
      if( piece->type == QUEEN ) {
	std::cout << "Checking if queen on: x: " << piece->x << " y: " <<piece->y << ". can move to x: " << to_x << " y: " << to_y << "\n";
      } 
      
      if( validateMove( m ) ){
	return true;
      }
    }
  }
  if( color == WHITE ) std::cout << "white cant move to: ";
  else std::cout << "black cant move to: ";
  
  std::cout << " x: "<< to_x << " y: " << to_y << "\n";
  return false;
}
Ejemplo n.º 5
0
/** When a target square is clicked, this event is prompted
*  (it is attached to every enabled target square button's onClick).
*	We execute the given move for the selected chess piece and clicked target using the
*	logic layer and mark them as possible targets on board.
*/
void onTargetClick(GuiButton* button)
{
	// Each target button caches a game square in its extent, so it can access the logic layer
	GameSquare* gameSquare = (GameSquare*)button->generalProperties.extent;

	if (NULL == gameSquare)
		return; // Avoid null extents

	GameControl* gameControl = gameSquare->gameControl;
	int guiStartX = boardRowIndexToGuiRowIndex(gameControl->selectedSquare->x);
	int guiTargetX = boardRowIndexToGuiRowIndex(gameSquare->x);

	// Build the move
	// Make sure to abort clicks on illegal moves
	Position initPos = { guiStartX, gameControl->selectedSquare->y };
	Position nextPos = { guiTargetX, gameSquare->y };
	Move* move = createMove(&initPos, &nextPos);
	if ((g_memError) || (NULL == move))
		return;

	// If a pawn have reached the other edge, we have a promotion move.
	// Show the promotion dialog and wait for results.
	// Since this event can only be prompted by a player, we can count on the isBlackPlayerEditable property
	if (isSquareOnOppositeEdge(gameControl->isBlackPlayerEditable, nextPos.x) &&
		isSquareOccupiedByPawn(gameControl->board, gameControl->isBlackPlayerEditable, initPos.x, initPos.y))
	{
		move->promotion = showPromotionDialog(button->generalProperties.window, gameControl->isBlackPlayerEditable);
	}

	// Black king is an error value of showPromotionDialog (this is an invalid promotion). We quit on errors.
	if (g_guiError || g_memError || (move->promotion == BLACK_K))
	{
		deleteMove(move);
		return;
	}

	// Validate the move is legal
	bool isValidMove = validateMove(gameControl->board, gameControl->isBlackPlayerEditable, move);
	if (!isValidMove)
	{
		printf("Error: Gui allowed user to interact with illegal move, but logic protected from executing this move.\n");
		deleteMove(move);
		return;
	}

	GuiWindow* window = (GuiWindow*)button->generalProperties.window;

	// Execute the move and update the gui. If the game is over, return.
	bool isGameOver = executeGuiTurn(window, gameControl, move);
	if (isGameOver)
		return;

	// When playing against the AI, execute the next turn
	if (g_gameMode == GAME_MODE_PLAYER_VS_AI)
		executeGuiNextComputerMove(window);
}
Ejemplo n.º 6
0
STATUS CChessGame :: playMoveOnBoard(BOARD_POSITION init, BOARD_POSITION dest, 
                                     CHESSPIECE_GENERAL newCp,
                                     MOVE_CLAIM mClaim = CLAIM_NONE)
{
    STATUS status;
    CHECK_STATUS cStatus;
    MOVELIST *mList, *tempList;
    CZobrist zob;
    UINT64 currentHash;
    UINT8 count = 1, currentSeqNum;
    
    status = validateMove(init, dest, MVT_GENERAL);

    if((status & MOVE_PAWN_PROMOTED) && 
        newCp == CHESSPIECE_TYPE(INVALID_CHESSPIECE))
    {
        //pawn promotion should provide new piece also
        if(playerType[gState.turn] != PT_COMPUTER)
        {
            newCp = getNewPieceFromUser();
        }
        else
        {
            status = MOVE_ILLEGAL;
        }
    }
    
    if(status & MOVE_SUCCESS)
    {
        (void)makeMove(init, dest, newCp, status);
        
        mList = (MOVELIST *)moveList.getTail();
        
        if(mList != NULL)
        {
            //status must have got updated after makemove... 
            status = mList->status;
    	    cStatus = scan4Check(init, dest, CHECK);

    	    if(isEndGame())
    	    {
                if(cStatus == CHECK)
                {
                    status |= MOVE_CHECKMATE;
    	           //printf("Checkmate\n");
                }
                else
                {
                    status |= MOVE_STALEMATE;
		            //printf("Stalemate\n");
                }
            }
            else if(cStatus == CHECK)
            {
                    status |= MOVE_CHECK;
    	            //printf("Itz a check!!\n");
            }

            /* Form the SAN notation for the MOVE */
            mList->status = status; //This is needed for SAN
            (void)updateCANString(mList);
            (void)updateSANString(mList, TRUE);
            (void)updateFENString(mList->FEN);

            //check if 50 move repetition happened
            if(gState.draw50HalfMoveCount >= 50)
            {
                mList->status |= MOVE_DRAW_50MOVE_ACTIVE;
            }
            
            //check for insufficient material draw
            tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)mList);
            
            if((tempList != NULL && tempList->status & MOVE_DRAW_INSUFFICIENT_PIECES_ACTIVE) ||
               insufficientMatingMaterial(getLastFENString()) == TRUE)
            {
                mList->status |= MOVE_DRAW_INSUFFICIENT_PIECES_ACTIVE;
            }

            // Update zobrist Hash
            zob.updateBoardPosition(getLastFENString());
            zob.calculateZobristHash();
            mList->zobristHash = zob.getZobristHash();
            currentHash = mList->zobristHash;
            currentSeqNum = gState.seqNum;
            
            //check if 3 move repetition happened
            for(tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)mList);
                tempList != NULL;
                tempList = (MOVELIST *)moveList.getPrev((DLL_NODE *)tempList))
            {
                if(tempList->seqNum != currentSeqNum)
                {
                    break;
                }
                
                if(tempList->zobristHash == currentHash)
                {
                    //add more detailed check using FEN string if required
                    count++;
                }
                
                if(count == 3) 
                {
                    break;
                }
            }
            
            if(count == 3)
            {
                mList->status |= MOVE_DRAW_3MOVE_ACTIVE;
            }
            
            status = mList->status;    
        }
        
        toggleTurn();
    }
    

    return status;
    
}
Ejemplo n.º 7
0
bool ChessBoard::makeMove(int from_x, int from_y, int to_x, int to_y ) {
  Move move( from_x, from_y, to_x, to_y );

  /* the code that validates the move, does not check the position after the move
     this is done in the end of this method */

  if( !validateMove( move ) ) return false;

  //castling
  if( getPiece( from_x, from_y )->type == KING && std::abs(to_x - from_x) == 2) {
    
    Piece* rook;
    int x, y = from_y;
    
    x = (to_x != 2) ? from_x + 1 : from_x - 1;
    
    if( to_x != 2 ) {
      rook = removePiece(to_x+1, to_y);  
    } else {
      rook = removePiece( to_x - 2, to_y);
    }
    
    setPiece( x, y, rook );
    rook->x = x;
    rook->y = y;
  }
  
 
  

  /* adds the piece to be taken if exists, then adds the move to the stack of moves */

  Piece* pieceToMove = removePiece( from_x, from_y );
  move.pieceTaken = getPiece( to_x, to_y );

  //amp
  if( (pieceToMove->type == PAWN) && (std::abs( to_x - from_x ) == 1 ) && (getPiece( to_x, to_y ) == NULL) ) {
    move.pieceTaken = removePiece( to_x, from_y );
    move.amp = true;
  }
  
  //transform to piece
  if( pieceToMove->type == PAWN  && ( to_y == 0 || to_y == 7) ) {
    move.trans = true;
    pieceToMove->type = QUEEN;
  }

  if( move.pieceTaken != NULL ) {

    if( pieceToMove->color == move.pieceTaken->color) {
      setPiece( from_x, from_y, pieceToMove );

      return false;
    }

    move.pieceTaken->inPlay = false;
  }
  moves.push( move );

  /* retrives the piece that is to be moved, and then it moves it. at the end the new
     position is updaten in the piece-object */
  setPiece( to_x, to_y, pieceToMove );
  pieceToMove->x = to_x;
  pieceToMove->y = to_y;
  PieceColor colorOfMovingPlayer = pieceToMove->color;
  pieceToMove->nrOfMoves++;

  /* checks if the king of the player which just moved is in check,
     if so the move is invalid and it goes back a move */
  if( playersKingInCheck( colorOfMovingPlayer ) ) {

    goBackAMove();
    return false;
  }
  return true;
}