summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Enders <smenders@gmail.com>2021-01-05 00:30:53 -0500
committerStephen Enders <smenders@gmail.com>2021-01-05 00:30:53 -0500
commit9ccf3248f2d9cd2cb9bd5a4826e8d0409f98f3d1 (patch)
tree50d8f29821fbbc42dc932bf3135a084ec2617ffe
Initial commit - Rendering
-rw-r--r--.gitignore6
-rw-r--r--CMakeLists.txt13
-rw-r--r--README.md16
-rw-r--r--helper.cpp106
-rw-r--r--helper.h55
-rwxr-xr-xreformat1
-rw-r--r--res/DejaVuSansMono.ttfbin0 -> 340712 bytes
-rw-r--r--res/ur.asepritebin0 -> 1107 bytes
-rw-r--r--res/ur.pngbin0 -> 1125 bytes
-rw-r--r--ur.cpp63
10 files changed, 260 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9620655
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+*.o
+ur
+Makefile
+CMakeFiles
+CMakeCache.txt
+cmake_install.cmake
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..be11c85
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.13)
+project(ur-sfml)
+set(CMAKE_CXX_STANDARD 20)
+set(EXECUTABLE_NAME ur)
+
+# setup SFML
+set(SFML_LIBRARIES sfml-system sfml-window sfml-graphics)
+find_package(SFML 2.5 REQUIRED COMPONENTS system window graphics)
+
+add_executable(${EXECUTABLE_NAME} ur.cpp helper.h helper.cpp)
+target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
+
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5e3913b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+# The Royal Game of Ur
+
+```
+[ ][ ] [ ][ ][ ][ ]
+[ ][ ][ ][ ][ ][ ][ ][ ]
+[ ][ ] [ ][ ][ ][ ]
+```
+[Gameplay Wiki](https://en.wikipedia.org/wiki/Royal_Game_of_Ur#Gameplay)
+[Play video](https://www.youtube.com/watch?v=WZskjLq040I)
+
+## How to play
+
+Two players - 7 pieces each -
+
+
+
diff --git a/helper.cpp b/helper.cpp
new file mode 100644
index 0000000..c16cb3a
--- /dev/null
+++ b/helper.cpp
@@ -0,0 +1,106 @@
+#include "helper.h"
+#include <iostream>
+
+std::shared_ptr<std::vector<sf::Texture>>
+loadTextures(const char* path)
+{
+ int sprite_width = SPRITE_SIZE, sprite_height = SPRITE_SIZE;
+ sf::Image textureAtlas;
+ if (!textureAtlas.loadFromFile(path)) {
+ std::cerr << "Unable to load textures from file: " << path << std::endl;
+ throw std::runtime_error("Unable to load spritesheet");
+ }
+
+ textureAtlas.createMaskFromColor(GLOBAL_MASK);
+ auto imageSize = textureAtlas.getSize();
+
+ auto textures = std::make_shared<std::vector<sf::Texture>>();
+
+ for (int y = 0; y < imageSize.y; y += sprite_height) {
+ for (int x = 0; x < imageSize.x; x += sprite_width) {
+ sf::Texture t;
+ t.loadFromImage(textureAtlas,
+ sf::IntRect(x, y, sprite_width, sprite_height));
+ textures->push_back(t);
+ }
+ }
+ return textures;
+}
+
+sf::Font loadFont()
+{
+ sf::Font font;
+ if (!font.loadFromFile("./res/DejaVuSansMono.ttf"))
+ {
+ std::cerr << "Unable to load font" << std::endl;
+ throw std::runtime_error("Unable to load font");
+ }
+ return font;
+}
+
+std::shared_ptr<struct piece_t>
+createPiece(int id, sf::Texture texture)
+{
+ std::shared_ptr<sf::Sprite> s = std::make_shared<sf::Sprite>();
+ s->setTexture(texture);
+
+ auto p = std::make_shared<struct piece_t>();
+ p->id = id;
+ p->sprite = s;
+
+ return p;
+}
+
+std::shared_ptr<struct player_t>
+createPlayer(sf::Texture texture)
+{
+ std::shared_ptr<struct player_t> player = std::make_shared<struct player_t>();
+ player->score = 0;
+ player->pieces =
+ std::make_shared<std::vector<std::shared_ptr<struct piece_t>>>();
+ for (int i = 0; i < NUM_PIECES; i++) {
+ player->pieces->push_back(createPiece(i + 1, texture));
+ }
+
+ return player;
+}
+
+bool
+clickedPiece(sf::Vector2i mousePosition, struct piece_t* piece)
+{
+ return piece->sprite->getGlobalBounds().contains(mousePosition.x,
+ mousePosition.y);
+}
+
+bool
+canMovePiece(
+ struct piece_t* piece,
+ int roll,
+ std::shared_ptr<std::vector<std::shared_ptr<struct piece_t>>> myPieces,
+ std::shared_ptr<std::vector<std::shared_ptr<struct piece_t>>> enemyPieces)
+{
+ int next = piece->position + roll;
+
+ // rolled passed the exit
+ if (next > EXIT_SPACE) {
+ return false;
+ }
+
+ // colliding with another piece
+ for (std::shared_ptr<struct piece_t> p : (*myPieces)) {
+ // cannot move onto your own piece
+ if (p->id != piece->id && p->position == next) {
+ return false;
+ }
+ }
+
+ // can't attack in safe square
+ for (std::shared_ptr<struct piece_t> p : (*enemyPieces)) {
+ // cannot move onto a protected enemy piece
+ if (next == SAFE_SPACE && p->position == SAFE_SPACE) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/helper.h b/helper.h
new file mode 100644
index 0000000..dbebfb6
--- /dev/null
+++ b/helper.h
@@ -0,0 +1,55 @@
+#ifndef UR_HELPER_H
+#define UR_HELPER_H
+
+#include <SFML/Graphics.hpp>
+#include <memory>
+#include <vector>
+
+// BOARD LAYOUT [0, 1, 2, 3](start) [4,5,6,7,8,9,10,11](middle), [12,13](end)
+
+static const unsigned int SPRITE_SIZE = 16;
+static const unsigned int NUM_PIECES = 7;
+static const unsigned int SAFE_SPACE = 7; // 0-indexed
+static const unsigned int EXIT_SPACE = 14; // final space + 1
+
+static const sf::Color GLOBAL_MASK(255, 0, 255, 255);
+
+struct piece_t
+{
+ int id;
+ int position;
+ std::shared_ptr<sf::Sprite> sprite;
+};
+
+
+struct player_t
+{
+ int score;
+ std::shared_ptr<std::vector<std::shared_ptr<struct piece_t>>> pieces;
+};
+
+
+std::shared_ptr<std::vector<sf::Texture>>
+loadTextures(const char* path);
+
+sf::Font loadFont();
+
+std::shared_ptr<struct player_t>
+createPlayer(sf::Texture pieceTexture);
+
+std::shared_ptr<struct piece_t>
+createPiece(int id, sf::Texture texture);
+
+bool
+clickedPiece(sf::Vector2i mousePosition, std::shared_ptr<struct piece_t> piece);
+
+bool
+canMovePiece(
+ std::shared_ptr<struct piece_t> piece,
+ int roll,
+ std::shared_ptr<std::vector<std::shared_ptr<struct piece_t>>> myPieces,
+ std::shared_ptr<std::vector<std::shared_ptr<struct piece_t>>> enemyPieces);
+
+std::vector<int> getLegalMoves(std::shared_ptr<struct player_t> activePlayer, std::shared_ptr<struct player_t> opponent);
+#endif
+
diff --git a/reformat b/reformat
new file mode 100755
index 0000000..64a1a59
--- /dev/null
+++ b/reformat
@@ -0,0 +1 @@
+clang-format -i --style=Mozilla *.*pp
diff --git a/res/DejaVuSansMono.ttf b/res/DejaVuSansMono.ttf
new file mode 100644
index 0000000..9d65312
--- /dev/null
+++ b/res/DejaVuSansMono.ttf
Binary files differ
diff --git a/res/ur.aseprite b/res/ur.aseprite
new file mode 100644
index 0000000..6c75ad4
--- /dev/null
+++ b/res/ur.aseprite
Binary files differ
diff --git a/res/ur.png b/res/ur.png
new file mode 100644
index 0000000..cec8744
--- /dev/null
+++ b/res/ur.png
Binary files differ
diff --git a/ur.cpp b/ur.cpp
new file mode 100644
index 0000000..c39c048
--- /dev/null
+++ b/ur.cpp
@@ -0,0 +1,63 @@
+#include <SFML/Graphics.hpp>
+#include <iostream>
+#include "helper.h"
+
+const float SCR_W = 800.f;
+const float SCR_H = 600.f;
+const char* TITLE = "Royal Game of Ur";
+const char* TEXTURE_PATH = "./res/ur.png";
+const int P1_PIECE = 5;
+const int P2_PIECE = 6;
+const int P1_BOARD_TILES[2] = { 0, 1 };
+const int P2_BOARD_TILES[2] = { 2, 3 };
+const int STAR_TILE = 4;
+const int BLANK_TILE = 9;
+const int DIE_0 = 8;
+const int DIE_1 = 7;
+const float ZOOM = .5f;
+const float PAD = 32.f;
+const sf::Color BG_COLOR = sf::Color(66, 47, 81, 255);
+
+int
+main()
+{
+ const std::shared_ptr<std::vector<sf::Texture>> textures =
+ loadTextures(TEXTURE_PATH);
+
+ const std::shared_ptr<struct player_t> p1 =
+ createPlayer((*textures)[P1_PIECE]);
+
+ const std::shared_ptr<struct player_t> p2 =
+ createPlayer((*textures)[P2_PIECE]);
+
+ sf::Font font = loadFont();
+ sf::RenderWindow window(sf::VideoMode(SCR_W, SCR_H), TITLE);
+ sf::Text p1Text("Player one text here!", font, 24);
+ p1Text.setPosition(0.f, 0.f);
+ sf::View view(window.getDefaultView());
+ view.zoom(ZOOM);
+ view.setSize(view.getSize() * ZOOM);
+ view.setCenter(view.getSize() / 2.f);
+
+ sf::Sprite s((*textures)[0]);
+ s.setPosition(0, 0);
+ while (window.isOpen()) {
+
+ sf::Event event;
+ while (window.pollEvent(event)) {
+ if (event.type == sf::Event::Closed ||
+ sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
+ window.close();
+ }
+ }
+
+ window.clear(BG_COLOR);
+ window.setView(view);
+ window.draw(s);
+ window.setView(window.getDefaultView());
+ window.draw(p1Text);
+ window.display();
+ }
+
+ return EXIT_SUCCESS;
+}