138 lines
4.0 KiB
C++
138 lines
4.0 KiB
C++
#include <iostream>
|
|
|
|
#include <SDL2/SDL_ttf.h>
|
|
|
|
#include <basic_widgets/core/font.hpp>
|
|
|
|
#include "game_screen.hpp"
|
|
#include "game.hpp"
|
|
|
|
using namespace bwidgets;
|
|
using namespace game;
|
|
|
|
int main()
|
|
{
|
|
int width = 640;
|
|
int height = 480;
|
|
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
SDL_Window* win = SDL_CreateWindow(
|
|
"ChainReact",
|
|
SDL_WINDOWPOS_UNDEFINED,
|
|
SDL_WINDOWPOS_UNDEFINED,
|
|
width,
|
|
height,
|
|
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
|
|
);
|
|
auto* rend = new core::Renderer(win, -1, SDL_RENDERER_ACCELERATED);
|
|
rend->blend_mode(SDL_BLENDMODE_BLEND);
|
|
|
|
SDL_Rect viewport {2, 2, width - 4, height - 4};
|
|
|
|
TTF_Init();
|
|
auto* font = new core::Font(core::Font::find("Monospace"), 20);
|
|
|
|
data::Board board(4, 3);
|
|
data::Board transition_board(board);
|
|
|
|
ui::GameScreen game_screen;
|
|
game_screen.board.board = &board;
|
|
game_screen.font(font);
|
|
game_screen.renderer(rend);
|
|
game_screen.viewport(viewport);
|
|
|
|
bool quit = false;
|
|
auto player = data::Player::P1;
|
|
auto round = 1;
|
|
game::data::Boards transitions;
|
|
auto transitions_timer = SDL_GetTicks();
|
|
size_t transitions_iterator = 0;
|
|
while (!quit)
|
|
{
|
|
SDL_Event ev;
|
|
while (SDL_PollEvent(&ev) != 0)
|
|
{
|
|
switch (ev.type)
|
|
{
|
|
case SDL_QUIT:
|
|
{
|
|
quit = true;
|
|
break;
|
|
}
|
|
case SDL_WINDOWEVENT:
|
|
{
|
|
if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
|
{
|
|
|
|
auto s = rend->output_size();
|
|
viewport.w = s.w - 4;
|
|
viewport.h = s.h - 4;
|
|
|
|
game_screen.viewport(viewport);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ev.type == game_screen.board.event_type)
|
|
{
|
|
switch ((ui::BoardWidget::event_code)ev.user.code)
|
|
{
|
|
case ui::BoardWidget::event_code::PLAY:
|
|
{
|
|
auto can_play = round <= 2 || (transitions.empty() &&
|
|
game::logic::winner(board) == game::data::Player::NONE);
|
|
if (!can_play)
|
|
break;
|
|
|
|
const auto coord = (SDL_Point*)ev.user.data2;
|
|
try
|
|
{
|
|
transitions = game::logic::play(board, {coord->x, coord->y}, player);
|
|
game_screen.cur_player = player = player == data::Player::P1 ? data::Player::P2 : data::Player::P1;
|
|
round++;
|
|
}
|
|
catch (const game::error::invalid_move&)
|
|
{
|
|
std::cerr << "invalid_move exception" << std::endl;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
game_screen.handle_event(ev);
|
|
|
|
}
|
|
|
|
rend->draw_color({0, 0, 0, SDL_ALPHA_OPAQUE})->clear();
|
|
|
|
|
|
if (transitions_iterator < transitions.size())
|
|
{
|
|
if (auto t = SDL_GetTicks(); t - transitions_timer > 750)
|
|
{
|
|
game_screen.board.board = &transitions[transitions_iterator];
|
|
transitions_iterator++;
|
|
transitions_timer = t;
|
|
}
|
|
}
|
|
else if (transitions_iterator > 0 && transitions_iterator == transitions.size())
|
|
{
|
|
game_screen.board.board = &board;
|
|
transitions_iterator = 0;
|
|
transitions.clear();
|
|
}
|
|
game_screen.render();
|
|
|
|
rend->present();
|
|
}
|
|
|
|
delete font;
|
|
delete rend;
|
|
TTF_Quit();
|
|
SDL_DestroyWindow(win);
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|