diff options
Diffstat (limited to 'qnetchess/src/gameboard.cpp')
-rw-r--r-- | qnetchess/src/gameboard.cpp | 1987 |
1 files changed, 1987 insertions, 0 deletions
diff --git a/qnetchess/src/gameboard.cpp b/qnetchess/src/gameboard.cpp new file mode 100644 index 00000000..ca07e3b8 --- /dev/null +++ b/qnetchess/src/gameboard.cpp @@ -0,0 +1,1987 @@ +/* + * $Id: gameboard.cpp,v 1.1 2005/03/26 11:24:13 denis Exp $ + * + * Author: Denis Kozadaev (denis@tambov.ru) + * Description: + * + * See also: style(9) + * + * Hacked by: + * Fixed the mate checker (big thanks to knyaz@RusNet) + */ + +#include <ntqpainter.h> +#include <ntqfontmetrics.h> +#include <ntqmessagebox.h> +#include <ntqcursor.h> +#include <ntqfiledialog.h> +#include <stdlib.h> + +#include "gameboard.h" +#include "gamesocket.h" + +#include "xpm/black_bishop.xpm" +#include "xpm/black_castle.xpm" +#include "xpm/black_king.xpm" +#include "xpm/black_knight.xpm" +#include "xpm/black_pawn.xpm" +#include "xpm/black_queen.xpm" +#include "xpm/white_bishop.xpm" +#include "xpm/white_castle.xpm" +#include "xpm/white_king.xpm" +#include "xpm/white_knight.xpm" +#include "xpm/white_pawn.xpm" +#include "xpm/white_queen.xpm" + +const int + cell_size = 40, + XSize = 640, + YSize = 480; + +TQColor cb, cw; + +bool +Figure::hasMyFigure(GameBoard::GameType gt, GameBoard::FigureType *map, + int x, int y, bool mirror) +{ + int n; + bool res; + + n = map2map(gt, x, y, mirror); + + if (gt == GameBoard::WHITE) + switch (map[n]) { + case GameBoard::DUMMY: + case GameBoard::WHITE_PAWN: + case GameBoard::WHITE_CASTLE: + case GameBoard::WHITE_BISHOP: + case GameBoard::WHITE_KING: + case GameBoard::WHITE_QUEEN: + case GameBoard::WHITE_KNIGHT: + res = TRUE; + break; + default: + res = FALSE; + } + else if (gt == GameBoard::BLACK) + switch (map[n]) { + case GameBoard::DUMMY: + case GameBoard::BLACK_PAWN: + case GameBoard::BLACK_CASTLE: + case GameBoard::BLACK_BISHOP: + case GameBoard::BLACK_KING: + case GameBoard::BLACK_QUEEN: + case GameBoard::BLACK_KNIGHT: + res = TRUE; + break; + default: + res = FALSE; + } + else + res = FALSE; + + return (res); +} + + +int +Figure::hasEnemyFigure(GameBoard::GameType gt, GameBoard::FigureType *map, + int x, int y, bool mirror) +{ + int n; + int res; + + n = map2map(gt, x, y, mirror); + + if (gt == GameBoard::BLACK) + switch (map[n]) { + case GameBoard::WHITE_PAWN: + case GameBoard::WHITE_CASTLE: + case GameBoard::WHITE_BISHOP: + case GameBoard::WHITE_QUEEN: + case GameBoard::WHITE_KNIGHT: + res = 1; + break; + case GameBoard::WHITE_KING: + res = 2; + break; + case GameBoard::DUMMY: + default: + res = 0; + } + else if (gt == GameBoard::WHITE) + switch (map[n]) { + case GameBoard::BLACK_PAWN: + case GameBoard::BLACK_CASTLE: + case GameBoard::BLACK_BISHOP: + case GameBoard::BLACK_QUEEN: + case GameBoard::BLACK_KNIGHT: + res = 1; + break; + case GameBoard::BLACK_KING: + res = 2; + break; + case GameBoard::DUMMY: + default: + res = 0; + } + else + res = 0; + + return (res); +} + + +bool +Figure::hasFigure(GameBoard::GameType gt, GameBoard::FigureType *map, + int x, int y, bool mirror) +{ + int n; + + n = map2map(gt, x, y, mirror); + + return (map[n] != GameBoard::NONE); +} + + +int +Figure::map2map(GameBoard::GameType gt, int x, int y, bool mirror) +{ + int n = -1; + + if (gt == GameBoard::WHITE) + if (mirror) + n = (y - 1) * 8 + (8 - x); + else + n = (8 - y) * 8 + (x - 1); + else if (gt == GameBoard::BLACK) + if (mirror) + n = (8 - y) * 8 + (x - 1); + else + n = (y - 1) * 8 + (8 - x); + + return (n); +} + + +QString +Figure::map2str(int x, int y) +{ + QString s; + + s = TQString(TQChar('a' + x - 1)) + TQString::number(y); + return (s); +} + + +void +Figure::str2map(const TQString &coo, int *x, int *y) +{ + + *x = coo[0] - 'a' + 1; + *y = coo[1] - '0'; +} + + +int +Figure::validMove(GameBoard::GameType gt, GameBoard::FigureType *map, + int fx, int fy, int tx, int ty, bool mirror) +{ + TQPointArray vl; + int res, f, t; + + moveList(vl, gt, map, fx, fy, mirror); + res = hasPoint(vl, tx, ty); + f = map2map(gt, fx, fy, mirror); + switch (map[f]) { + case GameBoard::WHITE_PAWN: + if (res && (ty == 8)) + res++; + break; + case GameBoard::BLACK_PAWN: + if (res && (ty == 1)) + res++; + break; + default:; + } + if (res) { + t = map2map(gt, tx, ty, mirror); + map[t] = map[f]; + map[f] = GameBoard::NONE; + if (mirror) { + vl.resize(0); + t = checkKing(gt, map, mirror, vl, FALSE); + switch (t) { + case 1: + res |= 0x10; + break; + case 2: + res |= 0x20; + break; + case 3: + res |= 0x40; + break; + default:; + } + } + } + + return (res); +} + + +/* + * 0 - nothing + * 1 - check + * 2 - mate + * 3 - stalemate + */ +int +Figure::checkKing(GameBoard::GameType gt, GameBoard::FigureType *map, + bool mirror, TQPointArray &vl, bool co) +{ + TQPointArray tmp; + GameBoard::FigureType myking, map1[64]; + GameBoard::GameType mytype; + int res, x, y, p, xk, yk, pk; + bool hp; + + if (gt == GameBoard::WHITE) { + myking = GameBoard::BLACK_KING; + mytype = GameBoard::BLACK; + } else if (gt == GameBoard::BLACK) { + myking = GameBoard::WHITE_KING; + mytype = GameBoard::WHITE; + } else { + myking = GameBoard::NONE; + mytype = GameBoard::NOGAME; + } + xk = yk = -1; + res = 0; p = -1; + + for (y = 1; y < 9; ++y) + for (x = 1; x < 9; ++x) + /* check enemy figures */ + if (hasMyFigure(gt, map, x, y, mirror)) + moveList(vl, gt, map, x, y, mirror); + else if (p == -1) { + p = map2map(mytype, x, y, !mirror); + if (map[p] == myking) { + xk = x; + yk = y; + } else + p = -1; + } + + hp = hasPoint(vl, xk, yk); + if (hp) { + res++; + if (!co) { + vl.resize(0); + for (y = 1; y < 9; ++y) + for (x = 1; x < 9; ++x) + if (hasMyFigure(mytype, map, + x, y, !mirror)) + moveList(vl, mytype, map, + x, y, !mirror); + memmove(map1, map, sizeof(map1)); + pk = map2map(mytype, xk, yk, !mirror); + for (x = vl.size() - 1; x >= 0; --x) { + p = map2map(mytype, vl.point(x).x(), + vl.point(x).y(), !mirror); + if (p != pk) + map1[p] = GameBoard::DUMMY; + } + if (checkKing(gt, map1, mirror, vl, TRUE) != 0) { + vl.resize(0); + moveListKing(vl, mytype, map, xk, yk, !mirror); + memmove(map1, map, sizeof(map1)); + for (y = 0, x = vl.size() - 1; x >= 0; --x) { + p = map2map(mytype, vl.point(x).x(), + vl.point(x).y(), !mirror); + map1[p] = myking; + map1[pk] = GameBoard::NONE; + if (checkKing(gt, map1, mirror, + tmp, TRUE) == 1) + ++y; + map1[pk] = map[pk]; + map1[p] = map[p]; + } + if (y == (int)vl.size()) + res++; + } + } + } else if (!co) { + vl.resize(0); + for (y = 1; y < 9; ++y) + for (x = 1; x < 9; ++x) + if (hasMyFigure(mytype, map, x, y, !mirror)) + moveList(vl, mytype, map, x, y, + !mirror); + if (vl.size() == 0) + res = 3; + } + + return (res); +} + + +void +Figure::moveList(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + int n; + + n = map2map(gt, x, y, mirror); + switch (map[n]) { + case GameBoard::WHITE_PAWN: + moveListWhitePawn(vl, gt, map, x, y, mirror); + break; + + case GameBoard::WHITE_CASTLE: + case GameBoard::BLACK_CASTLE: + moveListCastle(vl, gt, map, x, y, mirror); + break; + + case GameBoard::WHITE_BISHOP: + case GameBoard::BLACK_BISHOP: + moveListBishop(vl, gt, map, x, y, mirror); + break; + + case GameBoard::WHITE_KING: + case GameBoard::BLACK_KING: + moveListKing(vl, gt, map, x, y, mirror); + break; + + case GameBoard::WHITE_QUEEN: + case GameBoard::BLACK_QUEEN: + moveListQueen(vl, gt, map, x, y, mirror); + break; + + case GameBoard::WHITE_KNIGHT: + case GameBoard::BLACK_KNIGHT: + moveListKnight(vl, gt, map, x, y, mirror); + break; + + case GameBoard::BLACK_PAWN: + moveListBlackPawn(vl, gt, map, x, y, mirror); + break; + + + default:; + } +} + + +void +Figure::moveListWhitePawn(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + + if (validPoint(gt, map, x, y + 1, mirror) && + !hasFigure(gt, map, x, y + 1, mirror)) { + vl.putPoints(vl.size(), 1, x, y + 1); + if ((y == 2) && validPoint(gt, map, x, y + 2, mirror)) + vl.putPoints(vl.size(), 1, x, y + 2); + } + if (validPoint(gt, map, x + 1, y + 1, mirror) && + hasEnemyFigure(gt, map, x + 1, y + 1, mirror)) + vl.putPoints(vl.size(), 1, x + 1, y + 1); + if (validPoint(gt, map, x - 1, y + 1, mirror) && + hasEnemyFigure(gt, map, x - 1, y + 1, mirror)) + vl.putPoints(vl.size(), 1, x - 1, y + 1); +} + + +void +Figure::moveListBlackPawn(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + + if (validPoint(gt, map, x, y - 1, mirror) && + !hasFigure(gt, map, x, y - 1, mirror)) { + vl.putPoints(vl.size(), 1, x, y - 1); + if ((y == 7) && validPoint(gt, map, x, y - 2, mirror)) + vl.putPoints(vl.size(), 1, x, y - 2); + } + if (validPoint(gt, map, x + 1, y - 1, mirror) && + hasEnemyFigure(gt, map, x + 1, y - 1, mirror)) + vl.putPoints(vl.size(), 1, x + 1, y - 1); + if (validPoint(gt, map, x - 1, y - 1, mirror) && + hasEnemyFigure(gt, map, x - 1, y - 1, mirror)) + vl.putPoints(vl.size(), 1, x - 1, y - 1); +} + + +void +Figure::moveListCastle(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + int i; + + for (i = x + 1; i < 9; i++) { + if (!hasFigure(gt, map, i, y, mirror)) { + vl.putPoints(vl.size(), 1, i, y); + continue; + } else if (hasEnemyFigure(gt, map, i, y, mirror)) + vl.putPoints(vl.size(), 1, i, y); + break; + } + for (i = x - 1; i > 0; i--) { + if (!hasFigure(gt, map, i, y, mirror)) { + vl.putPoints(vl.size(), 1, i, y); + continue; + } else if (hasEnemyFigure(gt, map, i, y, mirror)) + vl.putPoints(vl.size(), 1, i, y); + break; + } + for (i = y + 1; i < 9; i++) { + if (!hasFigure(gt, map, x, i, mirror)) { + vl.putPoints(vl.size(), 1, x, i); + continue; + } else if (hasEnemyFigure(gt, map, x, i, mirror)) + vl.putPoints(vl.size(), 1, x, i); + break; + } + for (i = y - 1; i > 0; i--) { + if (!hasFigure(gt, map, x, i, mirror)) { + vl.putPoints(vl.size(), 1, x, i); + continue; + } else if (hasEnemyFigure(gt, map, x, i, mirror)) + vl.putPoints(vl.size(), 1, x, i); + break; + } +} + + +void +Figure::moveListBishop(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + int i, j; + + for (i = x + 1, j = y + 1; (i < 9) && (j < 9); i++, j++) { + if (!hasFigure(gt, map, i, j, mirror)) { + vl.putPoints(vl.size(), 1, i, j); + continue; + } else if (hasEnemyFigure(gt, map, i, j, mirror)) + vl.putPoints(vl.size(), 1, i, j); + break; + } + for (i = x - 1, j = y + 1; (i > 0) && (j < 9); i--, j++) { + if (!hasFigure(gt, map, i, j, mirror)) { + vl.putPoints(vl.size(), 1, i, j); + continue; + } else if (hasEnemyFigure(gt, map, i, j, mirror)) + vl.putPoints(vl.size(), 1, i, j); + break; + } + for (i = x - 1, j = y - 1; (i > 0) && (j > 0); i--, j--) { + if (!hasFigure(gt, map, i, j, mirror)) { + vl.putPoints(vl.size(), 1, i, j); + continue; + } else if (hasEnemyFigure(gt, map, i, j, mirror)) + vl.putPoints(vl.size(), 1, i, j); + break; + } + for (i = x + 1, j = y - 1; (i < 9) && (j > 0); i++, j--) { + if (!hasFigure(gt, map, i, j, mirror)) { + vl.putPoints(vl.size(), 1, i, j); + continue; + } else if (hasEnemyFigure(gt, map, i, j, mirror)) + vl.putPoints(vl.size(), 1, i, j); + break; + } +} + + +void +Figure::moveListKing(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + int x1, x2, y1, y2; + + x1 = x - 1; x2 = x + 1; + y1 = y - 1; y2 = y + 1; + if (validPoint(gt, map, x1, y2, mirror) && + !hasKingsMeeting(gt, map, x1, y2, mirror)) + vl.putPoints(vl.size(), 1, x1, y2); + if (validPoint(gt, map, x, y2, mirror) && + !hasKingsMeeting(gt, map, x, y2, mirror)) + vl.putPoints(vl.size(), 1, x, y2); + if (validPoint(gt, map, x2, y2, mirror) && + !hasKingsMeeting(gt, map, x2, y2, mirror)) + vl.putPoints(vl.size(), 1, x2, y2); + if (validPoint(gt, map, x1, y, mirror) && + !hasKingsMeeting(gt, map, x1, y, mirror)) + vl.putPoints(vl.size(), 1, x1, y); + if (validPoint(gt, map, x2, y, mirror) && + !hasKingsMeeting(gt, map, x2, y, mirror)) + vl.putPoints(vl.size(), 1, x2, y); + if (validPoint(gt, map, x1, y1, mirror) && + !hasKingsMeeting(gt, map, x1, y1, mirror)) + vl.putPoints(vl.size(), 1, x1, y1); + if (validPoint(gt, map, x, y1, mirror) && + !hasKingsMeeting(gt, map, x, y1, mirror)) + vl.putPoints(vl.size(), 1, x, y1); + if (validPoint(gt, map, x2, y1, mirror) && + !hasKingsMeeting(gt, map, x2, y1, mirror)) + vl.putPoints(vl.size(), 1, x2, y1); +} + + +void +Figure::moveListQueen(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + + moveListBishop(vl, gt, map, x, y, mirror); + moveListCastle(vl, gt, map, x, y, mirror); +} + + +void +Figure::moveListKnight(TQPointArray &vl, GameBoard::GameType gt, + GameBoard::FigureType *map, int x, int y, bool mirror) +{ + int x1, x2, x3, x4, + y1, y2, y3, y4; + + x1 = x + 1; + x2 = x1 + 1; + x3 = x - 1; + x4 = x3 - 1; + y1 = y + 1; + y2 = y1 + 1; + y3 = y - 1; + y4 = y3 - 1; + if (validPoint(gt, map, x3, y2, mirror)) + vl.putPoints(vl.size(), 1, x3, y2); + if (validPoint(gt, map, x1, y2, mirror)) + vl.putPoints(vl.size(), 1, x1, y2); + if (validPoint(gt, map, x4, y1, mirror)) + vl.putPoints(vl.size(), 1, x4, y1); + if (validPoint(gt, map, x2, y1, mirror)) + vl.putPoints(vl.size(), 1, x2, y1); + if (validPoint(gt, map, x4, y3, mirror)) + vl.putPoints(vl.size(), 1, x4, y3); + if (validPoint(gt, map, x2, y3, mirror)) + vl.putPoints(vl.size(), 1, x2, y3); + if (validPoint(gt, map, x3, y4, mirror)) + vl.putPoints(vl.size(), 1, x3, y4); + if (validPoint(gt, map, x1, y4, mirror)) + vl.putPoints(vl.size(), 1, x1, y4); +} + + +bool +Figure::hasKingsMeeting(GameBoard::GameType gt, GameBoard::FigureType *map, + int x, int y, bool mirror) +{ + int x1, x2, y1, y2; + bool res; + + x1 = x - 1; x2 = x + 1; + y1 = y - 1; y2 = y + 1; + res = FALSE; + + if (validPoint(gt, map, x1, y2, mirror)) + res = (hasEnemyFigure(gt, map, x1, y2, mirror) == 2); + if (! res && validPoint(gt, map, x, y2, mirror)) + res = (hasEnemyFigure(gt, map, x, y2, mirror) == 2); + if (!res && validPoint(gt, map, x2, y2, mirror)) + res = (hasEnemyFigure(gt, map, x2, y2, mirror) == 2); + if (!res && validPoint(gt, map, x1, y, mirror)) + res = (hasEnemyFigure(gt, map, x1, y, mirror) == 2); + if (!res && validPoint(gt, map, x2, y, mirror)) + res = (hasEnemyFigure(gt, map, x2, y, mirror) == 2); + if (!res && validPoint(gt, map, x1, y1, mirror)) + res = (hasEnemyFigure(gt, map, x1, y1, mirror) == 2); + if (!res && validPoint(gt, map, x, y1, mirror)) + res = (hasEnemyFigure(gt, map, x, y1, mirror) == 2); + if (!res && validPoint(gt, map, x2, y1, mirror)) + res = (hasEnemyFigure(gt, map, x2, y1, mirror) == 2); + + return (res); +} + + +bool +Figure::hasPoint(const TQPointArray &vl, int x, int y) +{ + int i, xp, yp, cnt; + bool res = FALSE; + + cnt = vl.count(); + for (i = 0; i < cnt; ++i) { + vl.point(i, &xp, &yp); + if ((xp == x) && (yp == y)) { + res = TRUE; + break; + } + } + + return (res); +} + + +bool +Figure::validPoint(GameBoard::GameType gt, GameBoard::FigureType *map, + int x, int y, bool mirror) +{ + bool res; + + res = ((x >0) && (x < 9) && (y >0) && (y < 9)); + if (res) + res = !hasMyFigure(gt, map, x, y, mirror); + + return (res); +} + +//----------------------------------------------------------------------------- + +GameBoard::GameBoard(GameType g, const TQString &h, TQWidget *parent, + const char *name) + :TQWidget(parent, name, TQt::WResizeNoErase | + TQt::WRepaintNoErase | TQt::WDestructiveClose) +{ + TQString str; + + gt = g; hst = h; + setCursor(TQCursor(TQt::WaitCursor)); + if (gt == WHITE) + str = tr("White"); + else if (gt == BLACK) + str = tr("Black"); + str += ' ' + tr("game with") + ' '; + setCaption(str + hst); + setIcon(TQPixmap((const char **)white_knight)); + map = new FigureType[64]; + initMap(); + + sock = new TQSocket(this); + drw = new Drawer(map, >, this); + drw->setEnabled(FALSE); + drw->setFocusPolicy(NoFocus); + box = new TQGroupBox(tr("Game chat"), this); + lst = new TQListBox(box); + lst->setFocusPolicy(NoFocus); + lst->setVScrollBarMode(TQScrollView::AlwaysOff); + lst->setSelectionMode(TQListBox::NoSelection); + edt = new TQLineEdit(box); + edt->setEnabled(FALSE); + setFocusProxy(edt); + hist = new TQGroupBox(tr("History"), this); + hist->setAlignment(TQt::AlignHCenter); + hist->setFocusPolicy(NoFocus); + hw = new TQListBox(hist); + hw->setSelectionMode(TQListBox::NoSelection); + hw->setPaletteBackgroundColor(cw); + hb = new TQListBox(hist); + hb->setSelectionMode(TQListBox::NoSelection); + hb->setPaletteBackgroundColor(cb); + tmr = new TQTimer(this); + sock_tout = SOCK_WAIT; + my_stat = tr("Looking up the host") + ' ' + hst + "..."; + TQObject::connect(sock, SIGNAL(hostFound()), + this, SLOT(showHostFound())); + TQObject::connect(sock, SIGNAL(connected()), + this, SLOT(sockConnected())); + TQObject::connect(sock, SIGNAL(readyRead()), + this, SLOT(sockRead())); + TQObject::connect(sock, SIGNAL(connectionClosed()), + this, SLOT(sockClosed())); + TQObject::connect(sock, SIGNAL(error(int)), + this, SLOT(sockError(int))); + TQObject::connect(drw, SIGNAL(moved(const TQString&)), + this, SLOT(sendMove(const TQString&))); + TQObject::connect(drw, SIGNAL(newFigure(const TQString&, + GameBoard::FigureType)), + this, SLOT(sendFigure(const TQString&, GameBoard::FigureType))); + TQObject::connect(drw, SIGNAL(gameover(int)), + this, SLOT(gameover(int))); + TQObject::connect(edt, SIGNAL(returnPressed()), + this, SLOT(sendText())); + TQObject::connect(tmr, SIGNAL(timeout()), this, SLOT(sockTest())); + + resize(XSize, YSize); + setMinimumSize(size()); + setMaximumSize(size()); + sock->connectToHost(hst, GAME_PORT); + tmr->start(1000); +} + +GameBoard::GameBoard(int sfd, TQWidget *parent, const char *name) + :TQWidget(parent, name, TQt::WResizeNoErase | TQt::WRepaintNoErase | + TQt::WDestructiveClose) +{ + + gt = NOGAME; + setCursor(TQCursor(TQt::WaitCursor)); + setIcon(TQPixmap((const char **)white_knight)); + map = new FigureType[64]; + memset(map, NONE, 64 * sizeof(*map)); + + sock = new TQSocket(this); + drw = new Drawer(map, >, this); + drw->setEnabled(FALSE); + drw->setFocusPolicy(NoFocus); + box = new TQGroupBox(tr("Game chat"), this); + lst = new TQListBox(box); + lst->setFocusPolicy(NoFocus); + lst->setVScrollBarMode(TQScrollView::AlwaysOff); + lst->setSelectionMode(TQListBox::NoSelection); + edt = new TQLineEdit(box); + setFocusProxy(edt); + hist = new TQGroupBox(tr("History"), this); + hist->setAlignment(TQt::AlignHCenter); + hist->setFocusPolicy(NoFocus); + hw = new TQListBox(hist); + hw->setSelectionMode(TQListBox::NoSelection); + hw->setPaletteBackgroundColor(cw); + hb = new TQListBox(hist); + hb->setSelectionMode(TQListBox::NoSelection); + hb->setPaletteBackgroundColor(cb); + tmr = new TQTimer(this); + sock->setSocket(sfd); + sock_tout = SOCK_WAIT; + my_stat = tr("Accepted a new connection"); + TQObject::connect(sock, SIGNAL(hostFound()), + this, SLOT(showHostFound())); + TQObject::connect(sock, SIGNAL(connected()), + this, SLOT(sockConnected())); + TQObject::connect(sock, SIGNAL(readyRead()), + this, SLOT(sockRead())); + TQObject::connect(sock, SIGNAL(connectionClosed()), + this, SLOT(sockClosed())); + TQObject::connect(sock, SIGNAL(error(int)), + this, SLOT(sockError(int))); + TQObject::connect(drw, SIGNAL(moved(const TQString&)), + this, SLOT(sendMove(const TQString&))); + TQObject::connect(drw, SIGNAL(newFigure(const TQString&, + GameBoard::FigureType)), + this, SLOT(sendFigure(const TQString&, GameBoard::FigureType))); + TQObject::connect(drw, SIGNAL(gameover(int)), + this, SLOT(gameover(int))); + TQObject::connect(edt, SIGNAL(returnPressed()), + this, SLOT(sendText())); + TQObject::connect(tmr, SIGNAL(timeout()), this, SLOT(sockTest())); + resize(XSize, YSize); + setMinimumSize(size()); + setMaximumSize(size()); + tmr->start(1000); +} + +GameBoard::~GameBoard() +{ + + GameProtocol::sendQuit(sock); + delete tmr; + delete hb; + delete hw; + delete hist; + delete edt; + delete lst; + delete box; + delete drw; + delete sock; + delete map; +} + + +void +GameBoard::resizeEvent(TQResizeEvent *e) +{ + TQFontMetrics fm(font()); + int w = e->size().width(), + h = e->size().height(), + fh = fm.lineSpacing() + 4; + + TQWidget::resizeEvent(e); + drw->move(0, 0); + box->move(drw->x(), drw->y() + drw->height()); + box->resize(w, h - box->y()); + edt->move(2, box->height() - fh - 2); + edt->resize(box->width() - edt->x() * 2, fh); + lst->move(edt->x(), fm.lineSpacing()); + lst->resize(edt->width(), edt->y() - lst->y()); + hist->move(drw->x() + drw->width(), drw->y()); + hist->resize(w - hist->x(), box->y()); + hw->move(2, TQFontMetrics(hist->font()).lineSpacing()); + hw->resize((hist->width() - hw->x()) / 2, + hist->height() - hw->y() - 2); + hb->move(hw->x() + hw->width(), hw->y()); + hb->resize(hw->size()); +} + + +void +GameBoard::focusInEvent(TQFocusEvent *e) +{ + + TQWidget::focusInEvent(e); + emit showStatus(my_stat); +} + + +void +GameBoard::initMap() +{ + + memset(map, NONE, 64 * sizeof(*map)); + if (gt == WHITE) { + map[0] = BLACK_CASTLE; + map[1] = BLACK_KNIGHT; + map[2] = BLACK_BISHOP; + map[3] = BLACK_QUEEN; + map[4] = BLACK_KING; + map[5] = BLACK_BISHOP; + map[6] = BLACK_KNIGHT; + map[7] = BLACK_CASTLE; + map[8] = BLACK_PAWN; + map[9] = BLACK_PAWN; + map[10] = BLACK_PAWN; + map[11] = BLACK_PAWN; + map[12] = BLACK_PAWN; + map[13] = BLACK_PAWN; + map[14] = BLACK_PAWN; + map[15] = BLACK_PAWN; + map[48] = WHITE_PAWN; + map[49] = WHITE_PAWN; + map[50] = WHITE_PAWN; + map[51] = WHITE_PAWN; + map[52] = WHITE_PAWN; + map[53] = WHITE_PAWN; + map[54] = WHITE_PAWN; + map[55] = WHITE_PAWN; + map[56] = WHITE_CASTLE; + map[57] = WHITE_KNIGHT; + map[58] = WHITE_BISHOP; + map[59] = WHITE_QUEEN; + map[60] = WHITE_KING; + map[61] = WHITE_BISHOP; + map[62] = WHITE_KNIGHT; + map[63] = WHITE_CASTLE; + } else { + map[0] = WHITE_CASTLE; + map[1] = WHITE_KNIGHT; + map[2] = WHITE_BISHOP; + map[3] = WHITE_KING; + map[4] = WHITE_QUEEN; + map[5] = WHITE_BISHOP; + map[6] = WHITE_KNIGHT; + map[7] = WHITE_CASTLE; + map[8] = WHITE_PAWN; + map[9] = WHITE_PAWN; + map[10] = WHITE_PAWN; + map[11] = WHITE_PAWN; + map[12] = WHITE_PAWN; + map[13] = WHITE_PAWN; + map[14] = WHITE_PAWN; + map[15] = WHITE_PAWN; + map[48] = BLACK_PAWN; + map[49] = BLACK_PAWN; + map[50] = BLACK_PAWN; + map[51] = BLACK_PAWN; + map[52] = BLACK_PAWN; + map[53] = BLACK_PAWN; + map[54] = BLACK_PAWN; + map[55] = BLACK_PAWN; + map[56] = BLACK_CASTLE; + map[57] = BLACK_KNIGHT; + map[58] = BLACK_BISHOP; + map[59] = BLACK_KING; + map[60] = BLACK_QUEEN; + map[61] = BLACK_BISHOP; + map[62] = BLACK_KNIGHT; + map[63] = BLACK_CASTLE; + } +} + + +void +GameBoard::showHostFound() +{ + + my_stat = tr("The host found"); + emit showStatus(my_stat); +} + + +void +GameBoard::sockConnected() +{ + + my_stat = tr("Connected to the host"); + emit showStatus(my_stat); + GameProtocol::setGameType(sock, gt); + edt->setEnabled(TRUE); +} + + +void +GameBoard::sockRead() +{ + TQString str; + + if (sock->canReadLine()) { + str = sock->readLine(); + str.remove(EOL); + str.remove('\r'); + parseString(str); + sock_tout = SOCK_WAIT; + } +} + + +void +GameBoard::sockClosed() +{ + + close(); +} + + +void +GameBoard::sockError(int err) +{ + TQString e; + + TQMessageBox::critical(this, tr("Socket Error..."), + tr("You have a socket error number") + ' ' + + TQString::number(err)); +} + + +void +GameBoard::parseString(const TQString &str) +{ + TQStringList lst(TQStringList::split(SEP, str)); + TQString s(lst[0].lower()); + int id; + + if (s == "game") { + s = lst[1].lower(); + if (s == "mate") { + updateHistory(GAMEOVER_TXT, TRUE); + gt = NOGAME; + gameover(0); + close(); + } else if (s == "stalemate") { + gt = NOGAME; + gameover(3); + close(); + } else if (s != "accept") { + if (s == "white") { + gt = BLACK; + s = tr("White"); + } else if (s == "black") { + gt = WHITE; + s = tr("Black"); + drw->setEnabled(TRUE); + setCursor(TQCursor(TQt::ArrowCursor)); + } + s += ' ' + tr("game from") + ' '; + my_stat = tr("Accepted the") + ' ' + s; + hst = sock->peerName(); + if (hst.isEmpty()) + hst = sock->peerAddress().toString() + ':' + + TQString::number(sock->peerPort()); + initMap(); + drw->repaint(TRUE); + GameProtocol::acceptGame(sock); + setCaption(s + hst); + my_stat += hst; + emit showStatus(my_stat); + } else if (gt == WHITE) { + drw->setEnabled(TRUE); + setCursor(TQCursor(TQt::ArrowCursor)); + } + } else if (s == "move") { + if (!drw->isEnabled()) { + drw->setEnabled(TRUE); + s = lst[1].lower(); + updateHistory(s, TRUE); + drw->makeMove(s); + setCursor(TQCursor(TQt::ArrowCursor)); + my_stat = tr("Your move..."); + emit showStatus(my_stat); + } + } else if (s == "quit") { + gt = NOGAME; + sockClosed(); + } else if (s == "chat") { + s = str.right(str.length() - 5); + updateChat('>' + s); + } else if (s == "figure") { + s = lst[1].lower(); + id = lst[2].toInt(); + drw->newFigure(s, id); + updateHistory(id, TRUE); + } +} + + +void +GameBoard::sendMove(const TQString &str) +{ + + GameProtocol::sendMove(sock, str); + drw->setEnabled(FALSE); + setCursor(TQCursor(TQt::WaitCursor)); + updateHistory(str, FALSE); + sock_tout = SOCK_WAIT; + my_stat = tr("Waiting a move..."); + emit showStatus(my_stat); +} + + +void +GameBoard::closeEvent(TQCloseEvent *e) +{ + int res; + + if (gt != NOGAME) { + res = TQMessageBox::question(this, tr("End the game"), + tr("Want you to end the game?\nYou will lose it"), + tr("Yes, end"), tr("No, continue"), TQString::null, 1); + if (res == 0) + TQWidget::closeEvent(e); + } else + TQWidget::closeEvent(e); +} + + +void +GameBoard::sendText() +{ + TQString s; + + s = edt->text().utf8(); + if (!s.isEmpty()) { + updateChat(s); + GameProtocol::sendText(sock, s.ascii()); + } + edt->clear(); +} + + +void +GameBoard::updateChat(const TQString &s) +{ + int fh, h; + + lst->insertItem(TQString::fromUtf8(s.ascii())); + h = lst->height(); + fh = TQFontMetrics(lst->font()).lineSpacing(); + if ((int)lst->count() * fh >= lst->visibleHeight()) + lst->removeItem(0); +} + + +void +GameBoard::updateHistory(const TQString &st, bool t) +{ + TQString s; + + if (st.length() == 3) { + if (st[0] == '@') + s = "O-O"; + else + s = st; + } else + s = st.left(2) + " - " + st.right(2); + if (t) { + if (gt == WHITE) + hb->insertItem(s); + else if (gt == BLACK) + hw->insertItem(s); + } else { + if (gt == WHITE) + hw->insertItem(s); + else if (gt == BLACK) + hb->insertItem(s); + } +} + + +void +GameBoard::updateHistory(int id, bool t) +{ + TQString s("; "), s1; + + switch (id) { + case 3: + s += tr("B"); + break; + case 4: + s += tr("K"); + break; + case 5: + s += tr("C"); + break; + case 10: + s += tr("Q"); + break; + default: + s += tr("Error!"); + } + if (t) { + if (gt == WHITE) { + id = hb->count() - 1; + s1 = hb->text(id); + hb->changeItem(s1 + s, id); + } else if (gt == BLACK) { + id = hw->count() - 1; + s1 = hw->text(id); + hw->changeItem(s1 + s, id); + } + } else { + if (gt == WHITE) { + id = hw->count() - 1; + s1 = hw->text(id); + hw->changeItem(s1 + s, id); + } else if (gt == BLACK) { + id = hb->count() - 1; + s1 = hb->text(id); + hb->changeItem(s1 + s, id); + } + } +} + + +void +GameBoard::sendFigure(const TQString &coo, GameBoard::FigureType ft) +{ + int id = -1; + + switch (ft) { + case BLACK_CASTLE: + case WHITE_CASTLE: + id = 5; + break; + + case BLACK_BISHOP: + case WHITE_BISHOP: + id = 3; + break; + + case BLACK_KNIGHT: + case WHITE_KNIGHT: + id = 4; + break; + + case BLACK_QUEEN: + case WHITE_QUEEN: + id = 10; + break; + default: + id = -1; + } + if (id != -1) { + GameProtocol::sendFigure(sock, coo, id); + updateHistory(id, FALSE); + } +} + + +void +GameBoard::sockTest() +{ + + --sock_tout; + if (sock_tout < 0) { + tmr->stop(); + HAXEP: + gt = NOGAME; + sockClosed(); + } else if ((sock->state() == TQSocket::HostLookup) && + (sock_tout + 60 < SOCK_WAIT)) { + tmr->stop(); + TQMessageBox::critical(this, tr("Lookup Error"), + tr("The host") + ' ' + hst + ' ' + tr("not found.")); + goto HAXEP; + } + +} + + +void +GameBoard::saveImage() +{ + TQString fn; + + fn = TQFileDialog::getSaveFileName(TQString::null, "*.png", this, NULL, + tr("Save image")); + + if (!fn.isEmpty()) { + if (fn.findRev(".png") < (int)(fn.length() - 4)) + fn += ".png"; + TQPixmap::grabWidget(this).save(fn, "PNG"); + } +} + + +void +GameBoard::gameover(int type) +{ + bool save = FALSE; + + TQString s('\n' + tr("Do you want to save the image?")), + yes(tr("Yes, save")), + no(tr("No, don't save")), + go(tr("Game over")); + + if (type == 0) { + save = (TQMessageBox::question(this, go, + tr("You scored the game") + s, yes, no) == 0); + } else if (type == 2) { + updateHistory(GAMEOVER_TXT, FALSE); + GameProtocol::sendGameover(sock, "MATE"); + save = (TQMessageBox::question(this, go, + tr("You have a mate.\nYou lost the game.") + s, + yes, no) == 0); + } else if (type == 3) { + GameProtocol::sendGameover(sock, "STALEMATE"); + save = (TQMessageBox::question(this, go, + tr("You have a stalemate") + s, yes, no) == 0); + } + + if (save) + saveImage(); +} + +//----------------------------------------------------------------------------- + +Drawer::Drawer(GameBoard::FigureType *ft, GameBoard::GameType *g, + TQWidget *parent, const char *name) + :TQWidget(parent, name, TQt::WResizeNoErase | TQt::WRepaintNoErase) +{ + TQFontMetrics fm(font()); + int i; + + map = ft; gt = g; + kk = rcm = lcm = km = FALSE; + cs = cell_size * 8; + top_margin = 5; + for (left_margin = 0, i = 0; i < 8; i++) + left_margin = MAX(fm.width(QString::number(i)), left_margin); + left_margin += top_margin; + hl = fm.lineSpacing() + 2; + setPaletteBackgroundColor(TQt::white); + i = MAX(cs + left_margin + top_margin, cs + top_margin + hl); + resize(i, i); + x_brd = i - cs - 6; + y_brd = 4; + tfx = tfy = -1; + fig[0] = TQPixmap((const char **)black_bishop); + fig[1] = TQPixmap((const char **)black_castle); + fig[2] = TQPixmap((const char **)black_knight); + fig[3] = TQPixmap((const char **)black_pawn); + fig[4] = TQPixmap((const char **)black_king); + fig[5] = TQPixmap((const char **)black_queen); + fig[6] = TQPixmap((const char **)white_bishop); + fig[7] = TQPixmap((const char **)white_castle); + fig[8] = TQPixmap((const char **)white_knight); + fig[9] = TQPixmap((const char **)white_pawn); + fig[10] = TQPixmap((const char **)white_king); + fig[11] = TQPixmap((const char **)white_queen); +} + +Drawer::~Drawer() +{ +} + + +void +Drawer::paintEvent(TQPaintEvent *e) +{ + TQPainter *p; + int w, y; + + w = width(); + y = w - 4; + TQWidget::paintEvent(e); + p = new TQPainter(this); + p->setPen(TQt::black); + p->drawRect(0, 0, w, w); + p->drawRect(2, 2, y, y); + p->drawLine(2, y, x_brd, cs + 4); + drawBoard(p, x_brd, y_brd); + drawMap(p, x_brd, y_brd); + delete p; +} + + +void +Drawer::drawBoard(TQPainter *p, int x, int y) +{ + int i, j, cs, x1, r, k; + char c, st; + + cs = Drawer::cs + 2; + p->setPen(TQt::black); + p->drawRect(x, y, cs, cs); + c = 'a'; st = 1; + r = (*gt == GameBoard::BLACK); + if (r) { + c += 7; + st = -st; + k = 1; + r ^= 1; + } else + k = 8; + x1 = x + 1; + for (j = 0, y++; j < 8; j++, y += cell_size, r ^= 1) { + for (i = 0, x = x1; i < 8; i++, x += cell_size) { + r ^= 1; + if (r) { + p->setPen(cw); + p->setBrush(cw); + } else { + p->setPen(cb); + p->setBrush(cb); + } + p->drawRect(x, y, cell_size, cell_size); + if (j == 7) { + p->setPen(Qt::black); + p->drawText(x, cs + 2, cell_size, hl, + TQt::AlignCenter, TQChar(c)); + c += st; + } + } + p->setPen(TQt::black); + p->drawText(x1 - left_margin, y, left_margin, cell_size, + TQt::AlignCenter, TQString::number(k)); + k -= st; + } + if ((tfx != -1) && (tfy != -1)) { + map2win(tfx, tfy, x, y); + p->setPen(TQPen(TQt::red, 2)); + p->setBrush(TQt::NoBrush); + p->drawRect(x, y, cell_size, cell_size); + } +} + + +void +Drawer::drawMap(TQPainter *p, int x, int y) +{ + int i, j, x1, n; + TQPixmap *xpm; + + x1 = x + 1; y++; + for (n = j = 0; j < 8; j++, y += cell_size) { + for (i = 0, x = x1; i < 8; i++, x += cell_size) { + switch (map[n++]) { + case GameBoard::WHITE_PAWN: + xpm = &fig[9]; + break; + case GameBoard::WHITE_CASTLE: + xpm = &fig[7]; + break; + case GameBoard::WHITE_BISHOP: + xpm = &fig[6]; + break; + case GameBoard::WHITE_KING: + xpm = &fig[10]; + break; + case GameBoard::WHITE_QUEEN: + xpm = &fig[11]; + break; + case GameBoard::WHITE_KNIGHT: + xpm = &fig[8]; + break; + case GameBoard::BLACK_PAWN: + xpm = &fig[3]; + break; + case GameBoard::BLACK_CASTLE: + xpm = &fig[1]; + break; + case GameBoard::BLACK_BISHOP: + xpm = &fig[0]; + break; + case GameBoard::BLACK_KING: + xpm = &fig[4]; + break; + case GameBoard::BLACK_QUEEN: + xpm = &fig[5]; + break; + case GameBoard::BLACK_KNIGHT: + xpm = &fig[2]; + break; + default: + xpm = NULL; + } + if (xpm != NULL) + p->drawPixmap(x, y, *xpm); + } + } +} + + +void +Drawer::mousePressEvent(TQMouseEvent *e) +{ + int x = e->x() - x_brd, + y = e->y() - y_brd; + + if ((x >= 0) && (x <= cs) && (y >= 0) && (y <= cs)) { + win2map(x, y); + if (hasTakenFigure()) { + if ((tfx == x) && (tfy == y)) { + tfx = tfy = -1; + repaint(FALSE); + } else + makeMove(*gt, tfx, tfy, x, y, FALSE, FALSE); + } else if (canTake(x, y)) { + takeFigure(x, y); + emit touchFigure(x, y); + } + } +} + + +bool +Drawer::canTake(int x, int y) +{ + + return (Figure::hasMyFigure(*gt, map, x, y, FALSE)); +} + + +void +Drawer::win2map(int &x, int &y) +{ + + if (*gt == GameBoard::WHITE) { + x /= cell_size; + y = 8 - y / cell_size; + x++; + } else if (*gt == GameBoard::BLACK) { + x = 8 - x / cell_size; + y /= cell_size; + y++; + } +} + + +void +Drawer::map2win(int mx, int my, int &x, int &y) +{ + + if (*gt == GameBoard::WHITE) { + x = (mx - 1) * cell_size + x_brd + 1; + y = (8 - my) * cell_size + y_brd + 1; + } else if (*gt == GameBoard::BLACK) { + x = (8 - mx) * cell_size + x_brd + 1; + y = (my - 1) * cell_size + y_brd + 1; + } else { + x = mx; + y = my; + } +} + + +void +Drawer::takeFigure(int x, int y) +{ + + if ((tfx == x) && (tfy == y)) + tfx = tfy = -1; + else { + tfx = x; + tfy = y; + } + repaint(FALSE); +} + + +bool +Drawer::hasTakenFigure() +{ + + return ((tfx != -1) && (tfy != -1)); +} + + +void +Drawer::newFigure(const TQString &coo, int id) +{ + GameBoard::FigureType ft; + int x, y, n; + + ft = GameBoard::NONE; n = -1; + Figure::str2map(coo, &x, &y); + if (*gt == GameBoard::WHITE) { + n = Figure::map2map(GameBoard::BLACK, x, y, TRUE); + switch (id) { + case 3: + ft = GameBoard::BLACK_BISHOP; + break; + case 4: + ft = GameBoard::BLACK_KNIGHT; + break; + case 5: + ft = GameBoard::BLACK_CASTLE; + break; + case 10: + ft = GameBoard::BLACK_QUEEN; + break; + default: + ft = GameBoard::NONE; + } + } else if (*gt == GameBoard::BLACK) { + n = Figure::map2map(GameBoard::WHITE, x, y, TRUE); + switch (id) { + case 3: + ft = GameBoard::WHITE_BISHOP; + break; + case 4: + ft = GameBoard::WHITE_KNIGHT; + break; + case 5: + ft = GameBoard::WHITE_CASTLE; + break; + case 10: + ft = GameBoard::WHITE_QUEEN; + break; + default: + ft = GameBoard::NONE; + } + } + + if (ft != GameBoard::NONE) { + map[n] = ft; + repaint(FALSE); + } +} + + +void +Drawer::makeMove(const TQString &txt) +{ + int fx, fy, tx, ty; + GameBoard::GameType et; + + if (*gt == GameBoard::WHITE) + et = GameBoard::BLACK; + else if (*gt == GameBoard::BLACK) + et = GameBoard::WHITE; + else + et = GameBoard::NOGAME; + if (txt == LONG_XCHG) { + if (et == GameBoard::BLACK) + makeMove(et, 1, 8, 4, 8, TRUE, TRUE); + else if (et == GameBoard::WHITE) + makeMove(et, 1, 1, 4, 1, TRUE, TRUE); + } else if (txt == SHORT_XCHG) { + if (et == GameBoard::BLACK) + makeMove(et, 8, 8, 6, 8, TRUE, TRUE); + else if (et == GameBoard::WHITE) + makeMove(et, 8, 1, 6, 1, TRUE, TRUE); + } else { + Figure::str2map(txt.left(2), &fx, &fy); + Figure::str2map(txt.right(2), &tx, &ty); + makeMove(et, fx, fy, tx, ty, TRUE, FALSE); + } +} + + +void +Drawer::makeMove(GameBoard::GameType gt, int fx, int fy, int tx, int ty, + bool mirror, bool xc) +{ + GameBoard::GameType et; + GameBoard::FigureType fo, old; + int res, nf, nt; + FigureDialog *dlg; + bool x; + TQPointArray vl; + + et = GameBoard::NOGAME; + nf = Figure::map2map(gt, fx, fy, mirror); + fo = map[nf]; + nt = Figure::map2map(gt, tx, ty, mirror); + old = map[nt]; + res = Figure::validMove(gt, map, fx, fy, tx, ty, mirror); + if (res) { + if (!mirror) { + x = FALSE; + if (gt == GameBoard::WHITE) + et = GameBoard::BLACK; + else if (gt == GameBoard::BLACK) + et = GameBoard::WHITE; + if (Figure::checkKing(et, map, mirror, vl, TRUE) != + 0) { + map[nf] = map[nt]; + map[nt] = old; + tfx = tfy = -1; + TQMessageBox::information(this, + tr("Error moving"), tr("You cannot " + "move this figure because the king " + "is in check") + '.'); + goto HAXEP; + } else + kk = FALSE; + if (!km && (!lcm || !rcm) && !kk) + x = xchg(fo, map[nt], fx, fy, tx, ty); + else + x = TRUE; + if (x) + emit moved(Figure::map2str(fx, fy) + + Figure::map2str(tx, ty)); + if ((res & 0xF) == 2) { + dlg = new FigureDialog(fig, gt, this); + dlg->exec(); + fo = dlg->figure(); + delete dlg; + map[nt] = fo; + emit newFigure(Figure::map2str(tx, ty), fo); + } + tfx = tfy = -1; + } else if (xc) { + if (gt == GameBoard::BLACK) + checkBlackCastle(fx, fy, tx, ty, TRUE); + else if (gt == GameBoard::WHITE) + checkWhiteCastle(fx, fy, tx, ty, TRUE); + } + if (mirror && (res & 0x10)) { + kk = TRUE; + } else if (res & 0x20) { + repaint(FALSE); + emit gameover(2); + return; + } else if (res & 0x40) { + repaint(FALSE); + emit gameover(3); + return; + } + HAXEP: + repaint(FALSE); + } +} + + +bool +Drawer::xchg(GameBoard::FigureType o, GameBoard::FigureType n, + int fx, int fy, int tx, int ty) +{ + bool ret = TRUE; + + if (*gt == GameBoard::WHITE) { + km = ((o == n) && (o == GameBoard::WHITE_KING)); + if (!km && ((o == n) && (o == GameBoard::WHITE_CASTLE))) + ret = checkWhiteCastle(fx, fy, tx, ty, FALSE); + } else if (*gt == GameBoard::BLACK) { + km = ((o == n) && (o == GameBoard::BLACK_KING)); + if (!km && ((o == n) && (o == GameBoard::BLACK_CASTLE))) + ret = checkBlackCastle(fx, fy, tx, ty, FALSE); + } + + return (ret); +} + + +bool +Drawer::checkWhiteCastle(int fx, int fy, int tx, int ty, bool mirror) +{ + int n1, n2; + bool ret = TRUE; + + n1 = n2 = -1; + if ((fx == 1) && (fy == 1)) { + if ((tx == 4) && (ty == 1)) + if (mirror) { + n1 = Figure::map2map(*gt, 5, 1, FALSE); + n2 = Figure::map2map(*gt, 3, 1, FALSE); + } else if (!lcm) { + if (makeXchg()) { + n1 = Figure::map2map(*gt, 5, 1, FALSE); + n2 = Figure::map2map(*gt, 3, 1, FALSE); + emit moved(LONG_XCHG); + ret = FALSE; + rcm = TRUE; + } + lcm = TRUE; + } + } else if ((fx == 8) && (fy == 1)) { + if ((tx == 6) && (ty == 1)) + if (mirror) { + n1 = Figure::map2map(*gt, 5, 1, FALSE); + n2 = Figure::map2map(*gt, 7, 1, FALSE); + } else if (!rcm) { + if (makeXchg()) { + n1 = Figure::map2map(*gt, 5, 1, FALSE); + n2 = Figure::map2map(*gt, 7, 1, FALSE); + emit moved(SHORT_XCHG); + ret = FALSE; + lcm = TRUE; + } + rcm = TRUE; + } + } + if (n1 != n2) { + map[n2] = map[n1]; + map[n1] = GameBoard::NONE; + } + + return (ret); +} + + +bool +Drawer::checkBlackCastle(int fx, int fy, int tx, int ty, bool mirror) +{ + int n1, n2; + bool ret = TRUE; + + n1 = n2 = -1; + if ((fx == 1) && (fy == 8)) { + if ((tx == 4) && (ty == 8)) { + if (mirror) { + n1 = Figure::map2map(*gt, 5, 8, FALSE); + n2 = Figure::map2map(*gt, 3, 8, FALSE); + } else if (!rcm) { + if (makeXchg()) { + n1 = Figure::map2map(*gt, 5, 8, FALSE); + n2 = Figure::map2map(*gt, 3, 8, FALSE); + emit moved(LONG_XCHG); + ret = FALSE; + } + rcm = TRUE; + } + } + } else if ((fx == 8) && (fy == 8)) { + if ((tx == 6) && (ty == 8)) + if (mirror) { + n1 = Figure::map2map(*gt, 5, 8, FALSE); + n2 = Figure::map2map(*gt, 7, 8, FALSE); + } else if (!lcm) { + if (makeXchg()) { + n1 = Figure::map2map(*gt, 5, 8, FALSE); + n2 = Figure::map2map(*gt, 7, 8, FALSE); + emit moved(SHORT_XCHG); + ret = FALSE; + } + lcm = TRUE; + } + } + if (n1 != n2) { + map[n2] = map[n1]; + map[n1] = GameBoard::NONE; + } + + return (ret); +} + + +bool +Drawer::makeXchg() +{ + + return (TQMessageBox::question(this, tr("To castle"), + tr("Do you want to castle?"), tr("Yes"), tr("No")) == 0); +} + + +//----------------------------------------------------------------------------- + +FigureDialog::FigureDialog(const TQPixmap *f, const GameBoard::GameType g, + TQWidget *parent, const char *name):TQDialog(parent, name) +{ + TQFontMetrics fm(font()); + int w, h; + + gt = g; fig = f; + if (gt == GameBoard::WHITE) + fr = GameBoard::WHITE_QUEEN; + else if (gt == GameBoard::BLACK) + fr = GameBoard::BLACK_QUEEN; + str = tr("What figure should I set?"); + setCaption(str); + fh = fm.lineSpacing() + 2; + h = cell_size + fh; + w = MAX(cell_size * 4, fm.width(str)); + step = (w - cell_size * 4) / 2; + resize(w, h); + setMinimumSize(size()); + setMaximumSize(size()); +} + +FigureDialog::~FigureDialog() +{ +} + + +void +FigureDialog::paintEvent(TQPaintEvent *e) +{ + TQPainter *p; + int x, f = -1; + + TQDialog::paintEvent(e); + p = new TQPainter(this); + + p->setPen(TQt::black); + p->drawText(0, 0, width(), fh, TQt::AlignCenter, str); + x = step; + if (gt == GameBoard::BLACK) + f = 0; + else if (gt == GameBoard::WHITE) + f = 6; + p->drawPixmap(x, fh, fig[f]); x += cell_size; + p->drawPixmap(x, fh, fig[f + 1]); x += cell_size; + p->drawPixmap(x, fh, fig[f + 2]); x += cell_size; + p->drawPixmap(x, fh, fig[f + 5]); + + delete p; +} + + +void +FigureDialog::mousePressEvent(TQMouseEvent *e) +{ + int x = e->x(), + y = e->y(), + f = -1; + + if (e->button() == TQt::LeftButton) { + if ((x >= step) && (x <= width() - step) && (y >= fh) && + (y <= height())) + f = (x - step) / cell_size; + } + + if (f != -1) { + if (gt == GameBoard::WHITE) + switch (f) { + case 0: + fr = GameBoard::WHITE_BISHOP; + break; + case 1: + fr = GameBoard::WHITE_CASTLE; + break; + case 2: + fr = GameBoard::WHITE_KNIGHT; + break; + case 3: + default: + fr = GameBoard::WHITE_QUEEN; + } + else if (gt == GameBoard::BLACK) + switch (f) { + case 0: + fr = GameBoard::BLACK_BISHOP; + break; + case 1: + fr = GameBoard::BLACK_CASTLE; + break; + case 2: + fr = GameBoard::BLACK_KNIGHT; + break; + case 3: + default: + fr = GameBoard::BLACK_QUEEN; + } + accept(); + } +} + + +//----------------------------------------------------------------------------- + +void +GameProtocol::send(TQSocket *sock, const TQString &dat) +{ + TQString s(dat + EOL); + const char *buf; + + if (sock->state() == TQSocket::Connected) { + buf = s.ascii(); + sock->writeBlock(buf, s.length()); + sock->flush(); + } +} + + +void +GameProtocol::setGameType(TQSocket *sock, GameBoard::GameType gt) +{ + TQString d("GAME"); + + d += SEP; + if (gt == GameBoard::WHITE) + d += "WHITE"; + else if (gt == GameBoard::BLACK) + d += "BLACK"; + else + d += "NOGAME"; + send(sock, d); +} + + +void +GameProtocol::acceptGame(TQSocket *sock) +{ + TQString d("GAME"); + + d += SEP; + d += "ACCEPT"; + send(sock, d); +} + + +void +GameProtocol::sendMove(TQSocket *sock, const TQString &coo) +{ + TQString d("MOVE"); + + d += SEP; + d += coo; + send(sock, d); +} + + +void +GameProtocol::sendQuit(TQSocket *sock) +{ + + send(sock, "QUIT"); +} + + +void +GameProtocol::sendText(TQSocket *sock, const TQString &txt) +{ + TQString d("CHAT"); + + d += SEP; + d += txt; + send(sock, d); +} + + +void +GameProtocol::sendFigure(TQSocket *sock, const TQString &coo, int id) +{ + TQString d("FIGURE"); + + d += SEP; + d += coo; + d += SEP; + d += TQString::number(id); + send(sock, d); +} + + +void +GameProtocol::sendGameover(TQSocket *sock, const TQString &got) +{ + TQString d("GAME"); + + d += SEP; + d += got; + send(sock, d); +} + +#include "gameboard.moc" |