105 lines
2 KiB
C++
105 lines
2 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_rect(i) );
|
|
}
|
|
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;
|
|
}
|
|
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;
|
|
|
|
// Check tie
|
|
bool is_tie;
|
|
for(Block* s : sons)
|
|
if(s->t == empty)
|
|
is_tie = false;
|
|
if(is_tie)
|
|
return tie;
|
|
|
|
return empty;
|
|
}
|
|
|
|
|
|
void Block::update_rect(Rectangle trg) {
|
|
place = trg;
|
|
if(depth == 0)
|
|
return;
|
|
for(int i = 0; i < 9; i++)
|
|
sons[i]->update_rect(get_son_rect(i));
|
|
}
|
|
|
|
Rectangle Block::get_rect(deque<int> v) {
|
|
if(v.size() == 0)
|
|
return place;
|
|
else {
|
|
int index = v.front();
|
|
v.pop_front();
|
|
return sons[index]->get_rect(v);
|
|
}
|
|
}
|
|
|
|
Rectangle Block::get_son_rect(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))
|
|
};
|
|
}
|