Beispiel #1
0
/*!
 * Returns true if \a side has material else false.
 */
bool HordeBoard::hasMaterial(Side side) const
{
	for (int i = 0; i < arraySize(); i++)
	{
		if  (side == pieceAt(i).side()
		&&   pieceAt(i).isValid())
			return true;
	}
	return false;
}
void CrazyhouseBoard::generateMovesForPiece(QVarLengthArray<Move>& moves,
					    int pieceType,
					    int square) const
{
	// Generate drops
	if (square == 0)
	{
		const int size = arraySize();
		const int maxRank = height() - 2;
		for (int i = 0; i < size; i++)
		{
			Piece tmp = pieceAt(i);
			if (!tmp.isEmpty())
				continue;
			if (pieceType == Pawn)
			{
				Square sq(chessSquare(i));
				if (sq.rank() < 1 || sq.rank() > maxRank)
					continue;
			}

			moves.append(Move(0, i, pieceType));
		}
	}
	else
		WesternBoard::generateMovesForPiece(moves, pieceType, square);
}
Beispiel #3
0
Chess::Piece GraphicsBoard::pieceTypeAt(const Chess::Square& square) const
{
	GraphicsPiece* piece = pieceAt(square);
	if (piece == nullptr)
		return Chess::Piece();
	return piece->pieceType();
}
Beispiel #4
0
void OukBoard::generateMovesForPiece(QVarLengthArray< Move >& moves,
					  int pieceType,
					  int square) const
{
	MakrukBoard::generateMovesForPiece(moves, pieceType, square);

	Side side = sideToMove();

	// Only consider King and Neang on their initial squares
	if ((pieceType != King || square != m_initialSquare[side][King])
	&&  (pieceType != Maiden || square != m_initialSquare[side][Maiden]))
		return;
	// Return if the piece has moved already
	if (m_moveCount[side].value((OukPieceType)pieceType, -1) != 0)
		return;
	// No special moves for King in check
	if (pieceType == King && inCheck(side))
		return;

	// Generate initial move option for King (leap of Horse)
	// and for Neang (forward two squares)
	int sign = (side == Side::White) ? 1 : -1;

	for (const auto& i: m_initialOffsets)
	{
		if (pieceType != i.type)
			continue;

		int target = square - i.offset * sign;
		const Piece& piece = pieceAt(target);

		if  (piece.isEmpty())
			moves.append(Move(square, target));
	}
}
Beispiel #5
0
bool OukBoard::vSetFenString(const QStringList& fen)
{
	// At first assume that King and Maiden pieces have moved
	m_moveCount[Side::White][King] = 1;
	m_moveCount[Side::Black][King] = 1;
	m_moveCount[Side::White][Maiden] = 1;
	m_moveCount[Side::Black][Maiden] = 1;

	// parseCastlingRights is called via vSetFenString of base class
	if (!MakrukBoard::vSetFenString(fen))
		return false;

	// Expect pieces on their initial squares if move counter is zero
	const OukPieceType types[2]{King, Maiden};
	for (int side = Side::White; side <= Side::Black; side++)
	{
		for (auto type: types)
		{
			int index = m_initialSquare[side][type];
			if ( m_moveCount[side][type] == 0
			&&   pieceAt(index) != Piece(Side::Type(side), type))
				return false;
		}
	}
	return true;
}
Beispiel #6
0
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
    if(x >= boardXOffset + (boardW)*hexW){
        //We are clicking the right-hand side of the screen, so we are
        // picking up or putting back a piece
        if(whoseTurn == 1 && pl1spares > 0 && currentAction == 0){
            currentAction = 1;
            pl1spares--;
        } else if(whoseTurn == 2 && pl2spares > 0 && currentAction == 0){
            currentAction = 1;
            pl2spares--;
        } else if (whoseTurn == 1 && currentAction == 1){
            currentAction = 0;
            pl1spares++;
        } else if (whoseTurn == 2 && currentAction == 1){
            currentAction = 0;
            pl2spares++;
        }
    } else if(x > boardXOffset && x <= boardXOffset +(boardW)*hexW ) {
        //We are clicking on the board...
        if(currentAction == 1){
            //...placing a new piece
            int whichRow = (y-boardYOffset+hexH/2)/hexH;
            int whichCol = (x-(boardXOffset+(whichRow%2)*(hexW/2))+hexW/2)/hexW;
            if(whichRow >= 0 && whichRow < boardH && whichCol >= 0 && whichCol < boardW){
                if(canPlaceNewPiece(whichCol,whichRow)){
                    currentAction = 0;
                    putPieceAt(whichCol,whichRow,whoseTurn);
                    whoseTurn = 3 - whoseTurn;
                }
            }
        } else if(currentAction == 0){
            //...picking up and old piece
            int whichRow = (y-boardYOffset+hexH/2)/hexH;
            int whichCol = (x-(boardXOffset+(whichRow%2)*(hexW/2))+hexW/2)/hexW;
            
            if(pieceAt(whichCol,whichRow) == whoseTurn){
                selectedPieceX = whichCol;
                selectedPieceY  = whichRow;
                currentAction = 2;
                putPieceAt(whichCol,whichRow,0);
            }
        } else if(currentAction == 2){
            //...placing an old piece back on the board
            int whichRow = (y-boardYOffset+hexH/2)/hexH;
            int whichCol = (x-(boardXOffset+(whichRow%2)*(hexW/2))+hexW/2)/hexW;
            if(whichRow == selectedPieceY && whichCol == selectedPieceX){
                currentAction = 0;
                putPieceAt(whichCol,whichRow,whoseTurn);
            } else if(whichRow >= 0 && whichRow < boardH && whichCol >= 0 && whichCol < boardW){
                if(canPlaceOldPiece(whichCol, whichRow)){
                    currentAction = 0;
                    putPieceAt(whichCol,whichRow,whoseTurn);
                    whoseTurn = 3 - whoseTurn;
                }
            }
        }
    }
}
Beispiel #7
0
void GraphicsBoard::movePiece(const Chess::Square& source,
			      const Chess::Square& target)
{
	GraphicsPiece* piece = pieceAt(source);
	Q_ASSERT(piece != nullptr);

	m_squares[squareIndex(source)] = nullptr;
	setSquare(target, piece);
}
QString CrazyhouseBoard::sanMoveString(const Move& move)
{
	Piece piece(pieceAt(move.sourceSquare()));
	QVarLengthArray<int> squares;

	normalizePieces(piece, squares);
	QString str(WesternBoard::sanMoveString(move));
	restorePieces(piece, squares);

	return str;
}
Beispiel #9
0
Result LosersBoard::result()
{
	Side winner;
	QString str;

	// Checkmate/Stalemate
	if (!canMove())
	{
		winner = sideToMove();
		str = tr("%1 gets mated").arg(winner.toString());
		return Result(Result::Win, winner, str);
	}

	// Lost all pieces
	int pieceCount = 0;
	for (int i = 0; i < arraySize(); i++)
	{
		if (pieceAt(i).side() == sideToMove()
		&&  ++pieceCount > 1)
			break;
	}
	if (pieceCount <= 1)
	{
		winner = sideToMove();
		str = tr("%1 lost all pieces").arg(winner.toString());
		return Result(Result::Win, winner, str);
	}

	// 50 move rule
	if (reversibleMoveCount() >= 100)
	{
		str = tr("Draw by fifty moves rule");
		return Result(Result::Draw, Side::NoSide, str);
	}

	// 3-fold repetition
	if (repeatCount() >= 2)
	{
		str = tr("Draw by 3-fold repetition");
		return Result(Result::Draw, Side::NoSide, str);
	}

	return Result();
}
void CrazyhouseBoard::normalizePieces(Piece piece, QVarLengthArray<int>& squares)
{
	if (!piece.isValid())
		return;

	Piece prom(piece.side(), promotedPieceType(piece.type()));
	Piece base(piece.side(), normalPieceType(piece.type()));
	if (base == prom)
		return;

	const int size = arraySize();
	for (int i = 0; i < size; i++)
	{
		if (pieceAt(i) == prom)
		{
			squares.append(i);
			setSquare(i, base);
		}
	}
}
Beispiel #11
0
bool HordeBoard::vIsLegalMove(const Move& m)
{
	if (!StandardBoard::vIsLegalMove(m))
		return false;

	/*
	 * Workaround for Stockfish (lichess.org) asymmetry:
	 * accept en passant on 3rd (6th) rank only.
	 */
	int src = m.sourceSquare();
	int tgt = m.targetSquare();
	Piece piece = pieceAt(src);

	if (piece.type() != Pawn
	|| tgt != enpassantSquare())
		return true;

	int targetRank = chessSquare(tgt).rank();
	return targetRank == 2 || targetRank == height() - 3;
}
Beispiel #12
0
bool ChessBoard::turn(int row, int column)
{
    if( !m_selected_piece )
        return false;
    // get possible turns
    QScopedPointer< const QList<QSize> > trns(m_selected_piece->getPossibleTurns( column, row ));
    // current coords
    QSize cur_coords = m_selected_piece->getCoords();
    QList<QSize>::const_iterator it;
    for(it = trns->begin(); it != trns->end(); it++)
    {
        QSize coords_sum = b_black_bottom ^ m_selected_piece->m_bWhite ? cur_coords - (*it)  : cur_coords + (*it);
        if( coords_sum == turn_coords )
        {
            emit figureMoved(cur_coords, turn_coords);
            PiecePtr &turned = pieceAt(column, row);
            m_selected_piece->setCoords(turn_coords);
            turned.swap(m_selected_piece);
            return true;
        }
    }
    return false;
}
Beispiel #13
0
bool ChessBoard::cellClick(int row, int column)
{
    if( row >= 0 && row < m_board_size && column >=0 && column < m_board_size )
    {
        QSize turn_coords = QSize( column, row );
        // check if piece clicked for the 1st time
        PiecePtr& _selected = pieceAt( column, row );
        if( _selected )
        {
            m_selected_piece.swap(_selected);
            return true;
        }
        QSize from = m_selected_piece->getCoords();
        if( turn( row, column ) )
        {
            writeLog(from, turn_coords);
            return true;
        }
        else
            return false;
    }
    return false;
}
Beispiel #14
0
void drawBoard(){
    //NOTE: This will need to be adapted to your board
    // data structure!
    //For each board hex...
    for(int y=0;y<boardH;y++){
        for(int x=0;x<boardW;x++){
            //Calculate the center, and draw the border
            float offset = (hexW/2) * (y%2);
            ofSetColor(0, 0, 0);
            drawHex(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen);
            
            if(pieceAt(x,y) != 0){
                //If there is a playing piece in the current hex,
                // draw it
                if(pieceAt(x,y) == 1){
                    ofSetColor(255,255,255);
                } else {
                    ofSetColor(0,0,0);
                }
                ofCircle(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen/2);
            } else {
                //This is an unoccupied space, but we might need to draw some
                // highlights...
                if(currentAction == 1){
                    //If the user is trying to place a new piece,
                    // higlight the space if it is valid to place the piece here
                    ofSetColor(64,192,64); //green highlight
                    
                    if(canPlaceNewPiece(x, y)){
                        ofCircle(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen/2);
                    }
                } else if(currentAction == 2){
                    //If the user is trying to move an old piece,
                    // higlight the space if it is valid to place the piece here
                    ofSetColor(64,192,64); //green
                    
                    if(canPlaceOldPiece(x, y)){
                        ofCircle(boardXOffset+x*hexW+offset,boardYOffset+y*hexH,sideLen/2);
                    }
                }
            }
        }
    }
    
    if(currentAction == 1){
        //If placing a new piece, draw the piece that the user is placing
        // at the mouse location
        if(whoseTurn == 1){
            ofSetColor(255,255,255);
        } else {
            ofSetColor(0,0,0);
        }
        
        ofCircle(ofGetMouseX(),ofGetMouseY(),sideLen/2);
    } else if(currentAction == 2){
        //If moving an old piece...
        
        //...show where it is being moved FROM
        ofSetColor(64,64,192); //blue
        float offset = (hexW/2) * (selectedPieceY%2);
        ofCircle(boardXOffset+selectedPieceX*hexW+offset,boardYOffset+selectedPieceY*hexH,sideLen/2);
        
        //...and also show the piece in the player's "hand" being moved
        if(whoseTurn == 1){
            ofSetColor(255,255,255);
        } else {
            ofSetColor(0,0,0);
        }
        ofCircle(ofGetMouseX(),ofGetMouseY(),sideLen/2);
    }
    
}