Newer
Older
Import / applications / Chess / QtChessBoard.cpp
/*
 * =====================================================================================
 *
 *       Filename:  QtChessBoard.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  21/02/2011 08:28:40
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  John Ryland (jryland), jryland@xiaofrog.com
 *        Company:  InvertedLogic
 *
 * =====================================================================================
 */


#include <AbstractChessMove.h>
#include <QtChessBoard.h>
#include <QPainter>
#include <QPixmap>
#include <QMouseEvent>
#include <QByteArray>
#include <QStringList>
#include <QDebug>


QtChessBoard::QtChessBoard(QWidget *parent, AbstractChessBoard *brd) : QWidget(parent)
{
    if ( !brd )
        brd = new AbstractChessBoard;
    board = brd;
    haveSelected = false;
    haveCursor = false;

    f = new QFile("./game-data.txt");
    f->open(QFile::ReadOnly);
    f->readLine(1024);
    f->readLine(1024);
    f->readLine(1024);
    f->readLine(1024);
    f->readLine(1024);
    f->readLine(1024);
    startTimer(700);
}


QtChessBoard::~QtChessBoard()
{
}


void QtChessBoard::timerEvent(QTimerEvent *te)
{
    static bool isWhitesMove = true;
    static QString blacksMove;
    QString moveStr;

    if ( isWhitesMove ) {
        QByteArray ba = f->readLine(1024);
        QString str = ba;
        str = str.simplified();
        QStringList strList = str.split(" ");
        QString whitesMove = strList[1];
        blacksMove = strList[2];
        qDebug() << "White: " << whitesMove;
        moveStr = whitesMove;
    } else {
        qDebug() << "Black: " << blacksMove;
        moveStr = blacksMove;
    }

    AbstractChessMove move(board, moveStr, isWhitesMove);
    qDebug() << "moving " << AbstractChessPiece::pieceName(move.typeMoving) 
            << " from " << move.movedFromRow << "," << move.movedFromColumn
            << " to " << move.movedToRow << "," << move.movedToColumn;
    //bool captureMove;
    //bool queenSideCastle;
    //bool kingSideCastle;

    foreach (AbstractChessPiece *piece, board->pieces) {
        if ( piece->position.rank == move.movedToRow && piece->position.file == move.movedToColumn ) {
            board->pieces.removeAll(piece);
            delete piece;
        }
    }

    foreach (AbstractChessPiece *piece, board->pieces) {
        if ( piece->position.rank == move.movedFromRow && piece->position.file == move.movedFromColumn ) {
            piece->position.rank = move.movedToRow;
            piece->position.file = move.movedToColumn;
        }
    }

    if ( move.queenSideCastle ) {
        AbstractChessPiece *piece = board->pieceAt( move.movedFromRow, 0 );
        if ( piece ) 
            piece->position.file = 3;
    } else if ( move.kingSideCastle ) {
        AbstractChessPiece *piece = board->pieceAt( move.movedFromRow, 7 );
        if ( piece ) 
            piece->position.file = 5;
    }

    isWhitesMove = !isWhitesMove;

    repaint();
}


void QtChessBoard::paintEvent(QPaintEvent *pe)
{
    int w = width();
    int h = height();
    int s = qMin(w, h);
    int sqr = s / 8;
    int xOffset = (w - s) / 2;
    int yOffset = (h - s) / 2;

    QPainter p(this);
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            if ( (i + j) % 2 ) 
                p.setBrush(Qt::black);
            else
                p.setBrush(Qt::white);
            p.drawRect(xOffset + i*sqr, yOffset + j*sqr, sqr, sqr);
        }
    }
    p.setBrush(Qt::NoBrush);
    if ( haveCursor ) {
        p.setPen(Qt::yellow);
        p.drawRect(xOffset + cursor.file*sqr, yOffset + cursor.rank*sqr, sqr, sqr);
    }
    if ( haveSelected ) {
        p.setPen(Qt::green);
        p.drawRect(xOffset + selected.file*sqr, yOffset + selected.rank*sqr, sqr, sqr);
    }
    foreach (AbstractChessPiece *piece, board->pieces) {
        int y = ( piece->color == Black ) ? 0 : 32;
        int i = piece->position.file;
        int j = piece->position.rank;
        int x;
        switch (piece->type) {
            case Pawn:   x =  0; break;
            case Bishop: x = 16; break;
            case Knight: x = 32; break;
            case Rook:   x = 48; break;
            case Queen:  x = 64; break;
            case King:   x = 80; break;
            default:             break;
        }
        QPixmap pieces("Graphics/pieces-small.png");
        if ( haveSelected && piece->position.rank == selected.rank && piece->position.file == selected.file ) {
            p.drawPixmap(mx - sqr*9/32, my - sqr*7/16, sqr*7/16, sqr*7/8, pieces, x, y, 16, 32);
        } else
            p.drawPixmap(xOffset + i*sqr + sqr*9/32, yOffset + j*sqr + sqr/16, sqr*7/16, sqr*7/8, pieces, x, y, 16, 32);
    }
}


void QtChessBoard::mouseMoveEvent(QMouseEvent *me)
{
    int w = width();
    int h = height();
    int s = qMin(w, h);
    int sqr = s / 8;
    int xOffset = (w - s) / 2;
    int yOffset = (h - s) / 2;

    mx = me->pos().x();
    my = me->pos().y();

    int i = (mx - xOffset) / sqr;
    int j = (my - yOffset) / sqr;

    haveCursor = false;

    if (i >= 0 && i <= 7 && j >= 0 && j <= 7 ) {
        cursor.file = i;
        cursor.rank = j;
        haveCursor = true;
    }

    repaint();
}


void QtChessBoard::mousePressEvent(QMouseEvent *me)
{
    int w = width();
    int h = height();
    int s = qMin(w, h);
    int sqr = s / 8;
    int xOffset = (w - s) / 2;
    int yOffset = (h - s) / 2;

    mx = me->pos().x();
    my = me->pos().y();

    int i = (mx - xOffset) / sqr;
    int j = (my - yOffset) / sqr;

    selected.file = i;
    selected.rank = j;
    haveSelected = true;
    repaint();
}


void QtChessBoard::mouseReleaseEvent(QMouseEvent *me)
{
    haveSelected = false;
    haveCursor = false;
    repaint();
}