This commit is contained in:
@@ -110,12 +110,13 @@ If for some reasons you wanna run the command line version (not updated):
|
|||||||
| 15 | 6849777 | 258s 219.666ms | 223s 386.329ms | 16s 483.426ms | 19392417 bytes |
|
| 15 | 6849777 | 258s 219.666ms | 223s 386.329ms | 16s 483.426ms | 19392417 bytes |
|
||||||
|
|
||||||
_File storing includes type checking and sorting all polyominoes before writing them to the file._
|
_File storing includes type checking and sorting all polyominoes before writing them to the file._
|
||||||
|
The files are compressed, they used to be about 5x as large.
|
||||||
If you want to know more details about the generation and storage of polyominoes, [check the documentation](/doc/)!
|
If you want to know more details about the generation and storage of polyominoes, [check the documentation](/doc/)!
|
||||||
|
|
||||||
Run it yourself by typing:
|
Run it yourself by typing:
|
||||||
``xmake f -m release``
|
``xmake f -m release``
|
||||||
``xmake build bmark``
|
``xmake build bmark``
|
||||||
``xmake run bmark``
|
``xmake run bmark``
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
@@ -125,4 +126,5 @@ Font used: [Press Start](https://www.zone38.net/font/#pressstart).
|
|||||||
Inspired by other modern stacker games such as Techmino, jstris, tetr.io, etc.
|
Inspired by other modern stacker games such as Techmino, jstris, tetr.io, etc.
|
||||||
This game isn't affiliated with any of them.
|
This game isn't affiliated with any of them.
|
||||||
|
|
||||||
Special thanks to my friend [Simon](https://git.ale-pri.com/Persson-dev) who did most of the outside stuff (github actions, files compression, asset manager, xmake).
|
Special thanks to my friend [Simon](https://git.ale-pri.com/Persson-dev) who did most of the outside stuff (github actions, files compression, asset manager, xmake).
|
||||||
|
All the code in src/Common and src/Utils comes from him.
|
||||||
|
|||||||
87
src/Benchmark/main.cpp
Normal file
87
src/Benchmark/main.cpp
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#include "../Pieces/Generator.h"
|
||||||
|
#include "../Pieces/PiecesFiles.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
static const int BENCHMARK_PIECES_SIZE = 15;
|
||||||
|
|
||||||
|
void benchmarking(int min_size, int max_size);
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
std::srand(std::time(NULL));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cout << "IMPORTANT: You are currently in debug mode, debug mode has lowest optimization settings and thus yields worse benchmarking results, to switch to release mode, type 'xmake f -m debug'." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
benchmarking(1, BENCHMARK_PIECES_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void benchmarking(int min_size, int max_size) {
|
||||||
|
using std::chrono::high_resolution_clock;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::milliseconds;
|
||||||
|
|
||||||
|
std::cout << "| n | Number | Generation | File storing | File retrieving | File size |" << std::endl;
|
||||||
|
std::cout << "| -: | -: | :-: | :-: | :-: | -: |" << std::endl;
|
||||||
|
|
||||||
|
Generator gen;
|
||||||
|
PiecesFiles pf;
|
||||||
|
|
||||||
|
for (int i = min_size; i <= max_size; i++) {
|
||||||
|
std::cout << "| " << i;
|
||||||
|
|
||||||
|
auto t1 = high_resolution_clock::now();
|
||||||
|
std::vector<Polyomino> polyominoes = gen.generatePolyominoes(i);
|
||||||
|
auto t2 = high_resolution_clock::now();
|
||||||
|
duration<double, std::milli> ms_double = t2 - t1;
|
||||||
|
std::cout << " | " << polyominoes.size();
|
||||||
|
std::flush(std::cout);
|
||||||
|
std::cout << " | " << (int) ms_double.count() / 1000 << "s " << std::fmod(ms_double.count(), 1000) << "ms ";
|
||||||
|
std::flush(std::cout);
|
||||||
|
|
||||||
|
t1 = high_resolution_clock::now();
|
||||||
|
pf.savePieces(i, polyominoes);
|
||||||
|
t2 = high_resolution_clock::now();
|
||||||
|
ms_double = t2 - t1;
|
||||||
|
std::cout << " | " << (int) ms_double.count() / 1000 << "s " << std::fmod(ms_double.count(), 1000) << "ms ";
|
||||||
|
std::flush(std::cout);
|
||||||
|
|
||||||
|
polyominoes.clear();
|
||||||
|
polyominoes.shrink_to_fit();
|
||||||
|
|
||||||
|
std::vector<Piece> pieces;
|
||||||
|
std::vector<int> convexPieces;
|
||||||
|
std::vector<int> holelessPieces;
|
||||||
|
std::vector<int> otherPieces;
|
||||||
|
|
||||||
|
t1 = high_resolution_clock::now();
|
||||||
|
pf.loadPieces(i, pieces, convexPieces, holelessPieces, otherPieces);
|
||||||
|
t2 = high_resolution_clock::now();
|
||||||
|
ms_double = t2 - t1;
|
||||||
|
std::cout << " | " << (int) ms_double.count() / 1000 << "s " << std::fmod(ms_double.count(), 1000) << "ms ";
|
||||||
|
std::flush(std::cout);
|
||||||
|
|
||||||
|
pieces.clear();
|
||||||
|
pieces.shrink_to_fit();
|
||||||
|
convexPieces.clear();
|
||||||
|
convexPieces.shrink_to_fit();
|
||||||
|
holelessPieces.clear();
|
||||||
|
holelessPieces.shrink_to_fit();
|
||||||
|
otherPieces.clear();
|
||||||
|
otherPieces.shrink_to_fit();
|
||||||
|
|
||||||
|
std::string filePath;
|
||||||
|
pf.getFilePath(i, filePath);
|
||||||
|
int fileSize = std::filesystem::file_size(filePath);
|
||||||
|
std::cout << " | " << fileSize << " bytes |" << std::endl;
|
||||||
|
std::flush(std::cout);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ GameDistributionAppMenu::GameDistributionAppMenu(std::shared_ptr<MenuStack> menu
|
|||||||
AppMenu(menuStack, settings, renderWindow),
|
AppMenu(menuStack, settings, renderWindow),
|
||||||
playerCursor({1}) {
|
playerCursor({1}) {
|
||||||
|
|
||||||
for (int i = 1; i <= this->settings->getMaximumPiecesSize(); i++) {
|
for (int i = 1; i <= this->settings->getLoadablePiecesSize(); i++) {
|
||||||
this->playerCursor.addRow(i, 1);
|
this->playerCursor.addRow(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ void GameDistributionAppMenu::drawFrame() const {
|
|||||||
const DistributionMode distributionMode = this->settings->getMenu().readPiecesList().getDistributionMode();
|
const DistributionMode distributionMode = this->settings->getMenu().readPiecesList().getDistributionMode();
|
||||||
const std::vector<int>& distributions = this->settings->getDistributions();
|
const std::vector<int>& distributions = this->settings->getDistributions();
|
||||||
|
|
||||||
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 1, 0, this->settings->getMaximumPiecesSize() - 3);
|
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 1, 0, this->settings->getLoadablePiecesSize() - 3);
|
||||||
if (firstElem == 0) {
|
if (firstElem == 0) {
|
||||||
this->placeText(text, this->playerCursor, "< DISTRIBUTION MODE: " + getPiecesDistributionName(distributionMode) + " >", 5.f, 15.f, sf::Vector2u{0, 0});
|
this->placeText(text, this->playerCursor, "< DISTRIBUTION MODE: " + getPiecesDistributionName(distributionMode) + " >", 5.f, 15.f, sf::Vector2u{0, 0});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ GamePiecesAppMenu::GamePiecesAppMenu(std::shared_ptr<MenuStack> menuStack, std::
|
|||||||
AppMenu(menuStack, settings, renderWindow),
|
AppMenu(menuStack, settings, renderWindow),
|
||||||
playerCursor({1, (unsigned int) this->settings->getSelectedPieces().size() + 1u}) {
|
playerCursor({1, (unsigned int) this->settings->getSelectedPieces().size() + 1u}) {
|
||||||
|
|
||||||
for (int i = 1; i <= this->settings->getMaximumPiecesSize(); i++) {
|
for (int i = 1; i <= this->settings->getLoadablePiecesSize(); i++) {
|
||||||
this->playerCursor.addRow(i + 1, this->settings->getMenu().readPiecesList().getNumberOfPieces(i) + 4);
|
this->playerCursor.addRow(i + 1, this->settings->getMenu().readPiecesList().getNumberOfPieces(i) + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->settings->getMaximumPiecesSize() < MAXIMUM_PIECES_SIZE) {
|
if (this->settings->getLoadablePiecesSize() < MAXIMUM_PIECES_SIZE) {
|
||||||
this->playerCursor.addRow(this->settings->getMaximumPiecesSize() + 2, 1);
|
this->playerCursor.addRow(this->settings->getLoadablePiecesSize() + 2, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,8 +35,8 @@ void GamePiecesAppMenu::computeFrame() {
|
|||||||
this->menuStack->push(std::make_shared<GameDistributionAppMenu>(this->menuStack, this->settings, this->renderWindow));
|
this->menuStack->push(std::make_shared<GameDistributionAppMenu>(this->menuStack, this->settings, this->renderWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->playerCursor.getPosition().y == (this->settings->getMaximumPiecesSize() + 2)) {
|
if (this->playerCursor.getPosition().y == (this->settings->getLoadablePiecesSize() + 2)) {
|
||||||
int newMaxSize = this->settings->getMaximumPiecesSize() + 1;
|
int newMaxSize = this->settings->getLoadablePiecesSize() + 1;
|
||||||
this->settings->loadPieces(newMaxSize);
|
this->settings->loadPieces(newMaxSize);
|
||||||
|
|
||||||
this->playerCursor.removeRow(newMaxSize + 1);
|
this->playerCursor.removeRow(newMaxSize + 1);
|
||||||
@@ -95,8 +95,8 @@ void GamePiecesAppMenu::drawFrame() const {
|
|||||||
this->drawSelectedPiecesRow(15.f);
|
this->drawSelectedPiecesRow(15.f);
|
||||||
|
|
||||||
bool drawFromFirstElem = (this->playerCursor.getPosition().y == 1);
|
bool drawFromFirstElem = (this->playerCursor.getPosition().y == 1);
|
||||||
bool addExtraLine = (this->settings->getMaximumPiecesSize() < MAXIMUM_PIECES_SIZE);
|
bool addExtraLine = (this->settings->getLoadablePiecesSize() < MAXIMUM_PIECES_SIZE);
|
||||||
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 2, 1, this->settings->getMaximumPiecesSize() - 2 + (addExtraLine ? 1 : 0));
|
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 2, 1, this->settings->getLoadablePiecesSize() - 2 + (addExtraLine ? 1 : 0));
|
||||||
this->drawRow(firstElem, 25.f, drawFromFirstElem);
|
this->drawRow(firstElem, 25.f, drawFromFirstElem);
|
||||||
this->drawRow(firstElem + 1, 35.f, drawFromFirstElem);
|
this->drawRow(firstElem + 1, 35.f, drawFromFirstElem);
|
||||||
this->drawRow(firstElem + 2, 45.f, drawFromFirstElem);
|
this->drawRow(firstElem + 2, 45.f, drawFromFirstElem);
|
||||||
@@ -130,7 +130,7 @@ void GamePiecesAppMenu::drawSelectedPiecesRow(float yPos) const {
|
|||||||
|
|
||||||
int pieceSize = getSizeOfPieces(pieceType);
|
int pieceSize = getSizeOfPieces(pieceType);
|
||||||
if (pieceSize > 0) {
|
if (pieceSize > 0) {
|
||||||
if (!(pieceSize > this->settings->getMaximumPiecesSize())) {
|
if (!(pieceSize > this->settings->getLoadablePiecesSize())) {
|
||||||
const Piece& piece = this->settings->getMenu().readPiecesList().lookAtPiece({pieceSize, value});
|
const Piece& piece = this->settings->getMenu().readPiecesList().lookAtPiece({pieceSize, value});
|
||||||
int cellSize = (8 * this->settings->getWindowSizeMultiplier()) / (piece.getLength());
|
int cellSize = (8 * this->settings->getWindowSizeMultiplier()) / (piece.getLength());
|
||||||
sf::FloatRect piecePosition(sf::Vector2f(xProgress, yPos - 4.f) * (float) this->settings->getWindowSizeMultiplier(), sf::Vector2f(8 , 8) * (float) this->settings->getWindowSizeMultiplier());
|
sf::FloatRect piecePosition(sf::Vector2f(xProgress, yPos - 4.f) * (float) this->settings->getWindowSizeMultiplier(), sf::Vector2f(8 , 8) * (float) this->settings->getWindowSizeMultiplier());
|
||||||
@@ -143,7 +143,7 @@ void GamePiecesAppMenu::drawSelectedPiecesRow(float yPos) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!(value > this->settings->getMaximumPiecesSize())) {
|
if (!(value > this->settings->getLoadablePiecesSize())) {
|
||||||
this->placeText(text, {}, ((first) ? "" : " ") + getPiecesTypeName(pieceType) + "_" + std::to_string(value), xProgress, yPos, {});
|
this->placeText(text, {}, ((first) ? "" : " ") + getPiecesTypeName(pieceType) + "_" + std::to_string(value), xProgress, yPos, {});
|
||||||
xProgress += (1.f + (text.getGlobalBounds().size.x / this->settings->getWindowSizeMultiplier()));
|
xProgress += (1.f + (text.getGlobalBounds().size.x / this->settings->getWindowSizeMultiplier()));
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ void GamePiecesAppMenu::drawSelectedPiecesRow(float yPos) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GamePiecesAppMenu::drawRow(int piecesSize, float yPos, bool drawFromFirstElem) const {
|
void GamePiecesAppMenu::drawRow(int piecesSize, float yPos, bool drawFromFirstElem) const {
|
||||||
if (piecesSize > this->settings->getMaximumPiecesSize()) {
|
if (piecesSize > this->settings->getLoadablePiecesSize()) {
|
||||||
sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2);
|
sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2);
|
||||||
text.setOutlineThickness(this->settings->getWindowSizeMultiplier() / 2);
|
text.setOutlineThickness(this->settings->getWindowSizeMultiplier() / 2);
|
||||||
if (this->playerCursor.getPosition().y == (piecesSize + 1)) {
|
if (this->playerCursor.getPosition().y == (piecesSize + 1)) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ StartUpAppMenu::StartUpAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared
|
|||||||
AppMenu(menuStack, settings, renderWindow),
|
AppMenu(menuStack, settings, renderWindow),
|
||||||
playerCursor({MAXIMUM_PIECES_SIZE + 1}) {
|
playerCursor({MAXIMUM_PIECES_SIZE + 1}) {
|
||||||
|
|
||||||
this->playerCursor.goToPosition({(unsigned int) std::clamp(this->settings->getMaximumPiecesSize(), MINIMUM_PIECES_SIZE, MAXIMUM_PIECES_SIZE), 0u});
|
this->playerCursor.goToPosition({(unsigned int) std::clamp(this->settings->getLoadablePiecesSize(), MINIMUM_PIECES_SIZE, MAXIMUM_PIECES_SIZE), 0u});
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartUpAppMenu::computeFrame() {
|
void StartUpAppMenu::computeFrame() {
|
||||||
|
|||||||
@@ -27,41 +27,41 @@ Settings::Settings(bool loadPieces) {
|
|||||||
this->loadSettingsFromFile(loadPieces, {});
|
this->loadSettingsFromFile(loadPieces, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::loadPieces(int maximumPiecesSizeRequest) {
|
void Settings::loadPieces(int loadablePiecesSizeRequest) {
|
||||||
if (maximumPiecesSizeRequest < MINIMUM_PIECES_SIZE) {
|
if (loadablePiecesSizeRequest < MINIMUM_PIECES_SIZE) {
|
||||||
maximumPiecesSizeRequest = MINIMUM_PIECES_SIZE;
|
loadablePiecesSizeRequest = MINIMUM_PIECES_SIZE;
|
||||||
}
|
}
|
||||||
else if (maximumPiecesSizeRequest > MAXIMUM_PIECES_SIZE) {
|
else if (loadablePiecesSizeRequest > MAXIMUM_PIECES_SIZE) {
|
||||||
maximumPiecesSizeRequest = MAXIMUM_PIECES_SIZE;
|
loadablePiecesSizeRequest = MAXIMUM_PIECES_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool succeeded = true;
|
bool succeeded = true;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while (succeeded && (i <= maximumPiecesSizeRequest)) {
|
while (succeeded && (i <= loadablePiecesSizeRequest)) {
|
||||||
succeeded = this->menu.getPiecesList().loadPieces(i);
|
succeeded = this->menu.getPiecesList().loadPieces(i);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (succeeded) {
|
if (succeeded) {
|
||||||
this->maximumPiecesSize = maximumPiecesSizeRequest;
|
this->loadablePiecesSize = loadablePiecesSizeRequest;
|
||||||
}
|
}
|
||||||
this->loadedPieces = succeeded;
|
this->loadedPieces = succeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::loadSettingsFromFile(bool loadPieces, std::optional<int> maximumPiecesSizeRequest) {
|
void Settings::loadSettingsFromFile(bool loadPieces, std::optional<int> loadablePiecesSizeRequest) {
|
||||||
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
|
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
|
||||||
char byte;
|
char byte;
|
||||||
|
|
||||||
// file format version
|
// file format version
|
||||||
settingsFile.get(byte);
|
settingsFile.get(byte);
|
||||||
|
|
||||||
// maximum pieces size
|
// loadable pieces size
|
||||||
settingsFile.get(byte);
|
settingsFile.get(byte);
|
||||||
this->maximumPiecesSize = byte;
|
this->loadablePiecesSize = byte;
|
||||||
|
|
||||||
if (loadPieces) {
|
if (loadPieces) {
|
||||||
if (maximumPiecesSizeRequest.has_value()) {
|
if (loadablePiecesSizeRequest.has_value()) {
|
||||||
this->loadPieces(maximumPiecesSizeRequest.value());
|
this->loadPieces(loadablePiecesSizeRequest.value());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this->loadPieces(byte);
|
this->loadPieces(byte);
|
||||||
@@ -165,8 +165,8 @@ void Settings::saveSettingsToFile() const {
|
|||||||
byte = CURRENT_FILE_FORMAT_VERSION;
|
byte = CURRENT_FILE_FORMAT_VERSION;
|
||||||
settingsFile.write(&byte, 1);
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
// maximum pieces size
|
// loadable pieces size
|
||||||
byte = this->maximumPiecesSize;
|
byte = this->loadablePiecesSize;
|
||||||
settingsFile.write(&byte, 1);
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
// keybind layout
|
// keybind layout
|
||||||
@@ -321,7 +321,7 @@ void Settings::confirmSelectedPieces() {
|
|||||||
int size = getSizeOfPieces(type);
|
int size = getSizeOfPieces(type);
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
if (!(value > this->maximumPiecesSize)) {
|
if (!(value > this->loadablePiecesSize)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CONVEX_PIECES : {this->menu.getPiecesList().selectConvexPieces(value); break;}
|
case CONVEX_PIECES : {this->menu.getPiecesList().selectConvexPieces(value); break;}
|
||||||
case HOLELESS_PIECES : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
|
case HOLELESS_PIECES : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
|
||||||
@@ -332,7 +332,7 @@ void Settings::confirmSelectedPieces() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!(getSizeOfPieces(type) > this->maximumPiecesSize)) {
|
if (!(getSizeOfPieces(type) > this->loadablePiecesSize)) {
|
||||||
this->menu.getPiecesList().selectPiece(size, value);
|
this->menu.getPiecesList().selectPiece(size, value);
|
||||||
selectedNone = false;
|
selectedNone = false;
|
||||||
}
|
}
|
||||||
@@ -347,7 +347,7 @@ void Settings::confirmSelectedPieces() {
|
|||||||
|
|
||||||
bool Settings::increaseDistribution(int size) {
|
bool Settings::increaseDistribution(int size) {
|
||||||
if (!this->loadedPieces) return false;
|
if (!this->loadedPieces) return false;
|
||||||
if (size < 1 || size > this->maximumPiecesSize) return false;
|
if (size < 1 || size > this->loadablePiecesSize) return false;
|
||||||
|
|
||||||
if (this->distributions.at(size) < DISTRIBUTION_MAX) {
|
if (this->distributions.at(size) < DISTRIBUTION_MAX) {
|
||||||
this->distributions.at(size)++;
|
this->distributions.at(size)++;
|
||||||
@@ -358,7 +358,7 @@ bool Settings::increaseDistribution(int size) {
|
|||||||
|
|
||||||
bool Settings::decreaseDistribution(int size) {
|
bool Settings::decreaseDistribution(int size) {
|
||||||
if (!this->loadedPieces) return false;
|
if (!this->loadedPieces) return false;
|
||||||
if (size < 1 || size > this->maximumPiecesSize) return false;
|
if (size < 1 || size > this->loadablePiecesSize) return false;
|
||||||
|
|
||||||
if (this->distributions.at(size) > 0) {
|
if (this->distributions.at(size) > 0) {
|
||||||
this->distributions.at(size)--;
|
this->distributions.at(size)--;
|
||||||
@@ -383,8 +383,8 @@ Keybinds& Settings::getKeybinds() {
|
|||||||
return this->keybinds.at(this->chosenKeybinds);
|
return this->keybinds.at(this->chosenKeybinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Settings::getMaximumPiecesSize() const {
|
int Settings::getLoadablePiecesSize() const {
|
||||||
return this->maximumPiecesSize;
|
return this->loadablePiecesSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::hasLoadedPieces() const {
|
bool Settings::hasLoadedPieces() const {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ static const std::pair<PiecesType, int> DEFAULT_SELECTION = {ALL_PIECES, MINIMUM
|
|||||||
class Settings {
|
class Settings {
|
||||||
private:
|
private:
|
||||||
Menu menu;
|
Menu menu;
|
||||||
int maximumPiecesSize;
|
int loadablePiecesSize;
|
||||||
bool loadedPieces;
|
bool loadedPieces;
|
||||||
std::vector<Keybinds> keybinds;
|
std::vector<Keybinds> keybinds;
|
||||||
int chosenKeybinds;
|
int chosenKeybinds;
|
||||||
@@ -42,9 +42,9 @@ class Settings {
|
|||||||
public:
|
public:
|
||||||
Settings(bool loadPieces);
|
Settings(bool loadPieces);
|
||||||
|
|
||||||
void loadPieces(int maximumPiecesSizeRequest);
|
void loadPieces(int loadablePiecesSizeRequest);
|
||||||
|
|
||||||
void loadSettingsFromFile(bool loadPieces, std::optional<int> maximumPiecesSizeRequest);
|
void loadSettingsFromFile(bool loadPieces, std::optional<int> loadablePiecesSizeRequest);
|
||||||
|
|
||||||
void saveSettingsToFile() const;
|
void saveSettingsToFile() const;
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ class Settings {
|
|||||||
|
|
||||||
Keybinds& getKeybinds();
|
Keybinds& getKeybinds();
|
||||||
|
|
||||||
int getMaximumPiecesSize() const;
|
int getLoadablePiecesSize() const;
|
||||||
|
|
||||||
bool hasLoadedPieces() const;
|
bool hasLoadedPieces() const;
|
||||||
|
|
||||||
|
|||||||
@@ -4,42 +4,69 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
[[nodiscard]] bool resetSettingsFile();
|
||||||
void resetSettingsFile();
|
[[nodiscard]] bool resetKeybindFile(int layout);
|
||||||
void resetKeybindFile(int layout);
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
std::srand(std::time(NULL));
|
std::srand(std::time(NULL));
|
||||||
|
|
||||||
|
bool everythingIsOK = true;
|
||||||
|
|
||||||
|
// CHECK PIECES FILES
|
||||||
|
|
||||||
PiecesFiles pf;
|
PiecesFiles pf;
|
||||||
|
bool warned = false;
|
||||||
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||||
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
std::cout << "IMPORTANT: You are currently in release mode, if you do not wish to generate big pieces (can take several minutes), type 'xmake f -m debug'." << std::endl;
|
if (!warned && i > DEBUG_PIECES_SIZE) {
|
||||||
|
std::cout << "IMPORTANT: You are currently in release mode, if you do not wish to generate big pieces (can take several minutes), type 'xmake f -m debug'." << std::endl;
|
||||||
|
warned = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::cout << "INFO: Pieces files for size " << i << " not found, generating..." << std::endl;
|
std::cout << "INFO: Pieces files for size " << i << " not found, generating..." << std::endl;
|
||||||
pf.savePieces(i);
|
everythingIsOK &= pf.savePieces(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cout << "IMPORTANT: You are currently in debug mode, if you wish to use bigger pieces, type 'xmake f -m release'." << std::endl;
|
std::cout << "IMPORTANT: You are currently in debug mode, if you wish to use bigger pieces, type 'xmake f -m release'." << std::endl;
|
||||||
|
|
||||||
bool everythingGenerated = true;
|
bool releasePiecesGenerated = true;
|
||||||
for (int i = DEBUG_PIECES_SIZE; i <= RELEASE_PIECES_SIZE; i++) {
|
for (int i = DEBUG_PIECES_SIZE + 1; i <= RELEASE_PIECES_SIZE; i++) {
|
||||||
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
||||||
everythingGenerated = false;
|
releasePiecesGenerated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!everythingGenerated) {
|
if (!releasePiecesGenerated) {
|
||||||
std::cout << "NOTE: You do not have all pieces generated, generating can take several minutes." << std::endl;
|
std::cout << "NOTE: You do not have all pieces generated, generating can take several minutes." << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool everythingGenerated = true;
|
||||||
|
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||||
|
std::string filePath = "data/pieces/" + std::to_string(i) + "minos.bin";
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(filePath)) {
|
||||||
|
std::cout << "ERROR: Could not open file " + filePath << std::endl;
|
||||||
|
everythingIsOK &= false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK CONFIG FILES
|
||||||
|
|
||||||
if (!std::filesystem::exists("data/config/settings.bin")) {
|
if (!std::filesystem::exists("data/config/settings.bin")) {
|
||||||
std::cout << "INFO: Settings file not found, generating..." << std::endl;
|
std::cout << "INFO: Settings file not found, generating..." << std::endl;
|
||||||
resetSettingsFile();
|
everythingIsOK &= resetSettingsFile();
|
||||||
|
|
||||||
|
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
|
||||||
|
if (!std::filesystem::exists("data/config/keybinds/layout" + std::to_string(i) + ".bin")) {
|
||||||
|
std::cout << "INFO: Keybind file number " << (i + 1) << "/" << NUMBER_OF_KEYBINDS << " not found, generating..." << std::endl;
|
||||||
|
everythingIsOK &= resetKeybindFile(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
|
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
|
||||||
@@ -48,42 +75,49 @@ int main() {
|
|||||||
settingsFile.get(byte);
|
settingsFile.get(byte);
|
||||||
if ((unsigned char) byte < CURRENT_FILE_FORMAT_VERSION) {
|
if ((unsigned char) byte < CURRENT_FILE_FORMAT_VERSION) {
|
||||||
std::cout << "INFO: Files format changed, regenerating..." << std::endl;
|
std::cout << "INFO: Files format changed, regenerating..." << std::endl;
|
||||||
resetSettingsFile();
|
everythingIsOK &= resetSettingsFile();
|
||||||
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
|
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
|
||||||
resetKeybindFile(i);
|
everythingIsOK &= resetKeybindFile(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
|
// LAUNCH APP
|
||||||
if (!std::filesystem::exists("data/config/keybinds/layout" + std::to_string(i) + ".bin")) {
|
|
||||||
std::cout << "INFO: Keybind file n°" << (i + 1) << "/" << NUMBER_OF_KEYBINDS << " not found, generating..." << std::endl;
|
|
||||||
resetKeybindFile(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphApp UI;
|
if (everythingIsOK) {
|
||||||
UI.run();
|
GraphApp UI;
|
||||||
|
UI.run();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "ERROR: The game could not launch properly." << std::endl;
|
||||||
|
std::cout << "Press enter to quit. ";
|
||||||
|
std::cin.get();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void resetSettingsFile() {
|
bool resetSettingsFile() {
|
||||||
if (!std::filesystem::exists("data/config")) {
|
if (!std::filesystem::exists("data/config")) {
|
||||||
std::filesystem::create_directories("data/config");
|
std::filesystem::create_directories("data/config");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ofstream settingsFile("data/config/settings.bin", std::ios::trunc | std::ios::binary);
|
std::string filePath ="data/config/settings.bin";
|
||||||
char byte;
|
std::ofstream settingsFile(filePath, std::ios::trunc | std::ios::binary);
|
||||||
|
if (!settingsFile.good()) {
|
||||||
|
std::cerr << "ERROR: Could not open file " + filePath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char byte;
|
||||||
Menu menu;
|
Menu menu;
|
||||||
|
|
||||||
// file format version
|
// file format version
|
||||||
byte = CURRENT_FILE_FORMAT_VERSION;
|
byte = CURRENT_FILE_FORMAT_VERSION;
|
||||||
settingsFile.write(&byte, 1);
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
// maximum pieces size
|
// loadable pieces size
|
||||||
byte = MINIMUM_PIECES_SIZE;
|
byte = MINIMUM_PIECES_SIZE;
|
||||||
settingsFile.write(&byte, 1);
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
@@ -132,16 +166,35 @@ void resetSettingsFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// selected pieces
|
// selected pieces
|
||||||
byte = ALL_PIECES;
|
byte = DEFAULT_SELECTION.first;
|
||||||
settingsFile.write(&byte, 1);
|
settingsFile.write(&byte, 1);
|
||||||
byte = 4;
|
byte = DEFAULT_SELECTION.second;
|
||||||
settingsFile.write(&byte, 1);
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetKeybindFile(int layout) {
|
bool resetKeybindFile(int layout) {
|
||||||
if (layout < 0 || layout > 4) return;
|
if (layout < 0 || layout > NUMBER_OF_KEYBINDS) {
|
||||||
|
std::cerr << "ERROR: Trying to create keybind layout number " << layout << " which is outside of range (" << NUMBER_OF_KEYBINDS << ")." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::exists("data/config/keybinds")) {
|
||||||
|
std::filesystem::create_directories("data/config/keybinds");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string filePath = "data/config/keybinds/layout" + std::to_string(layout) + ".bin";
|
||||||
|
std::ofstream layoutFile(filePath, std::ios::trunc | std::ios::binary);
|
||||||
|
if (!layoutFile.good()) {
|
||||||
|
std::cerr << "ERROR: Could not open file " + filePath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout == NUMBER_OF_KEYBINDS) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::ofstream layoutFile("data/config/keybinds/layout" + std::to_string(layout) + ".bin", std::ios::trunc | std::ios::binary);
|
|
||||||
std::map<Action, sfKey> keybinds;
|
std::map<Action, sfKey> keybinds;
|
||||||
|
|
||||||
if (layout != 4) {
|
if (layout != 4) {
|
||||||
@@ -207,4 +260,6 @@ void resetKeybindFile(int layout) {
|
|||||||
byte = 0xFF;
|
byte = 0xFF;
|
||||||
layoutFile.write(&byte, 1);
|
layoutFile.write(&byte, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,38 +7,35 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
static const int MAXIMUM_PIECES_SIZE = 10;
|
static const int MAXIMUM_PIECES_SIZE = 10;
|
||||||
static const int BENCHMARK_PIECES_SIZE = 15;
|
|
||||||
|
|
||||||
|
|
||||||
void testGeneratorForAllSizes(int max_size);
|
void testGeneratorForAllSizes(int max_size);
|
||||||
void testGeneratorForOneSize(int size);
|
void testGeneratorForOneSize(int size);
|
||||||
void printPiecesByTypesForOneSize(int size);
|
void printPiecesByTypesForOneSize(int size);
|
||||||
void readStatsFromFilesForAllSizes(int max_size);
|
void readStatsFromFilesForAllSizes(int max_size);
|
||||||
|
|
||||||
void benchmarking(int min_size, int max_size);
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
std::srand(std::time(NULL));
|
std::srand(std::time(NULL));
|
||||||
|
|
||||||
#ifdef BENCHMARK
|
// CHECK PIECES FILES
|
||||||
#ifdef DEBUG
|
|
||||||
std::cout << "IMPORTANT: You are currently in debug mode, debug mode has lowest optimization settings and thus yields worse benchmarking results, to switch to release mode, type 'xmake f -m debug'." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
benchmarking(1, BENCHMARK_PIECES_SIZE);
|
PiecesFiles pf;
|
||||||
#else
|
bool warned = false;
|
||||||
PiecesFiles pf;
|
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||||
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
||||||
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
if (!warned) {
|
||||||
std::cout << "INFO: Pieces files for size " << i << " not found, generating..." << std::endl;
|
std::cout << "INFO: Pieces files for size " << i << " not found, generating..." << std::endl;
|
||||||
pf.savePieces(i);
|
warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pf.savePieces(i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextApp UI;
|
// LAUNCH APP
|
||||||
UI.run();
|
|
||||||
#endif
|
TextApp UI;
|
||||||
|
UI.run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -119,66 +116,3 @@ void readStatsFromFilesForAllSizes(int max_size) {
|
|||||||
std::cout << "Others " << i << "-minos : " << otherPieces.size() << std::endl;
|
std::cout << "Others " << i << "-minos : " << otherPieces.size() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void benchmarking(int min_size, int max_size) {
|
|
||||||
using std::chrono::high_resolution_clock;
|
|
||||||
using std::chrono::duration_cast;
|
|
||||||
using std::chrono::duration;
|
|
||||||
using std::chrono::milliseconds;
|
|
||||||
|
|
||||||
std::cout << "| n | Number | Generation | File storing | File retrieving | File size |" << std::endl;
|
|
||||||
std::cout << "| -: | -: | :-: | :-: | :-: | -: |" << std::endl;
|
|
||||||
|
|
||||||
Generator gen;
|
|
||||||
PiecesFiles pf;
|
|
||||||
|
|
||||||
for (int i = min_size; i <= max_size; i++) {
|
|
||||||
std::cout << "| " << i;
|
|
||||||
|
|
||||||
auto t1 = high_resolution_clock::now();
|
|
||||||
std::vector<Polyomino> polyominoes = gen.generatePolyominoes(i);
|
|
||||||
auto t2 = high_resolution_clock::now();
|
|
||||||
duration<double, std::milli> ms_double = t2 - t1;
|
|
||||||
std::cout << " | " << polyominoes.size();
|
|
||||||
std::flush(std::cout);
|
|
||||||
std::cout << " | " << (int) ms_double.count() / 1000 << "s " << std::fmod(ms_double.count(), 1000) << "ms ";
|
|
||||||
std::flush(std::cout);
|
|
||||||
|
|
||||||
t1 = high_resolution_clock::now();
|
|
||||||
pf.savePieces(i, polyominoes);
|
|
||||||
t2 = high_resolution_clock::now();
|
|
||||||
ms_double = t2 - t1;
|
|
||||||
std::cout << " | " << (int) ms_double.count() / 1000 << "s " << std::fmod(ms_double.count(), 1000) << "ms ";
|
|
||||||
std::flush(std::cout);
|
|
||||||
|
|
||||||
polyominoes.clear();
|
|
||||||
polyominoes.shrink_to_fit();
|
|
||||||
|
|
||||||
std::vector<Piece> pieces;
|
|
||||||
std::vector<int> convexPieces;
|
|
||||||
std::vector<int> holelessPieces;
|
|
||||||
std::vector<int> otherPieces;
|
|
||||||
|
|
||||||
t1 = high_resolution_clock::now();
|
|
||||||
pf.loadPieces(i, pieces, convexPieces, holelessPieces, otherPieces);
|
|
||||||
t2 = high_resolution_clock::now();
|
|
||||||
ms_double = t2 - t1;
|
|
||||||
std::cout << " | " << (int) ms_double.count() / 1000 << "s " << std::fmod(ms_double.count(), 1000) << "ms ";
|
|
||||||
std::flush(std::cout);
|
|
||||||
|
|
||||||
pieces.clear();
|
|
||||||
pieces.shrink_to_fit();
|
|
||||||
convexPieces.clear();
|
|
||||||
convexPieces.shrink_to_fit();
|
|
||||||
holelessPieces.clear();
|
|
||||||
holelessPieces.shrink_to_fit();
|
|
||||||
otherPieces.clear();
|
|
||||||
otherPieces.shrink_to_fit();
|
|
||||||
|
|
||||||
std::string filePath;
|
|
||||||
pf.getFilePath(i, filePath);
|
|
||||||
int fileSize = std::filesystem::file_size(filePath);
|
|
||||||
std::cout << " | " << fileSize << " bytes |" << std::endl;
|
|
||||||
std::flush(std::cout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ target("text")
|
|||||||
target("bmark")
|
target("bmark")
|
||||||
set_default(false)
|
set_default(false)
|
||||||
set_kind("binary")
|
set_kind("binary")
|
||||||
add_files("./src/TextUI/*.cpp")
|
add_files("./src/Benchmark/*.cpp")
|
||||||
add_deps("core")
|
add_deps("core")
|
||||||
add_defines("BENCHMARK")
|
|
||||||
|
|
||||||
target("graph")
|
target("graph")
|
||||||
set_default(true)
|
set_default(true)
|
||||||
|
|||||||
Reference in New Issue
Block a user