Source Code (Use browser search to find items of interest.)
Class Index
kshisen'Board (./kdegames/kshisen/board.h:68)
class Board : public QWidget {
Q_OBJECT
public:
Board(QWidget *parent = 0);
~Board();
virtual void paintEvent(QPaintEvent *);
virtual void mousePressEvent(QMouseEvent *);
virtual QSize sizeHint();
void setDelay(int);
int getDelay();
bool canUndo();
bool canRedo();
void redo();
void undo();
void setSize(int x, int y);
void newGame();
void setShuffle(int);
int getShuffle();
void getHint();
bool getHint_I(int &, int &, int &, int &, History h[4]);
#ifdef DEBUGGING
void makeHintMove();
void finish();
#endif
int tilesLeft();
int getCurrentTime();
int getTimeForGame();
bool solvable(bool norestore = FALSE);
bool getSolvableFlag();
void setSolvableFlag(bool);
bool gravityFlag();
void setGravityFlag(bool);
int x_tiles();
int y_tiles();
bool isPaused() { return paused; }
signals:
void fieldClicked(int, int);
void markError();
void markMatched();
void madeMove(int, int, int, int);
void changed();
void sizeChange();
void endOfGame();
public slots:
bool pause();
private slots:
void marked(int, int);
void undrawArrow();
void slotMadeMove(int, int, int, int);
void gravity(int, bool);
private: // functions
bool loadTiles(float scale = 1.0);
void initBoard();
void setField(int x, int y, int value);
int getField(int x, int y);
void updateField(int, int);
QPixmap *lighten(QPixmap *src);
bool canMakePath(int x1, int y1, int x2, int y2);
bool findPath(int x1, int y1, int x2, int y2);
bool findSimplePath(int x1, int y1, int x2, int y2);
void drawArrow(int, int, int, int);
QPoint midCoord(int, int);
void clearHistory();
private:
time_t starttime;
time_t time_for_game;
QPixmap *pausedIcon;
KRandomSequence random;
QList<Move> _undo;
QList<Move> _redo;
int undraw_timer_id;
int mark_x;
int mark_y;
History history[4];
int *field;
QPixmap *pm_tile[45];
int _x_tiles;
int _y_tiles;
int _delay;
int _shuffle;
bool paused;
time_t pause_start;
bool trying;
bool gravity_flag;
bool _solvable_flag;
int grav_col_1, grav_col_2;
int highlighted_tile;
};
kshisen'Board::Board() (./kdegames/kshisen/board.cpp:67)
Board::Board(QWidget *parent) : QWidget(parent) {
pausedIcon = 0;
paused = false;
trying = false;
_solvable_flag = true;
grav_col_1 = -1;
grav_col_2 = -1;
setGravityFlag(false);
// randomze
setShuffle(DEFAULTSHUFFLE);
random.setSeed(0);
starttime = time((time_t *)0);
for(int i = 0; i < 45; i++)
pm_tile[i] = 0;
setDelay(DEFAULTDELAY);
_redo.setAutoDelete(true);
_undo.setAutoDelete(true);
loadTiles(1);
field = 0;
QPixmap bg(KGlobal::dirs()->findResource("appdata", "kshisen_bgnd.xpm"));
setBackgroundPixmap(bg);
connect(this, SIGNAL(fieldClicked(int, int)),
this, SLOT(marked(int, int)));
connect(this, SIGNAL(madeMove(int, int, int, int)),
this, SLOT(slotMadeMove(int, int, int, int)));
setShuffle(0);
setSize(18, 8);
highlighted_tile = -1;
}
kshisen'Board::~Board() (./kdegames/kshisen/board.cpp:104)
Board::~Board() {
for(int i = 0; i < 36; i++)
if(pm_tile[i])
delete pm_tile[i];
}
kshisen'Board::x_tiles() (./kdegames/kshisen/board.cpp:110)
int Board::x_tiles() {
return _x_tiles;
}
kshisen'Board::y_tiles() (./kdegames/kshisen/board.cpp:114)
int Board::y_tiles() {
return _y_tiles;
}
kshisen'Board::setField() (./kdegames/kshisen/board.cpp:118)
void Board::setField(int x, int y, int value) {
if(x < x_tiles() && y < y_tiles())
field[y * x_tiles() + x] = value;
else {
fprintf(stderr, "write access to invalid field (%d,%d)\n", x, y);
exit(1);
}
}
kshisen'Board::getField() (./kdegames/kshisen/board.cpp:127)
int Board::getField(int x, int y) {
if(x == x_tiles() || x == -1)
return EMPTY;
else if(y == y_tiles() || y == -1)
return EMPTY;
else if(x < -1 || x > x_tiles() || y < -1 || y > y_tiles()) {
return EMPTY;
fprintf(stderr, "read access to invalid field (%d,%d)\n", x, y);
exit(1);
return 0; // makes gcc happy
} else
return field[y * x_tiles() + x];
}
kshisen'Board::gravity() (./kdegames/kshisen/board.cpp:141)
void Board::gravity(int col, bool update) {
if(gravity_flag) {
int rptr = y_tiles()-1, wptr = y_tiles()-1;
while(rptr >= 0) {
if(getField(col, wptr) != EMPTY) {
rptr--;
wptr--;
} else {
if(getField(col, rptr) != EMPTY) {
setField(col, wptr, getField(col, rptr));
setField(col, rptr, EMPTY);
if(update) {
updateField(col, rptr);
updateField(col, wptr);
}
wptr--;
rptr--;
} else
rptr--;
}
}
}
}
kshisen'Board::mousePressEvent() (./kdegames/kshisen/board.cpp:165)
void Board::mousePressEvent(QMouseEvent *e) {
// calculate position
int pos_x = (e->pos().x() - XBORDER <0)?-1:
(e->pos().x() - XBORDER) / pm_tile[0]->width();
int pos_y = (e->pos().y() - YBORDER <0)?-1:
(e->pos().y() - YBORDER) / pm_tile[0]->height();
// Mark tile
if(e->button() == LeftButton) {
if(highlighted_tile != -1) {
int oldmarkx = mark_x;
int oldmarky = mark_y;
mark_x=-1; mark_y=-1;
for(int i = 0; i < x_tiles(); i++)
for(int j = 0; j < y_tiles(); j++){
if( highlighted_tile == getField(i, j))
updateField(i, j);
}
mark_x = oldmarkx;
mark_y = oldmarky; // no tile selected
highlighted_tile = -1;
}
if(pos_x >= 0 && pos_x < x_tiles() && pos_y >= 0 && pos_y < y_tiles())
emit fieldClicked(pos_x, pos_y);
}
// Assist by lighting all tiles of same type
if(e->button() == RightButton) {
int field = getField(pos_x,pos_y);
highlighted_tile = field;
for(int i = 0; i < x_tiles(); i++)
for(int j = 0; j < y_tiles(); j++){
if( field == getField(i, j)){
mark_x=i; mark_y=j;
}
else{
mark_x=-1; mark_y=-1;
}
updateField(i, j);
}
mark_x=-1; mark_y=-1; // no tile selected
}
}
kshisen'Board::setSize() (./kdegames/kshisen/board.cpp:212)
void Board::setSize(int x, int y) {
if(x == x_tiles() && y == y_tiles())
return;
if(field != 0)
delete [] field;
field = new int[ x * y ];
_x_tiles = x;
_y_tiles = y;
for(int i = 0; i < x; i++)
for(int j = 0; j < y; j++)
setField(i, j, EMPTY);
loadTiles();
double scaler = 1.0;
while(sizeHint().width() > kapp->desktop()->width() - 2*XBORDER ||
sizeHint().height() > kapp->desktop()->height() - 2*YBORDER) {
scaler -= 0.2;
loadTiles(scaler);
}
newGame();
emit changed();
emit sizeChange();
}
kshisen'Board::loadTiles() (./kdegames/kshisen/board.cpp:239)
bool Board::loadTiles(float scale) {
int i, j, x, y;
// delete old tiles
for(i = 0; i < 45; i++)
if(pm_tile[i] != 0) {
delete pm_tile[i];
pm_tile[i] = 0;
}
// locate tileset
QPixmap pm(KGlobal::dirs()->findResource("appdata", "kshisen.xpm"));
QBitmap mask(KGlobal::dirs()->findResource("appdata", "mask.xpm"));
if(pm.width() == 0 || pm.height() == 0) {
QMessageBox::warning(this, kapp->caption(),
i18n("Cannot load pixmaps!"),
i18n("OK"));
exit(1);
}
pm.setMask(mask);
if(pm.width() == 0 || pm.height() == 0)
return false;
x = pm.width() / 9;
y = pm.height() / 5;
for(i = 0; i < 9; i++)
for(j = 0; j < 5; j++) {
pm_tile[i + j*9] = new QPixmap(x,y);
QBitmap bm(x, y);
bitBlt(pm_tile[i + j*9], 0, 0, &pm, x * i, y * j, x, y, CopyROP);
bitBlt(&bm, 0, 0, &mask, x *i, y * j, x, y, CopyROP);
pm_tile[i+j*9]->setMask(bm);
if(scale != 1.0) {
QWMatrix wm;
wm.scale(scale, scale);
*pm_tile[i + j*9] = pm_tile[i + j*9]->xForm(wm);
}
}
return true;
}
kshisen'Board::newGame() (./kdegames/kshisen/board.cpp:282)
void Board::newGame() {
int i, j, x, y, k;
mark_x = -1;
mark_y = -1;
while(_undo.count())
_undo.removeFirst();
while(_redo.count())
_redo.removeFirst();
clearHistory();
for(i = 0; i < x_tiles(); i++)
for(j = 0; j < y_tiles(); j++)
setField(i, j, EMPTY);
// distribute all tiles on board
int cur_tile = 0;
for(i = 0; i < x_tiles() * y_tiles() * 12; i++) {
// map the tileindex to a tile
// not all tiles from the pixmap are really used, only
// 36 out of 45 are used. This maps and index to
// the "real" index.
int tile;
if(cur_tile == 28)
tile = 30;
else if(cur_tile >= 29 && cur_tile <= 35)
tile = cur_tile + 7;
else
tile = cur_tile;
cur_tile++;
if(cur_tile == 36)
cur_tile = 0;
x = i % x_tiles();
y = i / x_tiles() * 4;
tile++;
for(k = 0; k < 4 && k + y < y_tiles(); k++)
setField(x, y+k, tile);
}
if(getShuffle() == 0) {
if(!trying) {
update();
starttime = time((time_t *)0);
emit changed();
}
return;
}
// shuffle the field
int tx = x_tiles();
int ty = y_tiles();
for(i = 0; i < x_tiles() * y_tiles() * getShuffle(); i++) {
int x1 = random.getLong(tx);
int y1 = random.getLong(ty);
int x2 = random.getLong(tx);
int y2 = random.getLong(ty);
int t = getField(x1, y1);
setField(x1, y1, getField(x2, y2));
setField(x2, y2, t);
}
// do not make solvable if _solvable_flag is false
if(!_solvable_flag) {
if(!trying) {
update();
starttime = time((time_t *)0);
emit changed();
}
return;
}
int fsize = x_tiles() * y_tiles() * sizeof(int);
int *oldfield = new int[x_tiles() * y_tiles()];
memcpy(oldfield, field, fsize); // save field
int *tiles = new int[x_tiles() * y_tiles()];
int *pos = new int[x_tiles() * y_tiles()];
while(!solvable(true)) {
// generate a list of free tiles and positions
int num_tiles = 0;
for(i = 0; i < x_tiles() * y_tiles(); i++)
if(field[i] != EMPTY) {
pos[num_tiles] = i;
tiles[num_tiles] = field[i];
num_tiles++;
}
// restore field
memcpy(field, oldfield, fsize);
// redistribute unsolved tiles
while(num_tiles > 0) {
// get a random tile
int r1 = random.getLong(num_tiles);
int r2 = random.getLong(num_tiles);
int tile = tiles[r1];
int apos = pos[r2];
// truncate list
tiles[r1] = tiles[num_tiles-1];
pos[r2] = pos[num_tiles-1];
num_tiles--;
// put this tile on the new position
field[apos] = tile;
}
// remember field
memcpy(oldfield, field, fsize);
}
// restore field
memcpy(field, oldfield, fsize);
delete tiles;
delete pos;
delete oldfield;
if(!trying) {
update();
starttime = time((time_t *)0);
emit changed();
}
}
kshisen'Board::updateField() (./kdegames/kshisen/board.cpp:413)
void Board::updateField(int x, int y) {
if(trying)
return;
QRect r(XBORDER + x * pm_tile[0]->width(),
YBORDER + y * pm_tile[0]->height(),
pm_tile[0]->width(),
pm_tile[0]->height());
if(isUpdatesEnabled())
repaint(r, true);
}
kshisen'Board::lighten() (./kdegames/kshisen/board.cpp:439)
QPixmap *Board::lighten(QPixmap *src) {
const float FACTOR = 1.3;
QImage img = src->convertToImage();
if(img.depth() > 8) { // at least high-color
for(int y = 0; y < src->height(); y++) {
uchar *p = (uchar *)img.scanLine(y);
for(int x = 0; x < src->width() * 4; x++) {
*p = (unsigned char)MIN(255, (int)(FACTOR * (*p)));
p++;
}
}
} else { // image has a palette
// get background color index
int idx = img.pixelIndex(8, 1); // should work for all tiles
img.setColor(idx, QColor(img.color(idx)).light().rgb());
}
QPixmap *pm = new QPixmap();
pm->convertFromImage(img);
return pm;
}
kshisen'Board::paintEvent() (./kdegames/kshisen/board.cpp:462)
void Board::paintEvent(QPaintEvent *e) {
QPainter p;
p.begin(this);
if(paused) {
if(!pausedIcon)
pausedIcon = new QPixmap(KGlobal::dirs()->findResource("appdata", "paused.xpm"));
p.drawPixmap((width()-pausedIcon->width())/2,
(height()-pausedIcon->height())/2,
*pausedIcon);
} else {
for(int i = 0; i < x_tiles(); i++)
for(int j = 0; j < y_tiles(); j++) {
if(getField(i, j) == EMPTY)
continue;
int xpos = XBORDER + i * pm_tile[1]->width();
int ypos = YBORDER + j * pm_tile[1]->height();
QRect r(xpos, ypos, pm_tile[1]->width(), pm_tile[1]->height());
if(e->rect().intersects(r)) {
// check if it is a marked piece
if(i == mark_x && j == mark_y) {
QPixmap *lpm = lighten(pm_tile[getField(i, j)-1]);
p.drawPixmap(xpos, ypos, *lpm);
delete lpm;
} else
p.drawPixmap(xpos, ypos, *pm_tile[getField(i, j)-1]);
}
}
}
p.end();
}
kshisen'Board::marked() (./kdegames/kshisen/board.cpp:496)
void Board::marked(int x, int y) {
// make sure that the last arrow is correctly undrawn
undrawArrow();
if(getField(x, y) == EMPTY)
return;
if(x == mark_x && y == mark_y) {
// unmark the piece
mark_x = -1;
mark_y = -1;
updateField(x, y);
return;
}
if(mark_x == -1) {
mark_x = x;
mark_y = y;
updateField(x, y);
return;
} else {
int fld1 = getField(mark_x, mark_y);
int fld2 = getField(x, y);
// both field same?
if(fld1 != fld2) {
emit markError();
return;
}
// trace
if(findPath(mark_x, mark_y, x, y)) {
emit madeMove(mark_x, mark_y, x, y);
drawArrow(mark_x, mark_y, x, y);
setField(mark_x, mark_y, EMPTY);
setField(x, y, EMPTY);
grav_col_1 = x;
grav_col_2 = mark_x;
mark_x = -1;
mark_y = -1;
int dummyx;
History dummyh[4];
// game is over?
if(!getHint_I(dummyx,dummyx,dummyx,dummyx,dummyh)) {
time_for_game = (int)difftime( time((time_t)0), starttime);
emit endOfGame();
}
} else {
clearHistory();
emit markError();
}
}
}
kshisen'Board::canMakePath() (./kdegames/kshisen/board.cpp:553)
bool Board::canMakePath(int x1, int y1, int x2, int y2) {
int i;
if(x1 == x2) {
for(i = MIN(y1, y2)+1; i < MAX(y1, y2); i++)
if(getField(x1, i) != EMPTY)
return false;
return true;
}
if(y1 == y2) {
for(i = MIN(x1, x2)+1; i < MAX(x1, x2); i++)
if(getField(i, y1) != EMPTY)
return false;
return true;
}
return false;
}
kshisen'Board::findPath() (./kdegames/kshisen/board.cpp:575)
bool Board::findPath(int x1, int y1, int x2, int y2) {
clearHistory();
if(findSimplePath(x1, y1, x2, y2))
return true;
else {
// find 3-way path
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int i;
for(i = 0; i < 4; i++) {
int newx = x1 + dx[i], newy = y1 + dy[i];
while(getField(newx, newy) == EMPTY &&
newx >= -1 && newx <= x_tiles() &&
newy >= -1 && newy <= y_tiles()) {
if(findSimplePath(newx, newy, x2, y2)) {
// make place for history point
for(int j = 3; j > 0; j--)
history[j] = history[j-1];
// insert history point
history[0].x = x1;
history[0].y = y1;
return true;
}
newx += dx[i];
newy += dy[i];
}
}
clearHistory();
return false;
}
return false;
}
kshisen'Board::findSimplePath() (./kdegames/kshisen/board.cpp:614)
bool Board::findSimplePath(int x1, int y1, int x2, int y2) {
bool r = false;
// find direct line
if(canMakePath(x1, y1, x2, y2)) {
history[0].x = x1;
history[0].y = y1;
history[1].x = x2;
history[1].y = y2;
r = true;
} else {
if(!(x1 == x2 || y1 == y2)) // requires complex path
if(getField(x2, y1) == EMPTY &&
canMakePath(x1, y1, x2, y1) && canMakePath(x2, y1, x2, y2)) {
history[0].x = x1;
history[0].y = y1;
history[1].x = x2;
history[1].y = y1;
history[2].x = x2;
history[2].y = y2;
r = true;
} else if(getField(x1, y2) == EMPTY &&
canMakePath(x1, y1, x1, y2) && canMakePath(x1, y2, x2, y2)) {
history[0].x = x1;
history[0].y = y1;
history[1].x = x1;
history[1].y = y2;
history[2].x = x2;
history[2].y = y2;
r = true;
}
}
return r;
}
kshisen'Board::drawArrow() (./kdegames/kshisen/board.cpp:650)
void Board::drawArrow(int x1, int y1, int x2, int y2) {
if(trying)
return;
// find out number of array
int num = 0;
while(num < 4 && history[num].x != -2)
num++;
// lighten the fields
// remember mark_x,mark_y
int mx = mark_x, my = mark_y;
mark_x = x1; mark_y = y1;
updateField(x1, y1);
mark_x = x2; mark_y = y2;
updateField(x2, y2);
// restore the mark
mark_x = mx;
mark_y = my;
QPainter p;
p.begin(this);
p.setPen(QPen(QColor("red"), 6));
num = 0;
while(num < 3 && history[num+1].x != -2) {
p.drawLine(midCoord(history[num].x, history[num].y),
midCoord(history[num+1].x, history[num+1].y));
num++;
}
p.flush();
p.end();
QTimer::singleShot(getDelay(), this, SLOT(undrawArrow()));
}
kshisen'Board::undrawArrow() (./kdegames/kshisen/board.cpp:686)
void Board::undrawArrow() {
if(trying)
return;
if(grav_col_1 != -1 || grav_col_2 != -1) {
gravity(grav_col_1, true);
gravity(grav_col_2, true);
grav_col_1 = -1;
grav_col_2 = -1;
}
// is already undrawn?
if(history[0].x == -2)
return;
// redraw all affected fields
int num = 0;
while(num < 3 && history[num+1].x != -2) {
if(history[num].y == history[num+1].y)
for(int i = MIN(history[num].x, history[num+1].x);
i <= MAX(history[num].x, history[num+1].x); i++)
updateField(i, history[num].y);
else
for(int i = MIN(history[num].y, history[num+1].y);
i <= MAX(history[num].y, history[num+1].y); i++)
updateField(history[num].x, i);
num++;
}
clearHistory();
}
kshisen'Board::midCoord() (./kdegames/kshisen/board.cpp:718)
QPoint Board::midCoord(int x, int y) {
QPoint p;
int w = pm_tile[0]->width();
int h = pm_tile[0]->height();
if(x == -1)
p.setX(XBORDER/2 - w/2);
else if(x == x_tiles())
p.setX(XBORDER/2 + w * x_tiles());
else
p.setX(XBORDER + w * x);
if(y == -1)
p.setY(YBORDER/2 - h/2);
else if(y == y_tiles())
p.setY(YBORDER/2 + h * y_tiles());
else
p.setY(YBORDER + h * y);
p.setX(p.x() + w/2);
p.setY(p.y() + h/2);
return p;
}
kshisen'Board::setDelay() (./kdegames/kshisen/board.cpp:742)
void Board::setDelay(int newvalue) {
_delay = newvalue;
}
kshisen'Board::getDelay() (./kdegames/kshisen/board.cpp:746)
int Board::getDelay() {
return _delay;
}
kshisen'Board::slotMadeMove() (./kdegames/kshisen/board.cpp:750)
void Board::slotMadeMove(int x1, int y1, int x2, int y2) {
Move *m = new Move(x1, y1, x2, y2, getField(x1, y1));
_undo.append(m);
while(_redo.count())
_redo.removeFirst();
emit changed();
}
kshisen'Board::canUndo() (./kdegames/kshisen/board.cpp:758)
bool Board::canUndo() {
return (bool)(_undo.count() > 0);
}
kshisen'Board::canRedo() (./kdegames/kshisen/board.cpp:762)
bool Board::canRedo() {
return (bool)(_redo.count() > 0);
}
kshisen'Board::undo() (./kdegames/kshisen/board.cpp:766)
void Board::undo() {
if(canUndo()) {
undrawArrow();
Move *m = _undo.take(_undo.count() - 1);
if(gravityFlag()) {
int y;
int delta = 1;
if(m->x1 == m->x2) {
delta++;
/* damned, I hate this. This undo/redo stuff is really complicated
* when used with gravity. This avoids a bug when both tiles reside
* in the same row, but not adjascent y positions. In that case, the
* order of undo is important
*/
if(m->y1>m->y2) {
int t = m->x1;
m->x1 = m->x2;
m->x2 = t;
t = m->y1;
m->y1 = m->y2;
m->y2 = t;
}
}
for(y = 0; y <= m->y1-1; y++) {
setField(m->x1, y, getField(m->x1, y+delta));
updateField(m->x1, y);
}
if(m->x1 != m->x2) {
for(y = 0; y < m->y2; y++) {
setField(m->x2, y, getField(m->x2, y+1));
updateField(m->x2, y);
}
}
}
setField(m->x1, m->y1, m->tile);
setField(m->x2, m->y2, m->tile);
updateField(m->x1, m->y1);
updateField(m->x2, m->y2);
_redo.insert(0, m);
emit changed();
}
}
kshisen'Board::redo() (./kdegames/kshisen/board.cpp:814)
void Board::redo() {
if(canRedo()) {
undrawArrow();
Move *m = _redo.take(0);
setField(m->x1, m->y1, EMPTY);
setField(m->x2, m->y2, EMPTY);
updateField(m->x1, m->y1);
updateField(m->x2, m->y2);
gravity(m->x1, true);
gravity(m->x2, true);
_undo.append(m);
emit changed();
}
}
kshisen'Board::sizeHint() (./kdegames/kshisen/board.cpp:829)
QSize Board::sizeHint() {
return QSize(x_tiles() * pm_tile[0]->width() + 2 * XBORDER,
y_tiles() * pm_tile[0]->height() + 2 * YBORDER);
}
kshisen'Board::clearHistory() (./kdegames/kshisen/board.cpp:834)
void Board::clearHistory() {
// init history
for(int i = 0; i < 4; i++) {
history[i].x = -2;
history[i].y = -2;
}
}
kshisen'Board::getHint() (./kdegames/kshisen/board.cpp:842)
void Board::getHint() {
int x1, y1, x2, y2;
History h[4];
if(getHint_I(x1, y1, x2, y2, h)) {
undrawArrow();
for(int i = 0; i < 4; i++)
history[i] = h[i];
int old_delay = getDelay();
setDelay(1000);
drawArrow(x1, y1, x2, y2);
setDelay(old_delay);
}
}
kshisen'Board::makeHintMove() (./kdegames/kshisen/board.cpp:860)
void Board::makeHintMove() {
int x1, y1, x2, y2;
History h[4];
if(getHint_I(x1, y1, x2, y2, h)) {
mark_x = -1;
mark_y = -1;
marked(x1, y1);
marked(x2, y2);
}
}
kshisen'Board::finish() (./kdegames/kshisen/board.cpp:872)
void Board::finish() {
int x1, y1, x2, y2;
History h[4];
bool ready=false;
while(!ready && getHint_I(x1, y1, x2, y2, h)) {
mark_x = -1;
mark_y = -1;
if(tilesLeft() == 2)
ready = true;
marked(x1, y1);
marked(x2, y2);
kapp->processEvents();
usleep(250*1000);
}
}
kshisen'Board::getHint_I() (./kdegames/kshisen/board.cpp:890)
bool Board::getHint_I(int &x1, int &y1, int &x2, int &y2, History h[4]) {
short done[45];
for( short index = 0; index < 45; index++ )
done[index] = 0;
// remember old history
History old[4];
for(int i = 0; i < 4; i++)
old[i] = history[i];
// initial no hint
x1 = -1;
x2 = -1;
y1 = -1;
y2 = -1;
for(int x = 0; x < x_tiles(); x++)
for(int y = 0; y < y_tiles(); y++)
if(getField(x, y) != EMPTY && done[getField(x, y)] != 4) {
int tile = getField(x, y);
// for all these types of tile search path's
for(int xx = 0; xx < x_tiles(); xx++)
for(int yy = 0; yy < y_tiles(); yy++)
if(xx != x || yy != y)
if(getField(xx, yy) == tile)
if(findPath(x, y, xx, yy)) {
for(int i = 0; i < 4; i++)
h[i] = history[i];
x1 = x;
x2 = xx;
y1 = y;
y2 = yy;
for(int i = 0; i < 4; i++)
history[i] = old[i];
return true;
}
clearHistory();
done[tile]++;
}
for(int i = 0; i < 4; i++)
history[i] = old[i];
return false;
}
kshisen'Board::setShuffle() (./kdegames/kshisen/board.cpp:939)
void Board::setShuffle(int newvalue) {
_shuffle = newvalue;
}
kshisen'Board::getShuffle() (./kdegames/kshisen/board.cpp:943)
int Board::getShuffle() {
return _shuffle;
}
kshisen'Board::tilesLeft() (./kdegames/kshisen/board.cpp:947)
int Board::tilesLeft() {
int left = 0;
for(int i = 0; i < x_tiles(); i++)
for(int j = 0; j < x_tiles(); j++)
if(getField(i, j) != EMPTY)
left++;
return left;
}
kshisen'Board::getCurrentTime() (./kdegames/kshisen/board.cpp:958)
int Board::getCurrentTime() {
return (int)difftime(time((time_t *)0),starttime);
}
kshisen'Board::getTimeForGame() (./kdegames/kshisen/board.cpp:962)
int Board::getTimeForGame() {
if(tilesLeft() == 0)
return time_for_game;
else
if(paused)
return (int)difftime(pause_start, starttime);
else
return (int)difftime(time((time_t *)0), starttime);
}
kshisen'Board::solvable() (./kdegames/kshisen/board.cpp:972)
bool Board::solvable(bool norestore) {
int x1, y1, x2, y2;
History h[4];
int *oldfield = 0;
if(!norestore) {
oldfield = new int [x_tiles() * y_tiles()];
memcpy(oldfield, field, x_tiles() * y_tiles() * sizeof(int));
}
while(getHint_I(x1, y1, x2, y2, h)) {
setField(x1, y1, EMPTY);
setField(x2, y2, EMPTY);
// if(gravityFlag()) {
// gravity(x1, false);
// gravity(x2, false);
// }
}
int left = tilesLeft();
if(!norestore) {
memcpy(field, oldfield, x_tiles() * y_tiles() * sizeof(int));
delete [] oldfield;
}
return (bool)(left == 0);
}
kshisen'Board::getSolvableFlag() (./kdegames/kshisen/board.cpp:1001)
bool Board::getSolvableFlag() {
return _solvable_flag;
}
kshisen'Board::setSolvableFlag() (./kdegames/kshisen/board.cpp:1005)
void Board::setSolvableFlag(bool value) {
_solvable_flag = value;
}
kshisen'Board::gravityFlag() (./kdegames/kshisen/board.cpp:1009)
bool Board::gravityFlag() {
return gravity_flag;
}
kshisen'Board::setGravityFlag() (./kdegames/kshisen/board.cpp:1013)
void Board::setGravityFlag(bool b) {
gravity_flag = b;
}
kshisen'Board::pause() (./kdegames/kshisen/board.cpp:1017)
bool Board::pause() {
paused = !paused;
if(paused)
pause_start = time((time_t *)0);
else
starttime += (time_t) difftime( time((time_t *)0), pause_start);
update();
return paused;
}