added distribution menu

This commit is contained in:
2025-03-29 21:57:27 +01:00
parent 7151be0b1a
commit 314b7a8488
12 changed files with 207 additions and 40 deletions

View File

@@ -2,6 +2,7 @@
#include "../Pieces/Piece.h" #include "../Pieces/Piece.h"
#include "PiecesList.h" #include "PiecesList.h"
#include "DistributionMode.h"
#include <vector> #include <vector>
#include <memory> #include <memory>
@@ -18,7 +19,7 @@ class Bag {
std::shared_ptr<PiecesList> piecesList; // the list of loaded pieces std::shared_ptr<PiecesList> piecesList; // the list of loaded pieces
int highestSize; // the highest size of piece in the bag int highestSize; // the highest size of piece in the bag
std::vector<std::pair<int, int>> selectedPieces; // the list of pieces that can be given to the player std::vector<std::pair<int, int>> selectedPieces; // the list of pieces that can be given to the player
PiecesDistributionMode distributionMode; // the distribution mode DistributionMode distributionMode; // the distribution mode
std::vector<double> propotionsPerSize; // the proportion of pieces for each size std::vector<double> propotionsPerSize; // the proportion of pieces for each size
std::pair<int, int> next; // the next piece to give std::pair<int, int> next; // the next piece to give
std::vector<PieceBag> currentBags; // for each size, the list of pieces that are still to be taken out before starting a new bag std::vector<PieceBag> currentBags; // for each size, the list of pieces that are still to be taken out before starting a new bag

View File

@@ -0,0 +1,27 @@
#pragma once
#include <string>
/**
* The modes of pieces distribution managed by the app
*/
enum DistributionMode {
DEFAULT,
UNIFORM,
CUSTOM
};
/**
* @return A string containing the name of the given distribution mode
*/
inline std::string getPiecesDistributionName(DistributionMode distributionMode) {
static const std::string DISTRIBUTION_NAMES[] = {
"DEFAULT",
"UNIFORM",
"CUSTOM"
};
return DISTRIBUTION_NAMES[distributionMode];
}

View File

@@ -2,6 +2,7 @@
#include "../Pieces/Piece.h" #include "../Pieces/Piece.h"
#include "../Pieces/PiecesFiles.h" #include "../Pieces/PiecesFiles.h"
#include "DistributionMode.h"
#include <vector> #include <vector>
#include <utility> #include <utility>
@@ -91,7 +92,7 @@ void PiecesList::unselectAll() {
this->selectedPieces.clear(); this->selectedPieces.clear();
} }
bool PiecesList::setDistributionMode(PiecesDistributionMode distributionMode) { bool PiecesList::setDistributionMode(DistributionMode distributionMode) {
if (distributionMode == DEFAULT || distributionMode == UNIFORM || distributionMode == CUSTOM) { if (distributionMode == DEFAULT || distributionMode == UNIFORM || distributionMode == CUSTOM) {
this->distributionMode = distributionMode; this->distributionMode = distributionMode;
return true; return true;
@@ -113,7 +114,7 @@ std::vector<std::pair<int, int>> PiecesList::getSelectedPieces() const {
return this->selectedPieces; return this->selectedPieces;
} }
PiecesDistributionMode PiecesList::getDistributionMode() const { DistributionMode PiecesList::getDistributionMode() const {
return this->distributionMode; return this->distributionMode;
} }

View File

@@ -1,21 +1,12 @@
#pragma once #pragma once
#include "../Pieces/Piece.h" #include "../Pieces/Piece.h"
#include "DistributionMode.h"
#include <vector> #include <vector>
#include <utility> #include <utility>
/**
* The type of pieces distribution managed by the game
*/
enum PiecesDistributionMode {
DEFAULT,
UNIFORM,
CUSTOM
};
/** /**
* A container for all loaded pieces to prevent loading and copying them multiple times, * A container for all loaded pieces to prevent loading and copying them multiple times,
* also allows for the player to select a list of pieces to be used in a game * also allows for the player to select a list of pieces to be used in a game
@@ -28,7 +19,7 @@ class PiecesList {
std::vector<std::vector<int>> holelessPieces; // the list of holeless loaded pieces by size std::vector<std::vector<int>> holelessPieces; // the list of holeless loaded pieces by size
std::vector<std::vector<int>> otherPieces; // the list of other loaded pieces by size std::vector<std::vector<int>> otherPieces; // the list of other loaded pieces by size
std::vector<std::pair<int, int>> selectedPieces; // the list of all currently selected pieces std::vector<std::pair<int, int>> selectedPieces; // the list of all currently selected pieces
PiecesDistributionMode distributionMode; // the current pieces distribution mode DistributionMode distributionMode; // the current pieces distribution mode
std::vector<double> proportionsPerSize; // the proportion of piece for each sizes std::vector<double> proportionsPerSize; // the proportion of piece for each sizes
std::vector<double> customProportionsPerSize; // the proportion of piece for each sizes when the distribution mode is set to custom std::vector<double> customProportionsPerSize; // the proportion of piece for each sizes when the distribution mode is set to custom
@@ -83,7 +74,7 @@ class PiecesList {
* Changes the current pieces distribution mode * Changes the current pieces distribution mode
* @return If the mode is supported * @return If the mode is supported
*/ */
bool setDistributionMode(PiecesDistributionMode distributionMode); bool setDistributionMode(DistributionMode distributionMode);
/** /**
* Changes the distribution of the specified size for when the distribution mode is set to custom, * Changes the distribution of the specified size for when the distribution mode is set to custom,
@@ -110,7 +101,7 @@ class PiecesList {
/** /**
* @return The current distribution mode * @return The current distribution mode
*/ */
PiecesDistributionMode getDistributionMode() const; DistributionMode getDistributionMode() const;
/** /**
* @return The proportion of pieces for each loaded size * @return The proportion of pieces for each loaded size

View File

@@ -57,8 +57,6 @@ void GameBoardAppMenu::drawFrame() const {
this->placeTitle(text, {}, "BOARD SETTINGS", 5.f, {}); this->placeTitle(text, {}, "BOARD SETTINGS", 5.f, {});
sf::Vector2u windowSize = this->renderWindow->getSize();
this->placeText(text, this->playerCursor, "< BOARD WIDTH: " + std::to_string(menu.getBoardWidth()) + " >", 5.f, 15.f, sf::Vector2u{0, 0}); this->placeText(text, this->playerCursor, "< BOARD WIDTH: " + std::to_string(menu.getBoardWidth()) + " >", 5.f, 15.f, sf::Vector2u{0, 0});
this->placeText(text, this->playerCursor, "< BOARD HEIGHT: " + std::to_string(menu.getBoardHeight()) + " >", 5.f, 25.f, sf::Vector2u{0, 1}); this->placeText(text, this->playerCursor, "< BOARD HEIGHT: " + std::to_string(menu.getBoardHeight()) + " >", 5.f, 25.f, sf::Vector2u{0, 1});

View File

@@ -0,0 +1,85 @@
#include "GameDistributionAppMenu.h"
#include "AppMenu.h"
#include "../PlayerCursor.h"
#include <stack>
#include <memory>
#include <SFML/Graphics.hpp>
GameDistributionAppMenu::GameDistributionAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
AppMenu(menuStack, settings, renderWindow),
playerCursor({1}) {
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
this->playerCursor.addRow(i, 1);
}
}
void GameDistributionAppMenu::computeFrame() {
this->updateMetaBinds();
this->playerCursor.updatePosition();
PiecesList& piecesList = this->settings->getMenu().getPiecesList();
if (this->playerCursor.getPosition().y == 0) {
if (this->playerCursor.movedLeft()) {
piecesList.setDistributionMode(DistributionMode((int) piecesList.getDistributionMode() - 1));
}
if (this->playerCursor.movedRight()) {
piecesList.setDistributionMode(DistributionMode((int) piecesList.getDistributionMode() + 1));
}
}
else {
if (piecesList.getDistributionMode() != CUSTOM) {
this->playerCursor.goToPosition({0, 0});
}
else {
if (this->playerCursor.movedLeft()) {
this->settings->decreaseDistribution(this->playerCursor.getPosition().y);
}
if (this->playerCursor.movedRight()) {
this->settings->increaseDistribution(this->playerCursor.getPosition().y);
}
}
}
if (this->escReleased) {
this->settings->confirmDistribution();
this->menuStack->pop();
}
}
void GameDistributionAppMenu::drawFrame() const {
this->renderWindow->clear(sf::Color(200, 200, 200));
const Menu& menu = this->settings->getMenu();
sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2);
text.setFillColor(sf::Color(0, 0, 0));
text.setOutlineColor(sf::Color(255, 255, 255));
this->placeTitle(text, {}, "DISTRIBUTION SETTINGS", 5.f, {});
const DistributionMode distributionMode = this->settings->getMenu().readPiecesList().getDistributionMode();
const std::vector<int>& distributions = this->settings->getDistributions();
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 1, 0, MAXIMUM_PIECES_SIZE - 3);
if (firstElem == 0) {
this->placeText(text, this->playerCursor, "< DISTRIBUTION MODE: " + getPiecesDistributionName(distributionMode) + " >", 5.f, 15.f, sf::Vector2u{0, 0});
}
else {
this->placeText(text, this->playerCursor, "< SIZE " + std::to_string(firstElem) + " PROBABILITY: " + std::to_string(distributions.at(firstElem)) + " >", 5.f, 15.f, sf::Vector2u{(unsigned int) firstElem, 0});
}
if (distributionMode != CUSTOM) {
text.setFillColor(sf::Color(100, 100, 100));
}
this->placeText(text, this->playerCursor, "< SIZE " + std::to_string(firstElem + 1) + " PROBABILITY: " + std::to_string(distributions.at(firstElem + 1)) + " >", 5.f, 25.f, sf::Vector2u{0, (unsigned int) firstElem + 1});
this->placeText(text, this->playerCursor, "< SIZE " + std::to_string(firstElem + 2) + " PROBABILITY: " + std::to_string(distributions.at(firstElem + 2)) + " >", 5.f, 35.f, sf::Vector2u{0, (unsigned int) firstElem + 2});
this->placeText(text, this->playerCursor, "< SIZE " + std::to_string(firstElem + 3) + " PROBABILITY: " + std::to_string(distributions.at(firstElem + 3)) + " >", 5.f, 45.f, sf::Vector2u{0, (unsigned int) firstElem + 3});
this->renderWindow->display();
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include "AppMenu.h"
#include "../PlayerCursor.h"
#include <stack>
#include <memory>
#include <SFML/Graphics.hpp>
class GameDistributionAppMenu : public AppMenu {
private:
PlayerCursor playerCursor;
public:
GameDistributionAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow);
void computeFrame() override;
void drawFrame() const override;
};

View File

@@ -1,6 +1,7 @@
#include "GamePiecesAppMenu.h" #include "GamePiecesAppMenu.h"
#include "AppMenu.h" #include "AppMenu.h"
#include "GameDistributionAppMenu.h"
#include "../PlayerCursor.h" #include "../PlayerCursor.h"
#include <stack> #include <stack>
@@ -10,19 +11,61 @@
GamePiecesAppMenu::GamePiecesAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) : GamePiecesAppMenu::GamePiecesAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
AppMenu(menuStack, settings, renderWindow), AppMenu(menuStack, settings, renderWindow),
playerCursor({1}) { playerCursor({1, 1}) {
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
this->playerCursor.addRow(i + 1, this->settings->getMenu().readPiecesList().getNumberOfPieces(i) + 4);
}
} }
void GamePiecesAppMenu::computeFrame() { void GamePiecesAppMenu::computeFrame() {
this->updateMetaBinds(); this->updateMetaBinds();
this->playerCursor.updatePosition(); this->playerCursor.updatePosition();
if (this->enterReleased) {
if (this->playerCursor.getPosition().y == 0) {
this->menuStack->push(std::make_shared<GameDistributionAppMenu>(this->menuStack, this->settings, this->renderWindow));
}
if (this->playerCursor.getPosition().y > 1) {
//TODO
}
}
if (this->escReleased) { if (this->escReleased) {
this->menuStack->pop(); if (this->playerCursor.getPosition().y == 1) {
//TODO
}
else {
this->menuStack->pop();
}
} }
} }
void GamePiecesAppMenu::drawFrame() const { void GamePiecesAppMenu::drawFrame() const {
this->renderWindow->clear(sf::Color(200, 200, 200));
sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2);
text.setFillColor(sf::Color(0, 0, 0));
text.setOutlineColor(sf::Color(255, 255, 255));
this->placeTitle(text, {}, "PIECES SELECT", 5.f, {});
if (this->playerCursor.getPosition().y == 0) {
this->placeText(text, this->playerCursor, "PIECES DISTRIBUTION", 5.f, 15.f, sf::Vector2u{0, 0});
// draw pieces line
this->drawRow(1, 35.f);
this->drawRow(2, 45.f);
}
else {
// draw pieces line
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 2, 1, MAXIMUM_PIECES_SIZE - 1);
this->drawRow(firstElem, 25.f);
this->drawRow(firstElem, 35.f);
this->drawRow(firstElem, 45.f);
}
this->renderWindow->display();
}
void GamePiecesAppMenu::drawRow(int piecesSize, float yPos) const {
//TODO
} }

View File

@@ -18,4 +18,7 @@ class GamePiecesAppMenu : public AppMenu {
void computeFrame() override; void computeFrame() override;
void drawFrame() const override; void drawFrame() const override;
private:
void drawRow(int piecesSize, float yPos) const;
}; };

View File

@@ -69,18 +69,13 @@ void Settings::loadSettingsFromFile() {
// piece distribution // piece distribution
settingsFile.get(byte); settingsFile.get(byte);
this->menu.getPiecesList().setDistributionMode(PiecesDistributionMode(byte)); this->menu.getPiecesList().setDistributionMode(DistributionMode(byte));
this->distributions.clear(); this->distributions.clear();
this->distributions.push_back(0); this->distributions.push_back(0);
for (int i = 1; i <= 15; i++) { for (int i = 1; i <= 15; i++) {
if (byte == CUSTOM) { settingsFile.get(byte);
settingsFile.get(byte); this->distributions.push_back(byte);
this->distributions.push_back(i);
}
else {
this->distributions.push_back(1);
}
} }
this->confirmDistribution(); this->confirmDistribution();
@@ -143,11 +138,9 @@ void Settings::saveSettingsToFile() const {
byte = this->menu.readPiecesList().getDistributionMode(); byte = this->menu.readPiecesList().getDistributionMode();
settingsFile.write(&byte, 1); settingsFile.write(&byte, 1);
if (this->menu.readPiecesList().getDistributionMode() == CUSTOM) { for (int i = 1; i <= 15; i++) {
for (int i = 1; i <= 15; i++) { byte = this->distributions.at(i);
byte = this->distributions.at(i); settingsFile.write(&byte, 1);
settingsFile.write(&byte, 1);
}
} }
// selected pieces // selected pieces
@@ -256,10 +249,6 @@ void Settings::confirmSelectedPieces() {
} }
} }
bool Settings::setDistributionMode (PiecesDistributionMode distributionMode) {
return this->menu.getPiecesList().setDistributionMode(distributionMode);
}
bool Settings::increaseDistribution(int size) { bool Settings::increaseDistribution(int size) {
if (size < 1 || size > MAXIMUM_PIECES_SIZE) return false; if (size < 1 || size > MAXIMUM_PIECES_SIZE) return false;
@@ -313,3 +302,7 @@ int Settings::getStartTimerLength() const {
const std::vector<std::pair<PiecesType, int>>& Settings::getSelectedPieces() const { const std::vector<std::pair<PiecesType, int>>& Settings::getSelectedPieces() const {
return this->selectedPieces; return this->selectedPieces;
} }
const std::vector<int>& Settings::getDistributions() const {
return this->distributions;
}

View File

@@ -60,8 +60,6 @@ class Settings {
void confirmSelectedPieces(); void confirmSelectedPieces();
bool setDistributionMode (PiecesDistributionMode distributionMode);
bool increaseDistribution(int size); bool increaseDistribution(int size);
bool decreaseDistribution(int size); bool decreaseDistribution(int size);
@@ -81,4 +79,6 @@ class Settings {
int getStartTimerLength() const; int getStartTimerLength() const;
const std::vector<std::pair<PiecesType, int>>& getSelectedPieces() const; const std::vector<std::pair<PiecesType, int>>& getSelectedPieces() const;
const std::vector<int>& getDistributions() const;
}; };

View File

@@ -82,6 +82,10 @@ void resetSettingsFile() {
// piece distribution // piece distribution
byte = DEFAULT; byte = DEFAULT;
settingsFile.write(&byte, 1); settingsFile.write(&byte, 1);
for (int i = 1; i <= 15; i++) {
byte = 1;
settingsFile.write(&byte, 1);
}
// selected pieces // selected pieces
byte = ALL_PIECES; byte = ALL_PIECES;