Skip to content

Commit d718c75

Browse files
committed
Merge pull request #44 from Databean/buyingInterface
Buying interface
2 parents 9ea7c3b + d362c25 commit d718c75

File tree

9 files changed

+178
-46
lines changed

9 files changed

+178
-46
lines changed

include/GameBoard.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,16 @@ class GameBoard {
101101
void PlaceSettlement(Coordinate location, Player& Owner);
102102
void UpgradeSettlement(Coordinate location);
103103
void UpgradeToWonder(Coordinate location);
104-
105-
104+
106105
bool verifyRoadPlacement(Coordinate start, Coordinate end, Player& Owner) const;
107106
bool buyRoad(Coordinate start, Coordinate end, Player& Owner);
108-
107+
108+
bool canPlaceSettlement(const Coordinate& location, const Player& owner);
109+
bool buySettlement(const Coordinate& location, Player& owner);
110+
111+
bool canUpgradeSettlement(Coordinate location, const Player& owner) const;
112+
bool buyUpgradeOnSettlement(Coordinate location, Player& owner);
113+
109114
//void PlaceSettlement(Coordinate location, Player& Owner);
110115
void PlaceCity(Coordinate location, Player& Owner);
111116
void PlaceWonder(Coordinate location, Player& Owner);

include/GameController.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class GameView;
1212
class Player;
1313

1414

15-
enum ControlState {BASESTATE, MODALSTATE, BUILDROAD, BUILDSETTLEMENT, ROBBER,
15+
enum ControlState {BASESTATE, MODALSTATE, BUILDROAD, BUILDSETTLEMENT, BUILDCITY, ROBBER,
1616
VICTORYPOINT_DEVCARD, BUILDROAD_DEVCARD, KNIGHT_DEVCARD, YEAROFPLENTY_DEVCARD, MONOPOLY_DEVCARD};
1717

1818

@@ -38,6 +38,7 @@ class GameController {
3838
bool handleBoardEvent(ScreenCoordinate);
3939
bool handleRoadButtonEvent(ScreenCoordinate);
4040
bool handleSettlementButtonEvent(ScreenCoordinate);
41+
bool handleCityButtonEvent(ScreenCoordinate);
4142
bool handleRoadCardButtonEvent(ScreenCoordinate);
4243
bool handleKnightCardButtonEvent(ScreenCoordinate);
4344
bool handleYearOfPlentyCardButtonEvent(ScreenCoordinate);

include/Player.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class Player {
7171
void setLongestRoad(bool);
7272
void setLongestRoadSize(int);
7373

74-
std::tuple<float, float, float> getColor();
74+
std::tuple<float, float, float> getColor() const;
7575

7676
int getVictoryPointsWithoutCards();
7777
int getVictoryPointCards();

resources/graphics.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ font.path=resources/ComicNeue-Bold.ttf
33
font.size=50
44

55
# General window settings
6-
screen.width=900
7-
screen.height=800
6+
screen.width=1280
7+
screen.height=720
88

99
# Trading view screen coordinates
1010
screen.tradingView.bottomLeft=(0.1,0.1)

src/GameBoard.cpp

Lines changed: 116 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,8 @@ std::vector<CornerPiece*> GameBoard::GetNeighboringCorners(
410410
const Coordinate& diff = adjacentCoordDiffs[i];
411411
Coordinate adjacentPoint(location.first + diff.first,
412412
location.second + diff.second);
413-
auto it = resources.find(adjacentPoint);
414-
if (it != resources.end()) {
413+
auto it = corners.find(adjacentPoint);
414+
if (it != corners.end()) {
415415
GamePiece* piece = it->second.get();
416416
if (dynamic_cast<CornerPiece*>(piece)) {
417417
v.push_back(static_cast<CornerPiece*>(piece));
@@ -489,18 +489,26 @@ bool GameBoard::isRoadConnectionPoint(Coordinate point, Player& Owner) const {
489489
* @return If the road can be placed at the locations by the player.
490490
*/
491491
bool GameBoard::verifyRoadPlacement(Coordinate start, Coordinate end, Player& Owner) const {
492-
if (outOfBounds(start) || outOfBounds(end))
492+
if (outOfBounds(start) || outOfBounds(end)) {
493+
std::cout << "out of bounds" << std::endl;
493494
return false;
494-
495-
if (roadExists(start, end))
495+
}
496+
497+
if (roadExists(start, end)) {
498+
std::cout << "road exists" << std::endl;
496499
return false;
497-
498-
if (!isRoadConnectionPoint(start, Owner) && !isRoadConnectionPoint(end, Owner)) //need to XOR
500+
}
501+
502+
if (!isRoadConnectionPoint(start, Owner) && !isRoadConnectionPoint(end, Owner)) { //need to XOR
503+
std::cout << "not a road connection point" << std::endl;
499504
return false;
500-
501-
if(!Road::isValidRoad(start, end))
505+
}
506+
507+
if(!Road::isValidRoad(start, end)) {
508+
std::cout << "not a valid road" << std::endl;
502509
return false;
503-
510+
}
511+
504512
return true;
505513
}
506514

@@ -548,8 +556,12 @@ Coordinate GameBoard::getRobber() const {
548556
* @returns True if the road was placed, false otherwise
549557
*/
550558
bool GameBoard::PlaceRoad(Coordinate start, Coordinate end, Player& Owner) {
551-
if (!verifyRoadPlacement(start, end, Owner))
559+
if (!verifyRoadPlacement(start, end, Owner)) {
560+
std::cout << "invalid road placement" << std::endl;
552561
return false;
562+
}
563+
564+
std::cout << "passed verify" << std::endl;
553565

554566
std::shared_ptr<Road> newRoad;
555567
try {
@@ -600,6 +612,7 @@ bool GameBoard::buyRoad(Coordinate start, Coordinate end, Player& Owner){
600612
Owner.buyRoad();
601613
return true;
602614
}
615+
std::cout << "failed to buy for some reason" << std::endl;
603616
return false;
604617
}
605618

@@ -743,6 +756,61 @@ void GameBoard::updateLargestArmyPlayer(){
743756

744757
}
745758

759+
/**
760+
* Whether a player can place a settlement at a location.
761+
* @param location The place to put the settlement.
762+
* @param owner The player placing the settlement.
763+
* @return If the location is a valid place to put a settlement.
764+
*/
765+
bool GameBoard::canPlaceSettlement(const Coordinate& location, const Player& owner) {
766+
//Don't place this on top of a resource
767+
if(resources.find(location) != resources.end()) {
768+
std::cout << "can't put settlements on top of resource tiles" << std::endl;
769+
return false;
770+
}
771+
//Don't place this on top of another settlement
772+
if(corners.find(location) != corners.end()) {
773+
std::cout << "can't put a settlement on top of another corner piece" << std::endl;
774+
return false;
775+
}
776+
//Don't place this off the map
777+
if(outOfBounds(location)) {
778+
std::cout << "this is out of bounds" << std::endl;
779+
return false;
780+
}
781+
//Can't have a settlement next to another settlement.
782+
if(GetNeighboringCorners(location).size() > 0) {
783+
std::cout << "there's an adjacent corner piece" << std::endl;
784+
return false;
785+
}
786+
for(auto road : getRoads(location)) {
787+
if(road->getOwner() == owner) {
788+
//Player has a connecting road
789+
return true;
790+
}
791+
}
792+
std::cout << "there are no connecting roads" << std::endl;
793+
//Player has no connecting roads
794+
return false;
795+
}
796+
797+
/**
798+
* Buy a settlement if possible.
799+
* @param location The location to place the settlement.
800+
* @param owner The player buying the settlement.
801+
* @return If placing the settlement was a success.
802+
*/
803+
bool GameBoard::buySettlement(const Coordinate& location, Player& owner) {
804+
if(canPlaceSettlement(location, owner) && owner.canBuySettlement()) {
805+
if(!owner.buySettlement()) {
806+
std::cout << "wat" << std::endl;
807+
return false;
808+
}
809+
PlaceSettlement(location, owner);
810+
return true;
811+
}
812+
return false;
813+
}
746814

747815
/**
748816
* Place a settlement on the board.
@@ -755,6 +823,43 @@ void GameBoard::PlaceSettlement(Coordinate location, Player& Owner){
755823

756824
}
757825

826+
/**
827+
* Whether a settlement at a location can be upgraded to a city.
828+
*/
829+
bool GameBoard::canUpgradeSettlement(Coordinate location, const Player& owner) const {
830+
auto it = corners.find(location);
831+
if(it == corners.end()) {
832+
std::cout << "there's nothing there" << std::endl;
833+
return false;
834+
}
835+
if(!it->second) {
836+
std::cout << "null ptr there" << std::endl;
837+
return false;
838+
}
839+
if(!(it->second->getOwner() == owner)) {
840+
std::cout << "wrong owner" << std::endl;
841+
return false;
842+
}
843+
if(dynamic_cast<const Settlement*>(it->second.get()) == 0) {
844+
std::cout << "this isn't a settlement" << std::endl;
845+
return false;
846+
}
847+
return true;
848+
}
849+
850+
bool GameBoard::buyUpgradeOnSettlement(Coordinate location, Player& owner) {
851+
if(canUpgradeSettlement(location, owner) && owner.canBuyCity()) {
852+
if(!owner.buyCity()) {
853+
std::cout << "wat" << std::endl;
854+
return false;
855+
}
856+
UpgradeSettlement(location);
857+
return true;
858+
}
859+
std::cout << "failed for some reason" << std::endl;
860+
return false;
861+
}
862+
758863
/**
759864
* Place a city on the board.
760865
* @param location Where to place it on the board.

src/GameController.cpp

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@
1717
*/
1818
GameController::GameController(GameBoard& model, GameView& view) : model(model), view(view) {
1919
using namespace std::placeholders;
20-
20+
2121
view.addElement(makeViewButton(std::bind(&GameController::handleBoardEvent, this, _1), {{0, 0}, {1, 1}}));
22-
23-
view.addElement(makeViewButtonColor(std::bind(&GameController::nextTurn, this, _1), {{0, 0.2}, {0.1, 0.3}}, std::make_tuple(0.f, 0.f, 1.f)));
24-
view.addElement(makeViewButtonColor(std::bind(&GameController::handleRoadButtonEvent, this, _1), {{0, 0}, {0.1, 0.1}}, std::make_tuple(1.f, 0.f, 0.f)));
25-
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)));
2622

2723
auto font = getGraphicsConfig()["font.path"];
2824
auto fontSize = getGraphicsConfig()["font.size"];
2925

26+
view.addElement(makeViewButtonText(std::bind(&GameController::handleRoadButtonEvent, this, _1), {{0, 0}, {0.1, 0.1}}, font, fontSize, "Road"));
27+
view.addElement(makeViewButtonText(std::bind(&GameController::handleSettlementButtonEvent, this, _1), {{0, 0.1}, {0.1, 0.2}}, font, fontSize, "Stlm"));
28+
view.addElement(makeViewButtonText(std::bind(&GameController::handleCityButtonEvent, this, _1), {{0, 0.2}, {0.1, 0.3}}, font, fontSize, "City"));
29+
view.addElement(makeViewButtonText(std::bind(&GameController::nextTurn, this, _1), {{0, 0.3}, {0.1, 0.4}}, font, fontSize, "Turn"));
30+
3031
auto playerTopY = 0.9;
3132
for(auto i = 0; i < model.getNoOfPlayers(); i++) {
3233
auto width = 0.15;
@@ -131,15 +132,18 @@ int GameController::getClickHistorySize(){
131132
return clickHistory.size();
132133
}
133134

134-
135-
136-
135+
void printPlayerInfo(const Player& player) {
136+
auto color = player.getColor();
137+
std::cout << player.getName() << "'s turn. (" << std::get<0>(color) << ", " << std::get<1>(color) << ", " << std::get<2>(color) <<")" << std::endl;
138+
std::cout << "Wood: " << player.getWood() << ", Brick: " << player.getBrick() << ", Ore: " << player.getOre() << ", Wheat: " << player.getWheat() << ", Wool: " << player.getWool() << std::endl;
139+
}
137140

138141
/**
139142
* calls a function to advance turn, check for victory and roll dice
140143
*/
141144
bool GameController::nextTurn(ScreenCoordinate) {
142145
model.endTurn();
146+
printPlayerInfo(model.getCurrentPlayer());
143147
return true;
144148
}
145149

@@ -150,14 +154,15 @@ bool GameController::nextTurn(ScreenCoordinate) {
150154
* @return Whether this event was handled by this element. Always true.
151155
*/
152156
bool GameController::handleBoardEvent(ScreenCoordinate screenCoord) {
157+
printPlayerInfo(model.getCurrentPlayer());
153158
auto coord = screenToCoord(screenCoord);
154-
159+
155160
switch (getState()){
156161
case BUILDROAD:
157162
if(!hasClickHistory()) {
158163
storeClick(coord);
159164
} else {
160-
if (model.PlaceRoad(getLastClick(), coord, *model.getPlayers()[0]));
165+
if (model.buyRoad(getLastClick(), coord, model.getCurrentPlayer()));
161166
{
162167
popState();
163168
}
@@ -196,8 +201,13 @@ bool GameController::handleBoardEvent(ScreenCoordinate screenCoord) {
196201
popState();
197202
break;
198203
case BUILDSETTLEMENT:
199-
std::cout << "BUILDSETTLEMENT\n";
200-
model.PlaceSettlement(coord, *model.getPlayers()[0]);
204+
std::cout << "attempting to buy a settlement" << std::endl;
205+
model.buySettlement(coord, model.getCurrentPlayer());
206+
popState();
207+
break;
208+
case BUILDCITY:
209+
std::cout << "attempting to build a city" << std::endl;
210+
model.buyUpgradeOnSettlement(coord, model.getCurrentPlayer());
201211
popState();
202212
break;
203213
default:
@@ -234,7 +244,7 @@ bool GameController::handleRoadButtonEvent(ScreenCoordinate coord) {
234244
}
235245

236246
/**
237-
* Handles a click on the "create settlement" button. Changes the internal state to indicate the user is going to be making roads on the board.
247+
* Handles a click on the "create settlement" button. Changes the internal state to indicate the user is going to be making settlements on the board.
238248
* @param coord The place the user clicked on screen.
239249
* @return Whether this event was handled by this element. Always true.
240250
*/
@@ -246,6 +256,18 @@ bool GameController::handleSettlementButtonEvent(ScreenCoordinate coord) {
246256
return true;
247257
}
248258

259+
/**
260+
* Handles a click on the "create city" button. Changes the internal state to indicate the user is going to be upgrading settlements to cities on the board.
261+
* @param coord The place the user clicked on screen.
262+
* @return Whether this event was handled by this element. Always true.
263+
*/
264+
bool GameController::handleCityButtonEvent(ScreenCoordinate coord) {
265+
if(getState() == BASESTATE) {
266+
pushState(BUILDCITY);
267+
}
268+
return true;
269+
}
270+
249271

250272
/**
251273
* Handles a click on the road Building Card button. This changes the control state to indicate the user is going to be building roads on the board.

src/Player.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Player::~Player() {
111111

112112
}
113113

114-
std::tuple<float, float, float> Player::getColor(){
114+
std::tuple<float, float, float> Player::getColor() const {
115115
return color;
116116
}
117117

@@ -214,6 +214,7 @@ bool Player::canBuyCity(){
214214
bool Player::buyCity(){
215215
if(canBuyCity()){
216216
addMultiple(0,0,-3,-2,0);
217+
return true;
217218
}
218219
return false;
219220
}

src/Renderer.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,11 @@ pair<float, float> coordToScreen(const Coordinate& coord) {
145145
using std::sin;
146146
using std::cos;
147147
// TODO not magic numbers
148-
static const float scale = 0.1f;
148+
static const float xscale = 9.f / 16.f / 6.f;
149+
static const float yscale = 0.1f;
149150
static const float angle = M_PI / 3.f;
150-
float x = .25f + (scale * coord.first) + ((scale * coord.second) * cos(angle));
151-
float y = .1f + (scale * coord.second) * sin(angle);
151+
float x = .25f + (xscale * coord.first) + ((yscale * coord.second) * cos(angle));
152+
float y = .1f + (yscale * coord.second) * sin(angle);
152153
return std::make_pair(x, y);
153154
}
154155

@@ -158,12 +159,13 @@ pair<float, float> coordToScreen(const Coordinate& coord) {
158159
* @return The game coordinate.
159160
*/
160161
Coordinate screenToCoord(const pair<float, float>& screen) {
161-
static const float scale = 0.1;
162+
static const float xscale = 9.f / 16.f / 6.f;
163+
static const float yscale = 0.1f;
162164
static const float angle = M_PI / 3.f;
163165
Coordinate ret;
164-
float y_approx = (screen.second - 0.1f) / std::sin(angle) / scale;
166+
float y_approx = (screen.second - 0.1f) / std::sin(angle) / yscale;
165167
ret.second = std::round(y_approx);
166-
ret.first = std::round((screen.first - 0.2f) / scale - y_approx * std::cos(angle) - 0.5);
168+
ret.first = std::round((screen.first - 0.25f - y_approx * yscale * std::cos(angle)) / xscale);
167169
return ret;
168170
}
169171

0 commit comments

Comments
 (0)