summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Enders <smenders@gmail.com>2021-01-27 22:15:08 -0500
committerStephen Enders <smenders@gmail.com>2021-01-27 22:22:40 -0500
commitd73c93b4c783edfc6f3afe19d35b9409953c7323 (patch)
treedb6841bd704d8de2b16abfa34fa72e7e0039aed6
parent100907bd56b18c50aab9efb10700956b8c164c05 (diff)
Legal placement logic and capturing
Use board_t for board and prevent illegal placements. And allow for piece capture
-rw-r--r--src/helper.cpp79
-rw-r--r--src/helper.hpp25
-rw-r--r--src/ur.cpp72
3 files changed, 142 insertions, 34 deletions
diff --git a/src/helper.cpp b/src/helper.cpp
index 96eb919..11374e8 100644
--- a/src/helper.cpp
+++ b/src/helper.cpp
@@ -36,10 +36,10 @@ next(int* p, int max)
return i;
}
-std::shared_ptr<std::vector<struct piece_t>>
+std::shared_ptr<std::vector<struct board_t>>
createBoard(std::shared_ptr<std::vector<sf::Texture>> textures)
{
- auto board = std::make_shared<std::vector<struct piece_t>>();
+ auto board = std::make_shared<std::vector<struct board_t>>();
sf::Texture& star_texture = (*textures)[STAR_TILE];
int blank_idx = 0;
int sp_idx = 0;
@@ -53,12 +53,12 @@ createBoard(std::shared_ptr<std::vector<sf::Texture>> textures)
// p1 pieces
// p1 star
// id's don't matter
- int id = 0;
{
sf::Sprite s;
s.setTexture(star_texture);
s.setPosition(pos(3, 5));
- board->push_back({ id++, 3, s });
+ struct board_t bp = { P1_ID, 3, s };
+ board->push_back(bp);
}
// p1 start
for (int i = 0; i < 3; i++) {
@@ -66,25 +66,29 @@ createBoard(std::shared_ptr<std::vector<sf::Texture>> textures)
sf::Sprite s;
s.setTexture(t);
s.setPosition(pos(4 + i, 5));
- board->push_back({ id++, 2 - i, s });
+ struct board_t bp = { P1_ID, 2 - i, s };
+ board->push_back(bp);
}
// p1 end
{
sf::Sprite goal;
goal.setTexture((*textures)[P1_END]);
goal.setPosition(pos(8, 5));
- board->push_back({ id++, EXIT_SPACE, goal });
+ struct board_t exit_p = { P1_ID, EXIT_SPACE, goal };
+ board->push_back(exit_p);
sf::Sprite end_star;
end_star.setTexture(star_texture);
end_star.setPosition(pos(9, 5));
- board->push_back({ id++, EXIT_SPACE - 1, end_star });
+ struct board_t end_p = { P1_ID, EXIT_SPACE - 1, end_star };
+ board->push_back(end_p);
sf::Texture& t = (*textures)[P1_BOARD_TILES[next(&sp_idx, 2)]];
sf::Sprite s;
s.setTexture(t);
s.setPosition(pos(10, 5));
- board->push_back({ id++, EXIT_SPACE - 2, s });
+ struct board_t bp = { P1_ID, EXIT_SPACE - 2, s };
+ board->push_back(bp);
}
// center pieces
for (int i = 0; i < 8; i++) {
@@ -96,7 +100,8 @@ createBoard(std::shared_ptr<std::vector<sf::Texture>> textures)
s.setTexture(t);
}
s.setPosition(pos(3 + i, 4));
- board->push_back({ id++, 4 + i, s });
+ struct board_t bp = { SHARED_ID, 4 + i, s };
+ board->push_back(bp);
}
// p2 pieces
// p2 star
@@ -104,7 +109,8 @@ createBoard(std::shared_ptr<std::vector<sf::Texture>> textures)
sf::Sprite s;
s.setTexture(star_texture);
s.setPosition(pos(3, 3));
- board->push_back({ id++, 3, s });
+ struct board_t bp = { P2_ID, 3, s };
+ board->push_back(bp);
}
// p2 start
for (int i = 0; i < 3; i++) {
@@ -112,25 +118,29 @@ createBoard(std::shared_ptr<std::vector<sf::Texture>> textures)
sf::Sprite s;
s.setTexture(t);
s.setPosition(pos(4 + i, 3));
- board->push_back({ id++, 2 - i, s });
+ struct board_t bp = { P2_ID, 2 - i, s };
+ board->push_back(bp);
}
// p2 end
{
sf::Sprite goal;
goal.setTexture((*textures)[P2_END]);
goal.setPosition(pos(8, 3));
- board->push_back({ id++, EXIT_SPACE, goal });
+ struct board_t goal_p = { P2_ID, EXIT_SPACE, goal };
+ board->push_back(goal_p);
sf::Sprite end_star;
end_star.setTexture(star_texture);
end_star.setPosition(pos(9, 3));
- board->push_back({ id++, EXIT_SPACE - 1, end_star });
+ struct board_t end_p = { P2_ID, EXIT_SPACE - 1, end_star };
+ board->push_back(end_p);
sf::Texture& t = (*textures)[P2_BOARD_TILES[next(&sp_idx, 2)]];
sf::Sprite end_tile;
end_tile.setTexture(t);
end_tile.setPosition(pos(10, 3));
- board->push_back({ id++, EXIT_SPACE - 2, end_tile });
+ struct board_t bp = { P2_ID, EXIT_SPACE - 2, end_tile };
+ board->push_back(bp);
}
return board;
@@ -161,9 +171,10 @@ createPiece(int id, sf::Texture& texture)
}
std::shared_ptr<struct player_t>
-createPlayer(sf::Texture& texture)
+createPlayer(const int pid, sf::Texture& texture)
{
std::shared_ptr<struct player_t> player = std::make_shared<struct player_t>();
+ player->pid = pid;
player->score = 0;
player->pieces = std::make_shared<std::vector<struct piece_t>>();
for (int i = 0; i < NUM_PIECES; i++) {
@@ -273,3 +284,41 @@ pos(float c, float r)
{
return { c * SPRITE_SIZE, r * SPRITE_SIZE };
}
+
+bool
+canPlace(struct piece_t* piece,
+ int turn_pid,
+ struct board_t board_tile,
+ std::shared_ptr<std::vector<struct piece_t>> myPieces,
+ std::shared_ptr<std::vector<struct piece_t>> opponentPieces,
+ int& takenPieceId)
+{
+ if (board_tile.pid != turn_pid && board_tile.pid != SHARED_ID)
+ return false;
+ int position = board_tile.position;
+ if (position == EXIT_SPACE)
+ return true; // can always place in the exit
+
+ // can never collide with your own pieces
+ for (auto& p : (*myPieces)) {
+ if ((p.id != piece->id) // not the same
+ && (p.position == position)) {
+ return false; // collides with own pieces
+ }
+ }
+ // can collide with an enemy
+ if (position >= 4 && position <= 11) {
+ for (auto& p : (*opponentPieces)) {
+ // collided
+ if (p.position == position) {
+ // can not capture on safe space
+ if (position == SAFE_SPACE)
+ return false;
+ takenPieceId = p.id;
+ return true;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/src/helper.hpp b/src/helper.hpp
index 9495791..2ff8b24 100644
--- a/src/helper.hpp
+++ b/src/helper.hpp
@@ -16,6 +16,9 @@ static const float SPRITE_ROWS = 9.f;
static const float SPRITE_COLS = 14.f;
static const float SCR_W = SPRITE_SIZE / ZOOM * SPRITE_COLS / ZOOM;
static const float SCR_H = SPRITE_SIZE / ZOOM * SPRITE_ROWS / ZOOM;
+static const int SHARED_ID = -1;
+static const int P1_ID = 0;
+static const int P2_ID = 1;
static const int P1_PIECE = 19;
static const int P2_PIECE = 18;
static const int P1_BOARD_TILES[2] = { 0, 1 };
@@ -45,10 +48,19 @@ struct piece_t
int id;
int position;
sf::Sprite sprite;
+ sf::Vector2f origin;
+};
+
+struct board_t
+{
+ int pid; // owning players space -1 for shared
+ int position;
+ sf::Sprite sprite;
};
struct player_t
{
+ int pid;
int score;
std::shared_ptr<std::vector<struct piece_t>> pieces;
};
@@ -63,14 +75,14 @@ struct dice_t
std::shared_ptr<std::vector<sf::Texture>>
loadTextures(const char* path);
-std::shared_ptr<std::vector<struct piece_t>>
+std::shared_ptr<std::vector<struct board_t>>
createBoard(std::shared_ptr<std::vector<sf::Texture>> textures);
sf::Font
loadFont();
std::shared_ptr<struct player_t>
-createPlayer(sf::Texture& pieceTexture);
+createPlayer(const int pid, sf::Texture& pieceTexture);
std::shared_ptr<struct piece_t>
createPiece(int id, sf::Texture& texture);
@@ -101,4 +113,13 @@ getLegalMoves(std::shared_ptr<struct player_t> activePlayer,
sf::Vector2f
pos(float c, float r);
+
+bool
+canPlace(struct piece_t* piece,
+ int turn_pid,
+ struct board_t board_tile,
+ std::shared_ptr<std::vector<struct piece_t>> myPieces,
+ std::shared_ptr<std::vector<struct piece_t>> opponentPieces,
+ int& takenPieceId);
+
#endif
diff --git a/src/ur.cpp b/src/ur.cpp
index 6bd27f4..f406623 100644
--- a/src/ur.cpp
+++ b/src/ur.cpp
@@ -30,8 +30,8 @@ change_state(GameState next)
state = next;
}
-// p1 = false, p2 = true
-bool turn_tracker = false;
+// tracks the turn pids
+int turn_pid = P1_ID;
int rolling_frame = 0;
inline void
@@ -43,20 +43,20 @@ next(int* i, int max)
inline void
next_turn()
{
- turn_tracker = !turn_tracker;
+ turn_pid = turn_pid == P1_ID ? P2_ID : P1_ID;
change_state(GameState::WAITING);
}
inline bool
p1_turn()
{
- return !turn_tracker;
+ return turn_pid == P1_ID;
}
inline bool
p2_turn()
{
- return turn_tracker;
+ return turn_pid == P2_ID;
}
inline void
@@ -160,14 +160,14 @@ main()
const std::shared_ptr<std::vector<sf::Texture>> textures =
loadTextures(TEXTURE_PATH);
- const std::shared_ptr<std::vector<struct piece_t>> board =
+ const std::shared_ptr<std::vector<struct board_t>> board =
createBoard(textures);
const std::shared_ptr<struct player_t> p1 =
- createPlayer((*textures)[P1_PIECE]);
+ createPlayer(P1_ID, (*textures)[P1_PIECE]);
const std::shared_ptr<struct player_t> p2 =
- createPlayer((*textures)[P2_PIECE]);
+ createPlayer(P2_ID, (*textures)[P2_PIECE]);
const std::shared_ptr<std::vector<sf::Sprite>> roll_sprites =
createRollSprites((*textures)[ROLL_TILES[0]], (*textures)[ROLL_TILES[1]]);
@@ -187,11 +187,13 @@ main()
int p_num = (SPRITE_COLS / 2) - (p1->pieces->size() / 2) - 1;
for (auto& p : *(p1->pieces)) {
p.sprite.setPosition(pos(p_num++, SPRITE_ROWS - 1));
+ p.origin = p.sprite.getPosition();
}
p_num = (SPRITE_COLS / 2) - (p2->pieces->size() / 2) - 1;
for (auto& p : *(p2->pieces)) {
p.sprite.setPosition(pos(p_num++, 0));
+ p.origin = p.sprite.getPosition();
}
sf::Sprite roll_result;
@@ -263,6 +265,15 @@ main()
window.setView(window.getDefaultView()); // reset back to main view
} else if (!sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
mouse_left_locked = false;
+ // is a piece being clicked
+ std::shared_ptr<std::vector<struct piece_t>> pieces, enemyPieces;
+ if (p1_turn()) {
+ pieces = p1->pieces;
+ enemyPieces = p2->pieces;
+ } else {
+ pieces = p2->pieces;
+ enemyPieces = p1->pieces;
+ }
if (state == GameState::PLACING && grabbed_piece != nullptr) {
// did the piece drop into place
bool in_place = false;
@@ -274,9 +285,27 @@ main()
if (intersect.width > SPRITE_SIZE / 2 &&
intersect.height > SPRITE_SIZE / 2) {
// check valid placement
- grabbed_piece->sprite.setPosition(s.getPosition());
- in_place = true;
- break;
+ int takenPieceId = -1;
+ if (canPlace(grabbed_piece,
+ turn_pid,
+ bp,
+ pieces,
+ enemyPieces,
+ takenPieceId)) {
+ // did we take a piece
+ if (takenPieceId >= 0) {
+ for (auto& ep : (*enemyPieces)) {
+ if (ep.id = takenPieceId) {
+ ep.sprite.setPosition(ep.origin);
+ ep.position = -1;
+ }
+ }
+ }
+ grabbed_piece->sprite.setPosition(s.getPosition());
+ grabbed_piece->position = bp.position;
+ in_place = true;
+ break;
+ }
}
}
}
@@ -308,12 +337,21 @@ main()
float y = mPos.y - (grabbed_piece->sprite.getGlobalBounds().height / 2);
grabbed_piece->sprite.setPosition(x, y);
}
- // draw unused pieces
- for (auto& p : *(p1->pieces)) {
- window.draw(p.sprite);
- }
- for (auto& p : *(p2->pieces)) {
- window.draw(p.sprite);
+ // draw pieces (draw own pieces last to ensure "on top")
+ if (p1_turn()) {
+ for (auto& p : *(p2->pieces)) {
+ window.draw(p.sprite);
+ }
+ for (auto& p : *(p1->pieces)) {
+ window.draw(p.sprite);
+ }
+ } else {
+ for (auto& p : *(p1->pieces)) {
+ window.draw(p.sprite);
+ }
+ for (auto& p : *(p2->pieces)) {
+ window.draw(p.sprite);
+ }
}
render_dice(&window,