Skip to content

Commit b833033

Browse files
committed
Merge pull request #13 from Databean/renderCornerPieces
Added buttons for finer grained control of road and settlement placement.
2 parents d6429b2 + d81294e commit b833033

File tree

6 files changed

+172
-51
lines changed

6 files changed

+172
-51
lines changed

include/GameController.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
#ifndef GAME_CONTROLLER_H
22
#define GAME_CONTROLLER_H
33

4+
#include "Util.h"
5+
46
class GameBoard;
57
class ClickCoordinateEvent;
8+
class GameView;
69

710
class GameController {
811
private:
912
GameBoard& model;
13+
GameView& view;
14+
15+
bool placingRoads;
16+
bool placingCities;
17+
Coordinate lastCoordClick;
1018

11-
GameController(const GameController& o) : model(o.model) {} //deleted
19+
GameController(const GameController& o) : model(o.model), view(o.view) {} //deleted
1220
GameController& operator=(const GameController& o) { return *this; } //deleted
1321
public:
14-
GameController(GameBoard&);
22+
GameController(GameBoard&, GameView& view);
1523
~GameController();
1624

17-
void handleEvent(const ClickCoordinateEvent&);
25+
bool handleBoardEvent(ScreenCoordinate);
26+
bool handleRoadButtonEvent(ScreenCoordinate);
27+
bool handleSettlementButtonEvent(ScreenCoordinate);
1828
};
1929

2030
#endif

include/GameView.h

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,55 @@
11
#ifndef GAME_VIEW_H
22
#define GAME_VIEW_H
33

4+
#include <vector>
5+
#include <memory>
6+
47
#include "SDL2/SDL.h"
8+
#include "SDL2/SDL_opengl.h"
9+
#include "GL/gl.h"
510

611
#include "GameVisitor.h"
712
#include "Util.h"
813

914
class GameBoard;
1015
class GameController;
16+
class ViewElement;
17+
class GameView;
18+
19+
class ViewElement {
20+
private:
21+
std::pair<ScreenCoordinate, ScreenCoordinate> rect;
22+
23+
ViewElement(const ViewElement& vw) {} //deleted
24+
ViewElement& operator=(const ViewElement&) { return *this; } // deleted
25+
protected:
26+
virtual bool clicked(ScreenCoordinate coord) = 0;
27+
public:
28+
ViewElement(decltype(rect) rect);
29+
virtual ~ViewElement();
30+
31+
virtual decltype(rect) getRect() const;
32+
virtual bool containsPoint(ScreenCoordinate coord) const;
33+
virtual bool handleClick(ScreenCoordinate coord);
34+
virtual void render() = 0;
35+
};
1136

1237
class GameView {
1338
private:
1439
GameBoard& model;
15-
GameController& controller;
1640

17-
GameView(const GameView& o) : model(o.model), controller(o.controller) {} //deleted
41+
std::vector<std::unique_ptr<ViewElement>> viewElements;
42+
43+
GameView(const GameView& o) : model(o.model) {} //deleted
1844
GameView& operator=(const GameView& o) { return *this; } //deleted
1945
public:
20-
GameView(GameBoard&, GameController&);
46+
GameView(GameBoard&);
2147
~GameView();
2248

2349
void render();
2450
bool acceptInput(SDL_Event& event);
51+
52+
void addElement(std::unique_ptr<ViewElement>);
2553
};
2654

2755
class DrawingGameVisitor : public GameVisitor {
@@ -43,16 +71,57 @@ class DrawingGameVisitor : public GameVisitor {
4371
virtual void visit(DevelopmentCard&);
4472
};
4573

46-
class ClickCoordinateEvent {
74+
template<class Fn>
75+
class ViewButton : public ViewElement {
4776
private:
48-
Coordinate clicked;
77+
Fn action;
78+
79+
ViewButton(const ViewButton& vb) : ViewElement(vb) {} //deleted
80+
ViewButton& operator=(const ViewButton&) { return *this; } //deleted
81+
protected:
82+
virtual bool clicked(ScreenCoordinate coord) {
83+
return action(coord);
84+
}
4985
public:
50-
ClickCoordinateEvent(const Coordinate& clicked);
51-
ClickCoordinateEvent(const ClickCoordinateEvent&);
52-
~ClickCoordinateEvent();
53-
ClickCoordinateEvent& operator=(const ClickCoordinateEvent&);
86+
ViewButton(Fn action, std::pair<ScreenCoordinate, ScreenCoordinate> rect) : ViewElement(rect), action(action) {}
87+
virtual ~ViewButton() {}
5488

55-
Coordinate getCoordinate() const;
89+
virtual void render() {}
5690
};
5791

92+
template<class Fn>
93+
std::unique_ptr<ViewElement> makeViewButton(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect) {
94+
return std::unique_ptr<ViewElement>(new ViewButton<Fn>(fn, rect));
95+
}
96+
97+
template<class Fn>
98+
class ViewButtonColor : public ViewButton<Fn> {
99+
private:
100+
std::tuple<float, float, float> color;
101+
102+
ViewButtonColor(const ViewButtonColor& vb) : ViewElement(vb) {} //deleted
103+
ViewButtonColor& operator=(const ViewButtonColor& vb) { return *this; }
104+
public:
105+
ViewButtonColor(Fn action, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color) : ViewButton<Fn>(action, rect), color(color) {}
106+
virtual ~ViewButtonColor() {}
107+
108+
virtual void render() {
109+
glBindTexture(GL_TEXTURE_2D, 0);
110+
glColor3f(std::get<0>(color), std::get<1>(color), std::get<2>(color));
111+
auto topLeft = ViewElement::getRect().first;
112+
auto bottomRight = ViewElement::getRect().second;
113+
glBegin(GL_QUADS);
114+
glVertex2f(topLeft.first, topLeft.second);
115+
glVertex2f(bottomRight.first, topLeft.second);
116+
glVertex2f(bottomRight.first, bottomRight.second);
117+
glVertex2f(topLeft.first, bottomRight.second);
118+
glEnd();
119+
}
120+
};
121+
122+
template<class Fn>
123+
std::unique_ptr<ViewElement> makeViewButtonColor(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color) {
124+
return std::unique_ptr<ViewElement>(new ViewButtonColor<Fn>(fn, rect, color));
125+
}
126+
58127
#endif

include/Util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <sstream>
66

77
typedef std::pair<int, int> Coordinate;
8+
typedef std::pair<float, float> ScreenCoordinate;
89

910
template<class T>
1011
T fromString(const std::string& s) {

src/GameController.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
11
#include "GameController.h"
22

33
#include <iostream>
4+
#include <functional>
45

56
#include "GameBoard.h"
67
#include "GameView.h"
8+
#include "Renderer.h"
79

8-
GameController::GameController(GameBoard& model) : model(model) {
10+
GameController::GameController(GameBoard& model, GameView& view) : model(model), view(view), placingRoads(false), placingCities(false) ,lastCoordClick(-100, -100) {
11+
using namespace std::placeholders;
912

13+
view.addElement(makeViewButtonColor(std::bind(&GameController::handleRoadButtonEvent, this, _1), {{0, 0}, {0.1, 0.1}}, std::make_tuple(1.f, 0.f, 0.f)));
14+
view.addElement(makeViewButtonColor(std::bind(&GameController::handleSettlementButtonEvent, this, _1), {{0, 0.1}, {0.1, 0.2}}, std::make_tuple(0.f, 1.0f, 0.f)));
15+
view.addElement(makeViewButton(std::bind(&GameController::handleBoardEvent, this, _1), {{0, 0}, {1, 1}}));
1016
}
1117

1218
GameController::~GameController() {
1319

1420
}
1521

16-
void GameController::handleEvent(const ClickCoordinateEvent& event) {
17-
//std::cout << "user clicked at " << event.getCoordinate().first << ", " << event.getCoordinate().second << std::endl;
18-
if(model.getRoads(event.getCoordinate()).size() > 0) {
19-
model.PlaceSettlement(event.getCoordinate(), *model.getPlayers()[0]);
20-
} else {
21-
static Coordinate adjacentCoordDiffs[] = {Coordinate(0, 1), Coordinate(1, 0), Coordinate(1, -1), Coordinate(0, -1), Coordinate(-1, 0), Coordinate(-1, 1)};
22-
for(auto& adjacent : adjacentCoordDiffs) {
23-
Coordinate start {event.getCoordinate().first + adjacent.first, event.getCoordinate().second + adjacent.second};
24-
if(model.getRoads(start).size() > 0) {
25-
model.PlaceRoad(start, event.getCoordinate(), *model.getPlayers()[0]);
26-
break;
27-
}
22+
bool GameController::handleBoardEvent(ScreenCoordinate screenCoord) {
23+
auto coord = screenToCoord(screenCoord);
24+
if(placingRoads) {
25+
if(lastCoordClick.first == -100 && lastCoordClick.second == -100) {
26+
lastCoordClick = coord;
27+
} else {
28+
model.PlaceRoad(lastCoordClick, coord, *model.getPlayers()[0]);
29+
lastCoordClick = {-100, -100};
2830
}
31+
} else if(placingCities) {
32+
model.PlaceSettlement(coord, *model.getPlayers()[0]);
2933
}
34+
return true;
35+
}
36+
37+
bool GameController::handleRoadButtonEvent(ScreenCoordinate coord) {
38+
placingRoads = true;
39+
placingCities = false;
40+
return true;
41+
}
42+
43+
bool GameController::handleSettlementButtonEvent(ScreenCoordinate coord) {
44+
placingRoads = false;
45+
placingCities = true;
46+
return true;
3047
}
3148

src/GameView.cpp

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,39 @@ using std::pair;
1515
using std::runtime_error;
1616
using std::string;
1717

18-
GameView::GameView(GameBoard& model, GameController& controller) : model(model), controller(controller) {
18+
ViewElement::ViewElement(decltype(rect) rect) {
19+
using std::min;
20+
using std::max;
21+
22+
//rect.first is the min x/min y corner
23+
//rect.second is the max x/max y corner
24+
this->rect.first = {min(rect.first.first, rect.second.first), min(rect.first.second, rect.second.second)};
25+
this->rect.second = {max(rect.first.first, rect.second.first), max(rect.first.second, rect.second.second)};
26+
}
27+
28+
ViewElement::~ViewElement() {
29+
30+
}
31+
32+
decltype(ViewElement::rect) ViewElement::getRect() const {
33+
return rect;
34+
}
35+
36+
bool ViewElement::containsPoint(ScreenCoordinate coord) const {
37+
return rect.first.first < coord.first &&
38+
rect.first.second < coord.second &&
39+
coord.first < rect.second.first &&
40+
coord.second < rect.second.second;
41+
}
42+
43+
bool ViewElement::handleClick(ScreenCoordinate coord) {
44+
if(containsPoint(coord)) {
45+
return clicked(coord);
46+
}
47+
return false;
48+
}
49+
50+
GameView::GameView(GameBoard& model) : model(model) {
1951

2052
}
2153

@@ -29,18 +61,31 @@ void GameView::render() {
2961
DrawingGameVisitor visitor(*this);
3062
model.accept(visitor);
3163

64+
for(auto& it : viewElements) {
65+
it->render();
66+
}
67+
3268
glFlush();
3369
}
3470

3571
bool GameView::acceptInput(SDL_Event& event) {
3672
if(event.type == SDL_QUIT) {
3773
return false;
3874
} else if(event.type == SDL_MOUSEBUTTONUP) {
39-
controller.handleEvent(ClickCoordinateEvent(screenToCoord({(float) event.button.x / 900.f, 1.f - (float) event.button.y / 800.f})));
75+
ScreenCoordinate screen = {(float) event.button.x / 900.f, 1.f - (float) event.button.y / 800.f};
76+
for(auto& it : viewElements) {
77+
if(it->handleClick(screen)) {
78+
break;
79+
}
80+
}
4081
}
4182
return true;
4283
}
4384

85+
void GameView::addElement(std::unique_ptr<ViewElement> element) {
86+
viewElements.emplace_back(std::move(element));
87+
}
88+
4489
DrawingGameVisitor::DrawingGameVisitor(GameView& view) : view(view) {
4590

4691
}
@@ -194,24 +239,3 @@ void DrawingGameVisitor::visit(ResourceTile& tile) {
194239
void DrawingGameVisitor::visit(DevelopmentCard& card) {
195240

196241
}
197-
198-
ClickCoordinateEvent::ClickCoordinateEvent(const Coordinate& clicked) : clicked(clicked) {
199-
200-
}
201-
202-
ClickCoordinateEvent::ClickCoordinateEvent(const ClickCoordinateEvent& event) : clicked(event.clicked) {
203-
204-
}
205-
206-
ClickCoordinateEvent::~ClickCoordinateEvent() {
207-
208-
}
209-
210-
ClickCoordinateEvent& ClickCoordinateEvent::operator=(const ClickCoordinateEvent& event) {
211-
clicked = event.clicked;
212-
return *this;
213-
}
214-
215-
Coordinate ClickCoordinateEvent::getCoordinate() const {
216-
return clicked;
217-
}

src/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ int main(int argc, char *argv[]) {
6868
Player& firstPlayer = *players[0];
6969

7070
GameBoard model(std::move(players));
71-
GameController controller(model);
72-
GameView view(model, controller);
71+
GameView view(model);
72+
GameController controller(model, view);
7373

7474
model.PlaceSettlement(Coordinate{0, 0}, firstPlayer);
7575
model.PlaceRoad(Coordinate{0, 0}, Coordinate{1, 0}, firstPlayer);

0 commit comments

Comments
 (0)