-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.cpp
137 lines (114 loc) · 3.22 KB
/
Board.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "Board.h"
#include "MainWindow.h"
#include <QtGlobal>
//#include <QDebug>
#include <QGridLayout>
#include <QPoint>
#include <QPushButton>
#include <QTime>
#include <cstdlib> // for rand()
Board::Board(int cb, QWidget*) : cube(cb)
{
grid = new QGridLayout(this);
grid->setHorizontalSpacing(1);
grid->setVerticalSpacing(1);
grid->setContentsMargins(2, 2, 2, 2);
QTime midnight(0, 0, 0);
srand(midnight.secsTo(QTime::currentTime()));
bool oddBoard = (cube%2 == 1);
int n;
do
{
numbers.clear();
for(int i = 0; i < size(); i++)
{ // random numbers from
do n = rand() % size() + 1; // add 1, mod returns in range (0, size()-1)
while(numbers.contains(n));
numbers << n;
}
n = 0;
// check for which path-row is this random placement solvable
for(int i = 2; i <= size(); i++)
for(int j = 0; j < numbers.indexOf(i); j++)
{
if(numbers[j] < i)
{
++n;
}
}
// if this is oddBoard, we need "n" to be even
} while(oddBoard ? n%2 == 1 : false);
/* generate a random even or odd row position of the initial path, depending on "n"
if this is oddBoard, just skip the checks (it doesn't matter) */
do path.setY(rand() % cube);
while(oddBoard ? false : n%2 != path.y()%2);
path.setX(rand() % cube);
n = 0;
for(int y = 0; y < cube; ++y) // row
for(int x = 0; x < cube; ++x) // column
{
if(path.x() == x && path.y() == y)
continue;
createButton(NULL, numbers[n++], x, y);
}
setLayout(grid);
}
void Board::moveClicked()
{
int x, y, rs, cs;
QPushButton* clickedBtn = static_cast<QPushButton*>(sender());
grid->getItemPosition(grid->indexOf(clickedBtn), &y, &x, &rs, &cs);
if((path.x() == x && (path.y() == y+1 || path.y() == y-1))
|| (path.y() == y && (path.x() == x+1 || path.x() == x-1))) // valid button, move it
{
// remove the widget from the actual position
grid->removeWidget(clickedBtn);
// and re-add it to where the path has been
createButton(clickedBtn, 0, path.x(), path.y());
// and update the path coordinates
path = QPoint(x, y);
// also update the move count
static_cast<MainWindow*>(parentWidget())->updateMoves();
checkGameOver();
}
}
void Board::checkGameOver()
{
Q_ASSERT(grid->count() == numbers.size());
int i=1, n=0;
// check whether the buttons are placed upwardly from 1 to n
for(int y = 0; y < grid->rowCount(); ++y) // row
for(int x = 0; x < grid->columnCount(); ++x) // column
{
if(grid->itemAtPosition(y, x) == 0)
continue;
n = numbers.indexOf(i++);
if(buttons[n] != (QPushButton*)grid->itemAtPosition(y, x)->widget())
return;
}
// check whether the path is the last item in the grid
if(path.y() == grid->rowCount()-1 && path.x() == grid->columnCount()-1)
{ // game over:
// disable all the buttons
for(QList<QPushButton*>::const_iterator it = buttons.begin(); it != buttons.end(); ++it)
(*it)->setDisabled(true);
// stop the timer
static_cast<MainWindow*>(parentWidget())->stopTimer();
}
}
void Board::createButton(QPushButton* b, int no, int x, int y)
{
QPushButton* btn = b;
if(!btn)
{
btn = new QPushButton(QString("%1").arg(no));
buttons << btn;
connect(btn, SIGNAL(clicked()), this, SLOT(moveClicked()));
btn->setFixedSize(50, 50);
}
grid->addWidget(btn, y, x);
}
int Board::size() const
{
return cube*cube-1;
}