Fix include guard position. Move contents of Grid.*pp to Gameplay.*pp to avoid a circular dependency.

This commit is contained in:
Tim Schubert 2016-01-24 13:56:38 +01:00
parent ac0d35e053
commit 100065e158
11 changed files with 536 additions and 528 deletions

View file

@ -21,13 +21,13 @@ void Game::handle_event(SDL_Event *event)
}
break;
case SDL_MOUSEMOTION:
grid->handle_event(event);
grid->handle_event(event, this->event_context);
break;
case SDL_MOUSEWHEEL:
grid->handle_event(event);
grid->handle_event(event, this->event_context);
break;
case SDL_MOUSEBUTTONDOWN:
grid->handle_event(event);
grid->handle_event(event, this->event_context);
break;
case SDL_KEYDOWN:
switch (event->key.keysym.sym)
@ -73,6 +73,14 @@ void Game::handle_event(SDL_Event *event)
break;
}
break;
case SDL_USEREVENT:
switch (event->type - this->event_context->base_event)
{
case BOB_NEXTTURNEVENT:
this->grid->handle_event(event, this->event_context);
default:
break;
}
default:
break;
}
@ -86,15 +94,15 @@ int Game::game_loop()
Uint32 frame_counter = 0;
while (!this->quit)
{
if (move_timer->get_timer() > 16)
if (this->move_timer->get_timer() > 16)
{
move_timer->reset_timer();
this->move_timer->reset_timer();
SDL_Point move_by = {(this->move[1] - this->move[3]) * 20, (this->move[0] - this->move[2]) * 20};
this->grid->move(move_by);
}
if (frame_timer->get_timer() > 255)
if (this->frame_timer->get_timer() > 255)
{
fps = frame_counter / (frame_timer->reset_timer() / 1000.0);
fps = frame_counter / (this->frame_timer->reset_timer() / 1000.0);
frame_counter = 0;
this->test_box->load_text(std::to_string(fps));
}

View file

@ -1,3 +1,6 @@
#ifndef _BOB_H
#define _BOB_H
#include <iostream>
#include <string>
#include <utility>
@ -9,9 +12,6 @@
#include "Events.hpp"
#include "Gui.hpp"
#ifndef _BOB_H
#define _BOB_H
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGTH = 600;
const int SIDEBAR_WIDTH = 200;
@ -23,7 +23,7 @@ class Game
public:
Game(SDL_Rect *window_dimensions, Sint16 size)
{
this->event_context = new EventContext(4);
this->event_context = new EventContext();
this->layout = new Layout(pointy_orientation, size,
{window_dimensions->w / 2, window_dimensions->h / 2},
{0, 0, window_dimensions->w - SIDEBAR_WIDTH, window_dimensions->h});

View file

@ -1,2 +1,2 @@
add_executable(Bob Bob.cpp Bob.hpp Grid.cpp Grid.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp)
add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp)
target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES})

View file

@ -21,9 +21,4 @@ Uint32 Timer::reset_timer()
Uint32 EventContext::register_events(Uint32 num_events)
{
return SDL_RegisterEvents(num_events);
}
Uint32 EventContext::get_event(Bob_Event event)
{
return this->base_event + event;
}

View file

@ -1,27 +1,26 @@
#include <SDL2/SDL.h>
#include <boost/uuid/uuid.hpp>
#include "Grid.hpp"
#include "Gameplay.hpp"
#ifndef _EVENTS_H
#define _EVENTS_H
#include <SDL2/SDL.h>
#include <boost/uuid/uuid.hpp>
enum Bob_Event
{
BOB_NEXTTURNEVENT,
BOB_FIELDUPDATEEVENT
};
class EventContext
{
public:
enum Bob_Event
{
Bob_NextTurnEvent,
Bob_FieldUpdateEvent
};
EventContext(Uint32 num_events)
EventContext()
: base_event(register_events(num_events)) { }
Uint32 get_event(Bob_Event event);
const Uint32 base_event;
private:
const Uint32 base_event;
static const int num_events = 2;
static Uint32 register_events(Uint32 n);
};
@ -46,7 +45,9 @@ struct NextTurn
struct FieldUpdate
{
FieldMeta *field;
Sint16 x;
Sint16 y;
Sint16 z;
};
#endif

View file

@ -1,9 +1,9 @@
#include <stdexcept>
#include <SDL2/SDL_ttf.h>
#ifndef BOB_EXCEPTIONS_H
#define BOB_EXCEPTIONS_H
#include <stdexcept>
#include <SDL2/SDL_ttf.h>
class SDL_Exception : public std::runtime_error
{
public:

View file

@ -1,5 +1,129 @@
#include "Gameplay.hpp"
SDL_Point operator+(SDL_Point left, SDL_Point right)
{
return {left.x + right.x, left.y + right.y};
}
SDL_Point operator-(SDL_Point left, SDL_Point right)
{
return {left.x - right.x, left.y - right.y};
}
SDL_Point operator*(SDL_Point left, SDL_Point right)
{
return {left.x * right.x, left.y * right.y};
}
SDL_Point operator/(SDL_Point left, SDL_Point right)
{
return {(left.x / right.x), (left.x / right.y)};
}
SDL_Point operator*(double left, SDL_Point right)
{
int x = (int) (left * right.x);
int y = (int) (left * right.y);
return {x, y};
}
SDL_Point operator*(SDL_Point left, double right)
{
return right * left;
}
SDL_Point operator/(SDL_Point left, double right)
{
return (1 / right) * left;
}
double operator!(SDL_Point left)
{
double length = std::sqrt(left.x * left.x + left.y * left.y);
return length;
}
Field Field::cubic_round(double x, double y, double z)
{
Sint8 round_x = (Sint8) std::round(x);
Sint8 round_y = (Sint8) std::round(y);
Sint8 round_z = (Sint8) std::round(z);
double x_err = std::abs(round_x - x);
double y_err = std::abs(round_y - y);
double z_err = std::abs(round_z - z);
if (x_err > y_err && x_err > z_err)
{
round_x = -round_y - round_z;
} else if (y_err > z_err)
{
round_y = -round_x - round_z;
} else
{
round_z = -round_x - round_y;
}
return Field(round_x, round_y, round_z);
}
Field Field::hex_direction(Uint8 direction)
{
assert (0 <= direction && direction <= 5);
return hex_directions[direction];
}
Field Field::get_neighbor(Uint8 direction) const
{
return hex_direction(direction) + *this;
}
Point Field::field_to_point(const Layout *layout) const
{
const Orientation m = layout->orientation;
double x = (m.f0 * this->x + m.f1 * this->y) * layout->size;
double y = (m.f2 * this->x + m.f3 * this->y) * layout->size;
return {x + layout->origin.x, y + layout->origin.y};
}
Field Point::point_to_field(const Layout *layout) const
{
const Orientation m = layout->orientation;
double rel_x = (this->x - layout->origin.x) / layout->size;
double rel_y = (this->y - layout->origin.y) / layout->size;
double x = m.b0 * rel_x + m.b1 * rel_y;
double y = m.b2 * rel_x + m.b3 * rel_y;
return Field::cubic_round(x, y, -x - y);
}
Point field_corner_offset(Uint8 corner, const Layout *layout)
{
double angle = 2.0 * M_PI * (corner + layout->orientation.start_angle) / 6;
double x = (layout->size * cos(angle));
double y = (layout->size * sin(angle));
return {x, y};
}
std::vector<Point> Field::field_to_polygon(const Layout *layout) const
{
std::vector<Point> corners = this->field_to_polygon_normalized(layout);
Point center = this->field_to_point(layout);
for (Point &p : corners)
{
p = p + center;
}
return corners;
}
std::vector<Point> Field::field_to_polygon_normalized(const Layout *layout) const
{
std::vector<Point> corners;
for (uint8_t i = 0; i < 6; i++)
{
Point offset = field_corner_offset(i, layout);
corners.push_back(offset);
}
return corners;
}
void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
{
Point precise_location = this->field.field_to_point(layout);
@ -23,37 +147,34 @@ void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
inverse.g = (Uint8) (0xff - color.g);
inverse.b = (Uint8) (0xff - color.b);
inverse.a = 0xff;
Uint16 resource_size = (Uint16) (layout->size / 3);
if (this->resources_base.circle > 0)
{
circleRGBA(renderer, (Sint16) (location.x), (Sint16) (location.y), (Sint16) (resource_size), inverse.r,
inverse.g, inverse.b, inverse.a);
}
double resource_size = layout->size / 4;
if (this->resources_base.triangle > 0)
{
static const SDL_Point trigon[] = {{-1, 1},
{1, 1},
{0, -1}};
static const SDL_Point trigon[] = {{0, -1},
{-1, 1},
{1, 1}};
for (int i = 0; i < 3; i++)
{
vx[i] = (Sint16) (location.x + (trigon[i].x) * resource_size);
vy[i] = (Sint16) (location.y + (trigon[i].y) * resource_size);
vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size));
vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size));
}
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], inverse.r, inverse.g, inverse.b, inverse.a);
}
if (this->resources_base.circle > 0)
{
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, inverse.r, inverse.g,
inverse.b, inverse.a);
}
if (this->resources_base.square > 0)
{
static const SDL_Point square[] = {{-1, -1},
{-1, 1},
{1, 1},
{1, -1}};
for (int i = 0; i < 4; i++)
{
vx[i] = (Sint16) (location.x + (square[i].x) * resource_size);
vy[i] = (Sint16) (location.y + (square[i].y) * resource_size);
vx[i] = (Sint16) (location.x + square[i].x * resource_size);
vy[i] = (Sint16) (location.y + square[i].y * resource_size);
}
polygonRGBA(renderer, vx, vy, 4, inverse.r, inverse.g, inverse.b, inverse.a);
}
@ -190,9 +311,16 @@ bool Player::fight(FieldMeta *field)
return false;
}
void FieldMeta::handle_event(const SDL_Event *event)
void FieldMeta::handle_event(const SDL_Event *event, EventContext *context)
{
this->regenerate_resources();
switch (event->type - context->base_event)
{
case BOB_FIELDUPDATEEVENT:
this->regenerate_resources();
break;
default:
break;
}
}
bool HexagonGrid::render(SDL_Renderer *renderer)
@ -222,15 +350,16 @@ bool HexagonGrid::render(SDL_Renderer *renderer)
return true;
}
void Grid::handle_event(SDL_Event *event)
void Grid::handle_event(SDL_Event *event, EventContext *context)
{
if (event->type == SDL_MOUSEWHEEL)
SDL_Point mouse = {0, 0};
SDL_GetMouseState(&mouse.x, &mouse.y);
int scroll = this->layout->size / 10 * event->wheel.y;
double old_size = this->layout->size;
SDL_Point old_origin = this->layout->origin;
switch (event->type)
{
SDL_Point mouse = {0, 0};
SDL_GetMouseState(&mouse.x, &mouse.y);
int scroll = this->layout->size / 10 * event->wheel.y;
double old_size = this->layout->size;
SDL_Point old_origin = this->layout->origin;
case SDL_MOUSEWHEEL:
if (old_size + scroll < 10)
{
this->layout->size = 10;
@ -244,9 +373,8 @@ void Grid::handle_event(SDL_Event *event)
this->layout->size += scroll;
}
this->move(((1.0 - (double) this->layout->size / old_size) * (mouse - old_origin)));
}
if (event->type == SDL_MOUSEMOTION)
{
break;
case SDL_MOUSEMOTION:
if (this->panning)
{
SDL_Point mouse = {0, 0};
@ -258,10 +386,19 @@ void Grid::handle_event(SDL_Event *event)
this->move(mouse - p);
}
this->update_marker();
}
if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_MIDDLE)
{
this->panning = !(this->panning);
break;
case SDL_MOUSEBUTTONDOWN:
switch (event->button.button)
{
case SDL_BUTTON_MIDDLE:
this->panning = !(this->panning);
break;
default:
break;
}
break;
default:
break;
}
}

View file

@ -1,22 +1,339 @@
#ifndef _GAMEPLAY_H
#define _GAMEPLAY_H
#include <random>
#include <iostream>
#include <sstream>
#include <string>
#include <iostream>
#include <stdexcept>
#include <cmath>
#include <vector>
#include <assert.h>
#include <bitset>
#include <unordered_set>
#include <unordered_map>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <SDL2/SDL.h>
#include <SDL2/SDL_pixels.h>
#include <SDL2/SDL_render.h>
#include <bitset>
#include "Grid.hpp"
#include <stdexcept>
#ifndef _GAMEPLAY_H
#define _GAMEPLAY_H
#include <SDL2/SDL2_gfxPrimitives.h>
#include "Events.hpp"
#define NUM_UPGRADES 10
SDL_Point operator+(SDL_Point left, SDL_Point right);
SDL_Point operator-(SDL_Point left, SDL_Point right);
SDL_Point operator*(SDL_Point left, SDL_Point right);
SDL_Point operator/(SDL_Point left, SDL_Point right);
SDL_Point operator/(SDL_Point left, SDL_Point right);
SDL_Point operator*(double left, SDL_Point right);
SDL_Point operator*(SDL_Point left, double right);
SDL_Point operator/(SDL_Point left, double right);
double operator!(SDL_Point left);
struct Orientation
{
// cubic to point
const double f0, f1, f2, f3;
// point to cubic
const double b0, b1, b2, b3;
// in multiples of 60 deg
const double start_angle;
Orientation(double f0_, double f1_, double f2_, double f3_, double b0_, double b1_, double b2_, double b3_,
double start_angle_)
: f0(f0_), f1(f1_), f2(f2_), f3(f3_), b0(b0_), b1(b1_), b2(b2_), b3(b3_),
start_angle(start_angle_) { }
};
const Orientation pointy_orientation = Orientation(sqrt(3.0), sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, sqrt(3.0) / 3.0,
-1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5);
const Orientation flat_orientation = Orientation(3.0 / 2.0, 0.0, sqrt(3.0) / 2.0, sqrt(3.0), 2.0 / 3.0, 0.0, -1.0 / 3.0,
sqrt(3.0) / 3.0, 0);
struct Layout
{
const Orientation orientation;
Sint16 size;
SDL_Point origin;
SDL_Rect box;
Layout(Orientation orientation_, Sint16 size_, SDL_Point origin_, SDL_Rect box_)
: orientation(orientation_), size(size_), origin(origin_), box(box_) { }
};
struct Field;
struct Point
{
double x;
double y;
Point(double x_, double y_) : x(x_), y(y_) { }
bool operator==(const Point &rhs) const
{
return (this->x == rhs.x && this->y == rhs.y);
}
inline bool operator!=(const Point &rhs) const
{
return !(*this == rhs);
}
Point &operator+=(const Point &rhs)
{
this->x += rhs.x;
this->y += rhs.y;
return *this;
}
friend Point operator+(Point lhs, const Point &rhs)
{
lhs += rhs;
return lhs;
}
Point &operator-=(const Point &rhs)
{
this->x -= rhs.x;
this->y -= rhs.y;
return *this;
}
friend Point operator-(Point lhs, const Point &rhs)
{
lhs -= rhs;
return rhs;
}
Point &operator*=(const Point &rhs)
{
this->x *= rhs.x;
this->y *= rhs.y;
return *this;
}
friend Point operator*(Point lhs, const Point &rhs)
{
lhs *= rhs;
return rhs;
}
Point &operator/=(const Point &rhs)
{
this->x /= rhs.x;
this->y /= rhs.y;
return *this;
}
friend Point operator/(Point lhs, const Point &rhs)
{
lhs /= rhs;
return lhs;
}
Point &operator*=(const double &rhs)
{
this->x *= rhs;
this->y *= rhs;
return *this;
}
friend Point operator*(Point lhs, const double &rhs)
{
lhs *= rhs;
return lhs;
}
Point &operator/=(const double &rhs)
{
this->x /= rhs;
this->y /= rhs;
return *this;
}
friend Point operator/(Point lhs, const double &rhs)
{
lhs /= rhs;
return lhs;
}
double operator!()
{
return std::sqrt(this->x * this->x + this->y * this->y);
}
Field point_to_field(const Layout *layout) const;
};
struct Field
{
Sint16 x, y, z;
Field(Sint16 x_, Sint16 y_, Sint16 z_) : x(x_), y(y_), z(z_)
{
assert(x + y + z == 0);
}
bool operator==(const Field &rhs) const
{
return (this->x == rhs.x && this->y == rhs.y);
}
inline bool operator!=(const Field &rhs) const
{
return !(*this == rhs);
}
Field &operator+=(const Field &rhs)
{
this->x += rhs.x;
this->y += rhs.y;
this->z += rhs.z;
return *this;
}
friend Field operator+(Field lhs, const Field &rhs)
{
lhs += rhs;
return lhs;
}
Field &operator-=(const Field &rhs)
{
this->x -= rhs.x;
this->y -= rhs.y;
this->z -= rhs.z;
return *this;
}
friend Field operator-(Field lhs, const Field &rhs)
{
lhs -= rhs;
return rhs;
}
Field &operator*=(const Field &rhs)
{
this->x *= rhs.x;
this->y *= rhs.y;
this->z *= rhs.z;
return *this;
}
friend Field operator*(Field lhs, const Field &rhs)
{
lhs *= rhs;
return rhs;
}
Field &operator/=(const Field &rhs)
{
double x = this->x / rhs.x;
double y = this->y / rhs.y;
double z = this->z / rhs.z;
Field f = cubic_round(x, y, z);
*this = f;
return *this;
}
friend Field operator/(Field lhs, const Field &rhs)
{
lhs /= rhs;
return lhs;
}
Field &operator*=(const double &rhs)
{
double x = this->x * rhs;
double y = this->y * rhs;
double z = this->z * rhs;
Field f = cubic_round(x, y, z);
*this = f;
return *this;
}
friend Field operator*(Field lhs, const double &rhs)
{
lhs *= rhs;
return lhs;
}
Field &operator/=(const double &rhs)
{
double x = this->x / rhs;
double y = this->y / rhs;
double z = this->z / rhs;
Field f = cubic_round(x, y, z);
*this = f;
return *this;
}
friend Field operator/(Field lhs, const double &rhs)
{
lhs /= rhs;
return lhs;
}
int operator&(const Field &rhs)
{
return (abs(this->x - rhs.x) + abs(this->y - rhs.y) + abs(this->z - rhs.z)) / 2;
}
Field get_neighbor(Uint8 direction) const;
Point field_to_point(const Layout *layout) const;
std::vector<Point> field_to_polygon_normalized(const Layout *layout) const;
std::vector<Point> field_to_polygon(const Layout *layout) const;
static Field cubic_round(double x, double y, double z);
static Field hex_direction(Uint8 direction);
};
// from upper right corner
const std::vector<Field> hex_directions = {Field(1, 0, -1), Field(0, 1, -1), Field(-1, 1, 0), Field(-1, 0, 1),
Field(-1, 1, 0)};
Point field_corner_offset(Uint8 corner, const Layout *layout);
namespace std
{
template<>
struct hash<Field>
{
size_t operator()(const Field &f) const
{
hash<Sint16> int_hash;
size_t hx = int_hash(f.x);
size_t hy = int_hash(f.y);
// hz would be redundant, since f.z is redundant
// combine hashes
return hx ^ (hy + 0x9e3779b9 + (hx << 6) + (hx >> 2));
}
};
}
inline std::ostream &operator<<(std::ostream &os, const Field &rhs)
{
os << "(" << rhs.x << "," << rhs.y << ",";
return os;
}
typedef std::bitset<NUM_UPGRADES> UpgradeFlags;
struct Resource
@ -242,7 +559,7 @@ public:
bool upgrade(Upgrade upgrade);
void handle_event(const SDL_Event *event);
void handle_event(const SDL_Event *event, EventContext *context);
FieldMeta *get_neighbor(Uint8 direction);
@ -287,7 +604,7 @@ public:
virtual bool render(SDL_Renderer *renderer) { return false; };
void handle_event(SDL_Event *event);
void handle_event(SDL_Event *event, EventContext *context);
void update_box(SDL_Point dimensions);

View file

@ -1,125 +0,0 @@
#include "Grid.hpp"
SDL_Point operator+(SDL_Point left, SDL_Point right)
{
return {left.x + right.x, left.y + right.y};
}
SDL_Point operator-(SDL_Point left, SDL_Point right)
{
return {left.x - right.x, left.y - right.y};
}
SDL_Point operator*(SDL_Point left, SDL_Point right)
{
return {left.x * right.x, left.y * right.y};
}
SDL_Point operator/(SDL_Point left, SDL_Point right)
{
return {(left.x / right.x), (left.x / right.y)};
}
SDL_Point operator*(double left, SDL_Point right)
{
int x = (int) (left * right.x);
int y = (int) (left * right.y);
return {x, y};
}
SDL_Point operator*(SDL_Point left, double right)
{
return right * left;
}
SDL_Point operator/(SDL_Point left, double right)
{
return (1 / right) * left;
}
double operator!(SDL_Point left)
{
double length = std::sqrt(left.x * left.x + left.y * left.y);
return length;
}
Field Field::cubic_round(double x, double y, double z)
{
Sint8 round_x = (Sint8) std::round(x);
Sint8 round_y = (Sint8) std::round(y);
Sint8 round_z = (Sint8) std::round(z);
double x_err = std::abs(round_x - x);
double y_err = std::abs(round_y - y);
double z_err = std::abs(round_z - z);
if (x_err > y_err && x_err > z_err)
{
round_x = -round_y - round_z;
} else if (y_err > z_err)
{
round_y = -round_x - round_z;
} else
{
round_z = -round_x - round_y;
}
return Field(round_x, round_y, round_z);
}
Field Field::hex_direction(Uint8 direction)
{
assert (0 <= direction && direction <= 5);
return hex_directions[direction];
}
Field Field::get_neighbor(Uint8 direction) const
{
return hex_direction(direction) + *this;
}
Point Field::field_to_point(const Layout *layout) const
{
const Orientation m = layout->orientation;
double x = (m.f0 * this->x + m.f1 * this->y) * layout->size;
double y = (m.f2 * this->x + m.f3 * this->y) * layout->size;
return {x + layout->origin.x, y + layout->origin.y};
}
Field Point::point_to_field(const Layout *layout) const
{
const Orientation m = layout->orientation;
double rel_x = (this->x - layout->origin.x) / layout->size;
double rel_y = (this->y - layout->origin.y) / layout->size;
double x = m.b0 * rel_x + m.b1 * rel_y;
double y = m.b2 * rel_x + m.b3 * rel_y;
return Field::cubic_round(x, y, -x - y);
}
Point field_corner_offset(Uint8 corner, const Layout *layout)
{
double angle = 2.0 * M_PI * (corner + layout->orientation.start_angle) / 6;
double x = (layout->size * cos(angle));
double y = (layout->size * sin(angle));
return {x, y};
}
std::vector<Point> Field::field_to_polygon(const Layout *layout) const
{
std::vector<Point> corners = this->field_to_polygon_normalized(layout);
Point center = this->field_to_point(layout);
for (Point &p : corners)
{
p = p + center;
}
return corners;
}
std::vector<Point> Field::field_to_polygon_normalized(const Layout *layout) const
{
std::vector<Point> corners;
for (uint8_t i = 0; i < 6; i++)
{
Point offset = field_corner_offset(i, layout);
corners.push_back(offset);
}
return corners;
}

View file

@ -1,325 +0,0 @@
#include <iostream>
#include <stdexcept>
#include <SDL2/SDL.h>
#include <SDL2/SDL2_gfxPrimitives.h>
#include <cmath>
#include <vector>
#include <assert.h>
#include <unordered_set>
#ifndef _GRID_H
#define _GRID_H
SDL_Point operator+(SDL_Point left, SDL_Point right);
SDL_Point operator-(SDL_Point left, SDL_Point right);
SDL_Point operator*(SDL_Point left, SDL_Point right);
SDL_Point operator/(SDL_Point left, SDL_Point right);
SDL_Point operator/(SDL_Point left, SDL_Point right);
SDL_Point operator*(double left, SDL_Point right);
SDL_Point operator*(SDL_Point left, double right);
SDL_Point operator/(SDL_Point left, double right);
double operator!(SDL_Point left);
struct Orientation
{
// cubic to point
const double f0, f1, f2, f3;
// point to cubic
const double b0, b1, b2, b3;
// in multiples of 60 deg
const double start_angle;
Orientation(double f0_, double f1_, double f2_, double f3_, double b0_, double b1_, double b2_, double b3_,
double start_angle_)
: f0(f0_), f1(f1_), f2(f2_), f3(f3_), b0(b0_), b1(b1_), b2(b2_), b3(b3_),
start_angle(start_angle_)
{ }
};
const Orientation pointy_orientation = Orientation(sqrt(3.0), sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, sqrt(3.0) / 3.0,
-1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5);
const Orientation flat_orientation = Orientation(3.0 / 2.0, 0.0, sqrt(3.0) / 2.0, sqrt(3.0), 2.0 / 3.0, 0.0, -1.0 / 3.0,
sqrt(3.0) / 3.0, 0);
struct Layout
{
const Orientation orientation;
Sint16 size;
SDL_Point origin;
SDL_Rect box;
Layout(Orientation orientation_, Sint16 size_, SDL_Point origin_, SDL_Rect box_)
: orientation(orientation_), size(size_), origin(origin_), box(box_)
{ }
};
struct Field;
struct Point
{
double x;
double y;
Point(double x_, double y_) : x(x_), y(y_) { }
bool operator==(const Point &rhs) const
{
return (this->x == rhs.x && this->y == rhs.y);
}
inline bool operator!=(const Point &rhs) const
{
return !(*this == rhs);
}
Point &operator+=(const Point &rhs)
{
this->x += rhs.x;
this->y += rhs.y;
return *this;
}
friend Point operator+(Point lhs, const Point &rhs)
{
lhs += rhs;
return lhs;
}
Point &operator-=(const Point &rhs)
{
this->x -= rhs.x;
this->y -= rhs.y;
return *this;
}
friend Point operator-(Point lhs, const Point &rhs)
{
lhs -= rhs;
return rhs;
}
Point &operator*=(const Point &rhs)
{
this->x *= rhs.x;
this->y *= rhs.y;
return *this;
}
friend Point operator*(Point lhs, const Point &rhs)
{
lhs *= rhs;
return rhs;
}
Point &operator/=(const Point &rhs)
{
this->x /= rhs.x;
this->y /= rhs.y;
return *this;
}
friend Point operator/(Point lhs, const Point &rhs)
{
lhs /= rhs;
return lhs;
}
Point &operator*=(const double &rhs)
{
this->x *= rhs;
this->y *= rhs;
return *this;
}
friend Point operator*(Point lhs, const double &rhs)
{
lhs *= rhs;
return lhs;
}
Point &operator/=(const double &rhs)
{
this->x /= rhs;
this->y /= rhs;
return *this;
}
friend Point operator/(Point lhs, const double &rhs)
{
lhs /= rhs;
return lhs;
}
double operator!()
{
return std::sqrt(this->x * this->x + this->y * this->y);
}
Field point_to_field(const Layout *layout) const;
};
struct Field
{
Sint16 x, y, z;
Field(Sint16 x_, Sint16 y_, Sint16 z_) : x(x_), y(y_), z(z_)
{
assert(x + y + z == 0);
}
bool operator==(const Field &rhs) const
{
return (this->x == rhs.x && this->y == rhs.y);
}
inline bool operator!=(const Field &rhs) const
{
return !(*this == rhs);
}
Field &operator+=(const Field &rhs)
{
this->x += rhs.x;
this->y += rhs.y;
this->z += rhs.z;
return *this;
}
friend Field operator+(Field lhs, const Field &rhs)
{
lhs += rhs;
return lhs;
}
Field &operator-=(const Field &rhs)
{
this->x -= rhs.x;
this->y -= rhs.y;
this->z -= rhs.z;
return *this;
}
friend Field operator-(Field lhs, const Field &rhs)
{
lhs -= rhs;
return rhs;
}
Field &operator*=(const Field &rhs)
{
this->x *= rhs.x;
this->y *= rhs.y;
this->z *= rhs.z;
return *this;
}
friend Field operator*(Field lhs, const Field &rhs)
{
lhs *= rhs;
return rhs;
}
Field &operator/=(const Field &rhs)
{
double x = this->x / rhs.x;
double y = this->y / rhs.y;
double z = this->z / rhs.z;
Field f = cubic_round(x, y, z);
*this = f;
return *this;
}
friend Field operator/(Field lhs, const Field &rhs)
{
lhs /= rhs;
return lhs;
}
Field &operator*=(const double &rhs)
{
double x = this->x * rhs;
double y = this->y * rhs;
double z = this->z * rhs;
Field f = cubic_round(x, y, z);
*this = f;
return *this;
}
friend Field operator*(Field lhs, const double &rhs)
{
lhs *= rhs;
return lhs;
}
Field &operator/=(const double &rhs)
{
double x = this->x / rhs;
double y = this->y / rhs;
double z = this->z / rhs;
Field f = cubic_round(x, y, z);
*this = f;
return *this;
}
friend Field operator/(Field lhs, const double &rhs)
{
lhs /= rhs;
return lhs;
}
int operator&(const Field &rhs)
{
return (abs(this->x - rhs.x) + abs(this->y - rhs.y) + abs(this->z - rhs.z)) / 2;
}
Field get_neighbor(Uint8 direction) const;
Point field_to_point(const Layout *layout) const;
std::vector<Point> field_to_polygon_normalized(const Layout *layout) const;
std::vector<Point> field_to_polygon(const Layout *layout) const;
static Field cubic_round(double x, double y, double z);
static Field hex_direction(Uint8 direction);
};
// from upper right corner
const std::vector<Field> hex_directions = {Field(1, 0, -1), Field(0, 1, -1), Field(-1, 1, 0), Field(-1, 0, 1),
Field(-1, 1, 0)};
Point field_corner_offset(Uint8 corner, const Layout *layout);
namespace std
{
template<>
struct hash<Field>
{
size_t operator()(const Field &f) const
{
hash<Sint16> int_hash;
size_t hx = int_hash(f.x);
size_t hy = int_hash(f.y);
// hz would be redundant, since f.z is redundant
// combine hashes
return hx ^ (hy + 0x9e3779b9 + (hx << 6) + (hx >> 2));
}
};
}
inline std::ostream &operator<<(std::ostream &os, const Field &rhs)
{
os << "(" << rhs.x << "," << rhs.y << ",";
return os;
}
#endif

View file

@ -1,3 +1,6 @@
#ifndef _GUI_H
#define _GUI_H
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
#include <stdio.h>
@ -10,9 +13,6 @@
#include "Gameplay.hpp"
#include "Events.hpp"
#ifndef _GUI_H
#define _GUI_H
SDL_Color operator!(const SDL_Color &color);
class Window