121 lines
2.3 KiB
C++
121 lines
2.3 KiB
C++
#include "global.hpp"
|
|
|
|
Block::Block(int _depth, Rectangle trg) {
|
|
place = trg;
|
|
int x = trg.x, y = trg.y, w = trg.width, h = trg.height;
|
|
depth = _depth;
|
|
if(depth > 0)
|
|
for(int i = 0; i < 9; i++)
|
|
sons[i] = new Block( depth-1, get_son_rectangle(i) );
|
|
}
|
|
Rectangle Block::get_son_rectangle(int son) {
|
|
return {
|
|
float(int(place.x + place.width/3 * (son%3))),
|
|
float(int(place.y + place.height/3 * int(son/3))),
|
|
float(int(place.width/3)),
|
|
float(int(place.height/3))
|
|
};
|
|
}
|
|
int Block::set(tile pl) {
|
|
t = pl;
|
|
if(pl == empty)
|
|
return OKAY;
|
|
return CHANGE;
|
|
}
|
|
bool Block::playable(deque<int> v) {
|
|
if(depth == 0 && t == empty)
|
|
return true;
|
|
if(t != empty || v.size() == 0)
|
|
return false;
|
|
int son = v.front();
|
|
v.pop_front();
|
|
return sons[son]->playable(v);
|
|
}
|
|
int Block::play(deque<int> v, tile pl) {
|
|
if(t != empty)
|
|
return v.size();
|
|
if(depth == 0)
|
|
return set(pl);
|
|
if(v.size() == 0)
|
|
return OKAY;
|
|
|
|
int son = v.front();
|
|
v.erase(v.begin());
|
|
int rv = sons[son]->play(v, pl);
|
|
|
|
if(rv == CHANGE)
|
|
return set(update());
|
|
return rv;
|
|
}
|
|
bool Block::check_tie() {
|
|
bool is_tie = true;
|
|
for(Block* s : sons)
|
|
if(s->t == empty)
|
|
is_tie = false;
|
|
return is_tie;
|
|
}
|
|
tile Block::update() {
|
|
tile d1 = sons[0]->t, d2 = sons[2]->t;
|
|
for(int k = 0; k < 3; k++) {
|
|
tile row = sons[k*3]->t, col = sons[k%3]->t;
|
|
for(int i = 0; i < 3; i++) {
|
|
if(sons[k*3 + i]->t != row)
|
|
row = empty;
|
|
if(sons[k%3 + i*3]->t != col)
|
|
col = empty;
|
|
}
|
|
if(row != empty)
|
|
return row;
|
|
if(col != empty)
|
|
return col;
|
|
if(sons[k*4]->t != sons[0]->t)
|
|
d1 = empty;
|
|
if(sons[(k+1)*2]->t != sons[2]->t)
|
|
d2 = empty;
|
|
}
|
|
if(d1 != empty)
|
|
return d1;
|
|
if(d2 != empty)
|
|
return d2;
|
|
|
|
if(check_tie())
|
|
return tie;
|
|
|
|
return empty;
|
|
}
|
|
Rectangle Block::getRect(deque<int> v) {
|
|
if(v.size() == 0)
|
|
return place;
|
|
else {
|
|
int index = v.front();
|
|
v.pop_front();
|
|
return sons[index]->getRect(v);
|
|
}
|
|
}
|
|
void Block::updateRect(Rectangle trg) {
|
|
place = trg;
|
|
if(depth == 0)
|
|
return;
|
|
for(int i = 0; i < 9; i++)
|
|
sons[i]->updateRect(get_son_rectangle(i));
|
|
}
|
|
|
|
void Block::save(vector<tile> *r) {
|
|
if(depth == 0)
|
|
r->push_back(t);
|
|
else
|
|
for(Block* son : sons)
|
|
son->save(r);
|
|
}
|
|
void Block::load_state(vector<tile> state, int pos) {
|
|
if(depth == 0)
|
|
t = state[pos];
|
|
else {
|
|
for(int i = 0; i < 9; i++)
|
|
sons[i]->load_state(state, pos*9+i);
|
|
t = update();
|
|
}
|
|
}
|
|
void Block::undo(deque<int> &prev) {
|
|
// TODO
|
|
}
|