158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
#include "global.hpp"
|
|
|
|
|
|
tile act(int t) { return (t % 2) ? p2 : p1; }
|
|
tile pas(int t) { return (t % 2) ? p1 : p2; }
|
|
Color col(int t) { return act(t) == p2 ? BLUE : RED; }
|
|
|
|
|
|
deque<int> to_deque(Vector2 v, int depth, int size) {
|
|
deque<int> r = {};
|
|
int x = v.x, y = v.y;
|
|
|
|
if(x >= size || y >= size || x < 0 || y < 0)
|
|
return {};
|
|
|
|
for(int i = 0; i < depth; ++i) {
|
|
size /= 3;
|
|
r.push_back(3*(y/size) + x/size);
|
|
x %= size;
|
|
y %= size;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
|
|
void save_state(Block* root, int time, deque<int> &turn) {
|
|
vector<tile> state = {};
|
|
root->save(&state);
|
|
|
|
string filename; std::cin >> filename;
|
|
std::ofstream outfile("saves/" + filename);
|
|
|
|
outfile << root->depth << "\n" << time << "\n" << turn.size() << "\n";
|
|
|
|
// Save turns
|
|
for(int play : turn)
|
|
outfile << play << std::endl;
|
|
|
|
// Save game state
|
|
for(tile t : state)
|
|
outfile << int(t) << std::endl;
|
|
}
|
|
void load_state(Block** root, deque<int> &turn, int &time, char* argv) {
|
|
int depth = atoi(argv);
|
|
if(depth) {
|
|
*root = new Block(depth, {0, 0, SCREEN, SCREEN});
|
|
return;
|
|
}
|
|
|
|
// Load file
|
|
string path = "saves/" + string(argv);
|
|
std::ifstream infile(path);
|
|
infile >> depth >> time;
|
|
|
|
// Load turns
|
|
int K; infile >> K;
|
|
for(int k = 0; k < K; k++) {
|
|
int play; infile >> play;
|
|
turn.push_back(play);
|
|
cout << play;
|
|
}
|
|
|
|
// Load board
|
|
vector<tile> state = {};
|
|
|
|
long long pw = 1;
|
|
for(int i = 0; i < depth; i++)
|
|
pw *= 9;
|
|
|
|
for(int i = 0; i < pw; i++) {
|
|
int next; infile >> next;
|
|
state.push_back((tile)next);
|
|
}
|
|
|
|
*root = new Block(depth, {0, 0, SCREEN, SCREEN});
|
|
(*root)->load_state(state, 0);
|
|
}
|
|
|
|
void update(Block *root, int time, deque<int> &turn) {
|
|
time++;
|
|
turn.erase(turn.begin());
|
|
int rval_2 = root->play(turn, pas(time));
|
|
for(int i = 0; i <= rval_2; i++)
|
|
turn.pop_back();
|
|
}
|
|
void undo(Block *root, deque<int> &prev, int time) {
|
|
if(prev.size() == 0) return;
|
|
time--;
|
|
root->undo(prev);
|
|
// TODO
|
|
}
|
|
bool valid(Block *root, Rectangle play_area, deque<int> &turn) {
|
|
return CheckCollisionRecs(root->getRect(turn), play_area) && root->playable(turn);
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv) {
|
|
deque<int> turn = {};
|
|
int time = 0, depth;
|
|
Block* root = nullptr;
|
|
|
|
if(argc <= 1) {
|
|
cin >> depth;
|
|
root = new Block(depth, {0, 0, SCREEN, SCREEN});
|
|
}
|
|
else
|
|
load_state(&root, turn, time, argv[1]);
|
|
|
|
Rectangle play_area = root->getRect(turn);
|
|
|
|
Renderer renderer;
|
|
renderer.prepare_screen(root, time, play_area);
|
|
int board_size = renderer.update_board_size(depth);
|
|
|
|
bool end = false;
|
|
deque<int> pturn = {};
|
|
while(!WindowShouldClose()) {
|
|
// Update screen size
|
|
board_size = renderer.update_board_size(depth);
|
|
|
|
float start_x = ((float)GetScreenWidth()-board_size)/2;
|
|
float start_y = ((float)GetScreenHeight()-board_size)/2;
|
|
|
|
root->updateRect({start_x, start_y, (float)board_size, (float)board_size});
|
|
play_area = root->getRect(pturn);
|
|
|
|
// Move
|
|
Vector2 touch = GetMousePosition();
|
|
turn = to_deque({touch.x - start_x, touch.y - start_y}, depth, board_size);
|
|
if(IsMouseButtonPressed(0) && CheckCollisionPointRec(touch, play_area) && valid(root, play_area, turn)) {
|
|
switch(root->play(turn, act(time))) {
|
|
case CHANGE:
|
|
end = true;
|
|
break;
|
|
case OKAY:
|
|
update(root, time, turn);
|
|
pturn = turn;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Key presses
|
|
if(IsKeyPressed(KEY_X))
|
|
save_state(root, time, turn), end = true;
|
|
else if(IsKeyPressed(KEY_Z))
|
|
{} // TODO undo
|
|
|
|
// Rendering
|
|
renderer.render_all(root, time, play_area, turn);
|
|
|
|
if(end)
|
|
break;
|
|
}
|
|
|
|
WaitTime(10);
|
|
CloseWindow();
|
|
return 0;
|
|
}
|