Skip to content

Commit dffd4b9

Browse files
committed
Merge pull request #29 from Databean/tradingUI
Trading ui
2 parents 6ba3b53 + 0765d9a commit dffd4b9

File tree

7 files changed

+443
-106
lines changed

7 files changed

+443
-106
lines changed

include/GameController.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33

44
#include "Util.h"
55

6+
#include <array>
7+
68
class GameBoard;
79
class ClickCoordinateEvent;
810
class GameView;
11+
class Player;
912

1013
/**
1114
* Takes interpreted Catan events from the View and calls the appropriate functions on the model to changee the state
@@ -29,6 +32,8 @@ class GameController {
2932
bool handleBoardEvent(ScreenCoordinate);
3033
bool handleRoadButtonEvent(ScreenCoordinate);
3134
bool handleSettlementButtonEvent(ScreenCoordinate);
35+
bool handlePlayerClick(ScreenCoordinate, Player&);
36+
bool handleTradeOffer(ScreenCoordinate, Player& initiating, std::array<int, 5>, Player& receiving, std::array<int, 5>);
3237
};
3338

3439
#endif

include/GameView.h

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33

44
#include <vector>
55
#include <memory>
6+
#include <array>
67

78
#include "SDL2/SDL.h"
89
#include "SDL2/SDL_opengl.h"
910
#include "GL/gl.h"
1011

1112
#include "GameVisitor.h"
13+
#include "Renderer.h"
1214
#include "Util.h"
1315

1416
class GameBoard;
@@ -45,10 +47,10 @@ class GameView {
4547
private:
4648
GameBoard& model;
4749

48-
std::vector<std::unique_ptr<ViewElement>> viewElements;
50+
std::map<int, std::unique_ptr<ViewElement>> viewElements;
4951

50-
GameView(const GameView& o) : model(o.model) {} //deleted
51-
GameView& operator=(const GameView& o) { return *this; } //deleted
52+
GameView(const GameView& o) = delete;
53+
GameView& operator=(const GameView& o) = delete;
5254
public:
5355
GameView(GameBoard&);
5456
~GameView();
@@ -57,6 +59,11 @@ class GameView {
5759
bool acceptInput(SDL_Event& event);
5860

5961
void addElement(std::unique_ptr<ViewElement>);
62+
void addElement(int priority, std::unique_ptr<ViewElement>);
63+
64+
std::unique_ptr<ViewElement> removeElement(int priority);
65+
std::unique_ptr<ViewElement> removeElement(const ViewElement*);
66+
std::unique_ptr<ViewElement> removeElement(const ViewElement&);
6067
};
6168

6269
/**
@@ -66,8 +73,8 @@ class DrawingGameVisitor : public GameVisitor {
6673
private:
6774
GameView& view;
6875

69-
DrawingGameVisitor(const DrawingGameVisitor& o) : view(o.view) {} //deleted
70-
DrawingGameVisitor& operator=(const DrawingGameVisitor& o) { return *this; } //deleted
76+
DrawingGameVisitor(const DrawingGameVisitor& o) = delete;
77+
DrawingGameVisitor& operator=(const DrawingGameVisitor& o) = delete;
7178
public:
7279
DrawingGameVisitor(GameView& view);
7380
~DrawingGameVisitor();
@@ -86,22 +93,19 @@ class DrawingGameVisitor : public GameVisitor {
8693
/**
8794
* A view element that is invisible and calls a callback function when it is clicked.
8895
*/
89-
template<class Fn>
9096
class ViewButton : public ViewElement {
9197
private:
92-
Fn action;
98+
std::function<bool(ScreenCoordinate)> action;
9399

94-
ViewButton(const ViewButton& vb) : ViewElement(vb) {} //deleted
95-
ViewButton& operator=(const ViewButton&) { return *this; } //deleted
100+
ViewButton(const ViewButton& vb) = delete;
101+
ViewButton& operator=(const ViewButton&) = delete;
96102
protected:
97-
virtual bool clicked(ScreenCoordinate coord) {
98-
return action(coord);
99-
}
103+
virtual bool clicked(ScreenCoordinate coord);
100104
public:
101-
ViewButton(Fn action, std::pair<ScreenCoordinate, ScreenCoordinate> rect) : ViewElement(rect), action(action) {}
102-
virtual ~ViewButton() {}
105+
ViewButton(std::function<bool(ScreenCoordinate)> action, std::pair<ScreenCoordinate, ScreenCoordinate> rect);
106+
virtual ~ViewButton();
103107

104-
virtual void render() {}
108+
virtual void render();
105109
};
106110

107111
/**
@@ -113,35 +117,23 @@ class ViewButton : public ViewElement {
113117
*/
114118
template<class Fn>
115119
std::unique_ptr<ViewElement> makeViewButton(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect) {
116-
return std::unique_ptr<ViewElement>(new ViewButton<Fn>(fn, rect));
120+
return std::unique_ptr<ViewElement>(new ViewButton(fn, rect));
117121
}
118122

119123
/**
120124
* A view element drawn as a solid color that has a callback function that is called when it is clicked.
121125
*/
122-
template<class Fn>
123-
class ViewButtonColor : public ViewButton<Fn> {
126+
class ViewButtonColor : public ViewButton {
124127
private:
125128
std::tuple<float, float, float> color;
126129

127-
ViewButtonColor(const ViewButtonColor& vb) : ViewElement(vb) {} //deleted
128-
ViewButtonColor& operator=(const ViewButtonColor& vb) { return *this; }
130+
ViewButtonColor(const ViewButtonColor& vb) = delete;
131+
ViewButtonColor& operator=(const ViewButtonColor& vb) = delete;
129132
public:
130-
ViewButtonColor(Fn action, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color) : ViewButton<Fn>(action, rect), color(color) {}
131-
virtual ~ViewButtonColor() {}
132-
133-
virtual void render() {
134-
glBindTexture(GL_TEXTURE_2D, 0);
135-
glColor3f(std::get<0>(color), std::get<1>(color), std::get<2>(color));
136-
auto topLeft = ViewElement::getRect().first;
137-
auto bottomRight = ViewElement::getRect().second;
138-
glBegin(GL_QUADS);
139-
glVertex2f(topLeft.first, topLeft.second);
140-
glVertex2f(bottomRight.first, topLeft.second);
141-
glVertex2f(bottomRight.first, bottomRight.second);
142-
glVertex2f(topLeft.first, bottomRight.second);
143-
glEnd();
144-
}
133+
ViewButtonColor(std::function<bool(ScreenCoordinate)> action, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color);
134+
virtual ~ViewButtonColor();
135+
136+
virtual void render();
145137
};
146138

147139
/**
@@ -154,7 +146,60 @@ class ViewButtonColor : public ViewButton<Fn> {
154146
*/
155147
template<class Fn>
156148
std::unique_ptr<ViewElement> makeViewButtonColor(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color) {
157-
return std::unique_ptr<ViewElement>(new ViewButtonColor<Fn>(fn, rect, color));
149+
return std::unique_ptr<ViewElement>(new ViewButtonColor(fn, rect, color));
158150
}
159151

152+
/**
153+
* A view element drawn as some text on the screen that has a callback function when it is clicked.
154+
*/
155+
class ViewButtonText : public ViewButton {
156+
private:
157+
GLuint texture;
158+
159+
ViewButtonText(const ViewButtonText& vb) = delete;
160+
ViewButtonText& operator=(const ViewButtonText& vb) = delete;
161+
public:
162+
ViewButtonText(std::function<bool(ScreenCoordinate)> action, std::pair<ScreenCoordinate, ScreenCoordinate> rect, const std::string& font, int fontSize, const std::string& text);
163+
virtual ~ViewButtonText();
164+
165+
void setText(const std::string& font, int fontSize, const std::string& text);
166+
167+
virtual void render();
168+
};
169+
170+
/**
171+
* Constructs a ViewButtonText using the same parameters as the ViewButtonText. Exists because template inference exists only
172+
* for functions, not classes.
173+
* @param fn The callback function to be called with the ScreenCoordinate clicked and returning a boolean on if it was handled.
174+
* @param rect The location on screen to draw to and receive clicks from.
175+
* @param font The path to the font to use to draw the text.
176+
* @param fontSize The font size of the text.
177+
* @param text The text to render.
178+
*/
179+
template<class Fn>
180+
std::unique_ptr<ViewElement> makeViewButtonText(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect, const std::string& font, int fontSize, const std::string& text) {
181+
return std::unique_ptr<ViewElement>(new ViewButtonText(fn, rect, font, fontSize, text));
182+
}
183+
184+
class TradingView : public ViewElement {
185+
private:
186+
Player& initiating;
187+
Player& receiving;
188+
189+
ViewButtonText trade;
190+
ViewButtonText cancel;
191+
192+
std::array<int, 5> offer;
193+
194+
TradingView(TradingView& o) = delete;
195+
TradingView& operator=(TradingView& o) = delete;
196+
protected:
197+
virtual bool clicked(ScreenCoordinate coord);
198+
public:
199+
TradingView(Player& initiating, Player& receiving, std::function<bool(std::array<int, 5>, ScreenCoordinate)> trade, std::function<bool(ScreenCoordinate)> cancel, std::array<int, 5> offer);
200+
virtual ~TradingView();
201+
202+
void render();
203+
};
204+
160205
#endif

include/Player.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <vector>
1414
#include <string>
1515
#include <memory>
16+
#include <array>
1617

1718
#include "tinyxml2.h"
1819

@@ -45,7 +46,7 @@ class Player {
4546
int tradeModifiers[5];
4647

4748

48-
void tradeWithBank(int offer[], int demand[]);
49+
void tradeWithBank(std::array<int, 5> offer, std::array<int, 5> demand);
4950

5051
public:
5152

@@ -93,11 +94,9 @@ class Player {
9394

9495
void setGeneralModifier(); //3:1 port
9596

96-
bool offerBankTrade(int offer[], int demand[]);
97+
bool offerBankTrade(std::array<int, 5> offer, std::array<int, 5> demand);
9798

98-
bool offerTrade(Player* p, int offer[], int demand[]);
99-
bool recieveOffer(Player* p, int offer[], int demand[]);
100-
bool acceptOffer(Player* p, int offer[], int demand[]);
99+
bool acceptOffer(Player& p, std::array<int, 5> offer, std::array<int, 5> demand);
101100

102101
int getRandomResource();
103102

src/GameController.cpp

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
#include <iostream>
44
#include <functional>
5+
#include <memory>
56

67
#include "GameBoard.h"
78
#include "GameView.h"
89
#include "Renderer.h"
10+
#include "Player.h"
911

1012
/**
1113
* Initialize the game controller. Adds the buttons for user control to the view, binding them to GameController methods.
@@ -15,8 +17,20 @@
1517
GameController::GameController(GameBoard& model, GameView& view) : model(model), view(view), placingRoads(false), placingCities(false) ,lastCoordClick(-100, -100) {
1618
using namespace std::placeholders;
1719

18-
view.addElement(makeViewButtonColor(std::bind(&GameController::handleRoadButtonEvent, this, _1), {{0, 0}, {0.1, 0.1}}, std::make_tuple(1.f, 0.f, 0.f)));
19-
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)));
20+
auto font = "resources/TypeWritersSubstitute-Black.ttf";
21+
auto fontSize = 50;
22+
23+
view.addElement(makeViewButtonText(std::bind(&GameController::handleRoadButtonEvent, this, _1), {{0, 0}, {0.1, 0.1}}, font, fontSize, "Road"));
24+
view.addElement(makeViewButtonText(std::bind(&GameController::handleSettlementButtonEvent, this, _1), {{0, 0.1}, {0.1, 0.2}}, font, fontSize, "Settlement"));
25+
26+
auto playerTopY = 0.9;
27+
for(auto i = 0; i < model.getNoOfPlayers(); i++) {
28+
auto width = 0.2;
29+
Player& player = model.getPlayer(i);
30+
view.addElement(makeViewButtonText(std::bind(&GameController::handlePlayerClick, this, _1, std::ref(player)), {{1.0 - width, playerTopY - 0.1}, {1.0, playerTopY}}, font, fontSize, player.getName()));
31+
playerTopY -= 0.05;
32+
}
33+
2034
view.addElement(makeViewButton(std::bind(&GameController::handleBoardEvent, this, _1), {{0, 0}, {1, 1}}));
2135
}
2236

@@ -69,3 +83,76 @@ bool GameController::handleSettlementButtonEvent(ScreenCoordinate coord) {
6983
return true;
7084
}
7185

86+
template<int size>
87+
auto negativeArr(std::array<int, size> arr) -> std::array<int, size> {
88+
for(auto& it : arr) {
89+
it = -it;
90+
}
91+
return arr;
92+
}
93+
94+
/**
95+
* Handles a click on one of the Player names at the top right of the screen.
96+
* @param coord The coordinate clicked on.
97+
* @param player The player whose name was clicked on.
98+
*/
99+
bool GameController::handlePlayerClick(ScreenCoordinate coord, Player& player) {
100+
using namespace std::placeholders;
101+
Player& initiating = *model.getPlayers()[0];
102+
Player& receiving = player;
103+
auto priority = -10;
104+
105+
std::array<int, 5> initial{{0, 0, 0, 0, 0}};
106+
107+
//std::function<bool(std::array<int, 5>, ScreenCoordinate)> tradeFunction(std::bind(&GameController::handleTradeOffer, this, _2, std::ref(initiating), _1, std::ref(receiving)));
108+
std::function<bool(std::array<int, 5>, ScreenCoordinate)> tradeFunction([this, &initiating, &receiving](std::array<int, 5> offer, ScreenCoordinate coord) {
109+
std::array<int, 5> initial{{0, 0, 0, 0, 0}};
110+
std::array<int, 5> reverseOffer = negativeArr<5>(offer);
111+
handleTradeOffer(coord, receiving, initial, initiating, reverseOffer);
112+
return true;
113+
});
114+
std::function<bool(ScreenCoordinate)> cancelFunction([this, priority](ScreenCoordinate coord) {
115+
view.removeElement(priority);
116+
return true;
117+
});
118+
119+
view.addElement(priority, std::unique_ptr<ViewElement>(new TradingView(initiating, receiving, tradeFunction, cancelFunction, initial)));
120+
std::cout << player.getName() << std::endl;
121+
return true;
122+
}
123+
124+
/**
125+
* Handle a trade offer from a player.
126+
* @param coord The coordinate clicked on to initiate the trade.
127+
* @param initiating The player initiating the trade.
128+
* @param offer The offer the player is giving.
129+
* @param receiving The other player in the trade.
130+
*/
131+
bool GameController::handleTradeOffer(ScreenCoordinate coord, Player& initiating, std::array<int, 5> offer, Player& receiving, std::array<int, 5> counterOffer) {
132+
auto priority = -10;
133+
if(offer == negativeArr<5>(counterOffer)) {
134+
view.removeElement(priority);
135+
std::array<int, 5> splitOffer;
136+
std::array<int, 5> splitDemand;
137+
for(int i = 0; i < 5; i++) {
138+
splitOffer[i] = counterOffer[i] < 0 ? 0 : -counterOffer[i];
139+
splitDemand[i] = counterOffer[i] < 0 ? 0 : counterOffer[i];
140+
}
141+
initiating.acceptOffer(receiving, splitOffer, splitDemand);
142+
} else {
143+
//std::function<bool(std::array<int, 5>, ScreenCoordinate)> tradeFunction(std::bind(&GameController::handleTradeOffer, this, _2, std::ref(initiating), _1, std::ref(receiving)));
144+
std::function<bool(std::array<int, 5>, ScreenCoordinate)> tradeFunction([this, &initiating, &receiving, counterOffer](std::array<int, 5> offer, ScreenCoordinate coord) {
145+
std::array<int, 5> reverseOffer = negativeArr<5>(offer);
146+
handleTradeOffer(coord, receiving, counterOffer, initiating, reverseOffer);
147+
return true;
148+
});
149+
std::function<bool(ScreenCoordinate)> cancelFunction([this, priority](ScreenCoordinate coord) {
150+
view.removeElement(priority);
151+
return true;
152+
});
153+
154+
view.addElement(priority, std::unique_ptr<ViewElement>(new TradingView(initiating, receiving, tradeFunction, cancelFunction, counterOffer)));
155+
}
156+
return true;
157+
}
158+

0 commit comments

Comments
 (0)