Skip to content

Commit 3269ac6

Browse files
committed
Merge branch 'master' of https://github.com/Databean/warsofcatan into refactor_and_test_dice
2 parents ec2ae81 + 26b1eee commit 3269ac6

File tree

8 files changed

+444
-107
lines changed

8 files changed

+444
-107
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export EXECUTABLE := warsofcatan
77
ALLFILES := $(wildcard $(SRC_HOME)/*) $(wildcard $(INCL_HOME)/*)
88
export CXX := g++
99
export LD := g++
10-
export CXXFLAGS := -g -I$(INCL_HOME) -std=c++0x -I/usr/include/SDL -Wall
10+
export CXXFLAGS := -g -I$(INCL_HOME) -std=c++0x -I/usr/include/SDL2 -I/usr/local/include/SDL2 -Wall
1111
export LDFLAGS := -L/usr/local/lib -lSDL2 -lSDL2_ttf -lGL -lGLU -Wl,-R/usr/local/lib
1212

1313
.PHONY: all

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;
@@ -46,10 +48,10 @@ class GameView {
4648
private:
4749
GameBoard& model;
4850

49-
std::vector<std::unique_ptr<ViewElement>> viewElements;
51+
std::map<int, std::unique_ptr<ViewElement>> viewElements;
5052

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

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

6370
/**
@@ -67,8 +74,8 @@ class DrawingGameVisitor : public GameVisitor {
6774
private:
6875
GameView& view;
6976

70-
DrawingGameVisitor(const DrawingGameVisitor& o) : view(o.view) {} //deleted
71-
DrawingGameVisitor& operator=(const DrawingGameVisitor& o) { return *this; } //deleted
77+
DrawingGameVisitor(const DrawingGameVisitor& o) = delete;
78+
DrawingGameVisitor& operator=(const DrawingGameVisitor& o) = delete;
7279
public:
7380
DrawingGameVisitor(GameView& view);
7481
~DrawingGameVisitor();
@@ -87,22 +94,19 @@ class DrawingGameVisitor : public GameVisitor {
8794
/**
8895
* A view element that is invisible and calls a callback function when it is clicked.
8996
*/
90-
template<class Fn>
9197
class ViewButton : public ViewElement {
9298
private:
93-
Fn action;
99+
std::function<bool(ScreenCoordinate)> action;
94100

95-
ViewButton(const ViewButton& vb) : ViewElement(vb) {} //deleted
96-
ViewButton& operator=(const ViewButton&) { return *this; } //deleted
101+
ViewButton(const ViewButton& vb) = delete;
102+
ViewButton& operator=(const ViewButton&) = delete;
97103
protected:
98-
virtual bool clicked(ScreenCoordinate coord) {
99-
return action(coord);
100-
}
104+
virtual bool clicked(ScreenCoordinate coord);
101105
public:
102-
ViewButton(Fn action, std::pair<ScreenCoordinate, ScreenCoordinate> rect) : ViewElement(rect), action(action) {}
103-
virtual ~ViewButton() {}
106+
ViewButton(std::function<bool(ScreenCoordinate)> action, std::pair<ScreenCoordinate, ScreenCoordinate> rect);
107+
virtual ~ViewButton();
104108

105-
virtual void render() {}
109+
virtual void render();
106110
};
107111

108112
/**
@@ -114,35 +118,23 @@ class ViewButton : public ViewElement {
114118
*/
115119
template<class Fn>
116120
std::unique_ptr<ViewElement> makeViewButton(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect) {
117-
return std::unique_ptr<ViewElement>(new ViewButton<Fn>(fn, rect));
121+
return std::unique_ptr<ViewElement>(new ViewButton(fn, rect));
118122
}
119123

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

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

148140
/**
@@ -155,7 +147,60 @@ class ViewButtonColor : public ViewButton<Fn> {
155147
*/
156148
template<class Fn>
157149
std::unique_ptr<ViewElement> makeViewButtonColor(Fn fn, std::pair<ScreenCoordinate, ScreenCoordinate> rect, std::tuple<float, float, float> color) {
158-
return std::unique_ptr<ViewElement>(new ViewButtonColor<Fn>(fn, rect, color));
150+
return std::unique_ptr<ViewElement>(new ViewButtonColor(fn, rect, color));
159151
}
160152

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