chainreaction/main.cpp

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;
}