You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/qnetchess/src/gameboard.cpp

1988 lines
42 KiB

/*
* $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, &gt, 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, &gt, 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"