Compare commits
4 Commits
compress
...
e676cd19f6
| Author | SHA1 | Date | |
|---|---|---|---|
| e676cd19f6 | |||
| 8342bf3969 | |||
| 34d781fcfe | |||
| b17a40fda5 |
41
README.md
41
README.md
@@ -79,9 +79,10 @@ To switch between debug and release mode:
|
||||
``xmake f -m debug``
|
||||
``xmake f -m release``
|
||||
|
||||
If for some reasons you wanna run the command line version (not updated):
|
||||
If for some reasons you wanna run the command line version:
|
||||
``xmake build text``
|
||||
``xmake run text``
|
||||
``xmake run text``
|
||||
The command line version is **not** updated.
|
||||
|
||||
### Package the project
|
||||
|
||||
@@ -93,29 +94,30 @@ If for some reasons you wanna run the command line version (not updated):
|
||||
|
||||
| n | Number | Generation | File storing | File retrieving | File size |
|
||||
| -: | -: | :-: | :-: | :-: | -: |
|
||||
| 1 | 1 | 0s 0.005622ms | 0s 0.750955ms | 0s 0.014016ms | 2 bytes |
|
||||
| 2 | 1 | 0s 0.005758ms | 0s 0.181323ms | 0s 0.012256ms | 3 bytes |
|
||||
| 3 | 2 | 0s 0.017525ms | 0s 0.054497ms | 0s 0.006431ms | 8 bytes |
|
||||
| 4 | 7 | 0s 0.050554ms | 0s 0.067617ms | 0s 0.010984ms | 35 bytes |
|
||||
| 5 | 18 | 0s 0.191971ms | 0s 0.109905ms | 0s 0.021234ms | 108 bytes |
|
||||
| 6 | 60 | 0s 0.651757ms | 0s 0.327465ms | 0s 0.04558ms | 420 bytes |
|
||||
| 7 | 196 | 0s 3.38847ms | 0s 1.94434ms | 0s 0.258777ms | 1568 bytes |
|
||||
| 8 | 704 | 0s 22.7411ms | 0s 10.0103ms | 0s 1.34813ms | 6336 bytes |
|
||||
| 9 | 2500 | 0s 66.2949ms | 0s 20.6137ms | 0s 2.56374ms | 25000 bytes |
|
||||
| 10 | 9189 | 0s 194.764ms | 0s 84.5884ms | 0s 9.64467ms | 101079 bytes |
|
||||
| 11 | 33896 | 0s 759.182ms | 0s 378.494ms | 0s 44.1424ms | 406752 bytes |
|
||||
| 12 | 126759 | 2s 709.277ms | 1s 530.34ms | 0s 155ms | 1647867 bytes |
|
||||
| 13 | 476270 | 10s 668.308ms | 7s 395.512ms | 0s 765.601ms | 6667780 bytes |
|
||||
| 14 | 1802312 | 45s 606.597ms | 32s 28.7977ms | 2s 919.653ms | 27034680 bytes |
|
||||
| 15 | ~6M | ~5mn | ~5mn | ~10s | ~100 MB |
|
||||
| 1 | 1 | 0s 0.005471ms | 0s 0.14436ms | 0s 0.022223ms | 3 bytes |
|
||||
| 2 | 1 | 0s 0.006979ms | 0s 0.036624ms | 0s 0.011424ms | 4 bytes |
|
||||
| 3 | 2 | 0s 0.018718ms | 0s 0.035885ms | 0s 0.013246ms | 9 bytes |
|
||||
| 4 | 7 | 0s 0.060544ms | 0s 0.056277ms | 0s 0.019395ms | 36 bytes |
|
||||
| 5 | 18 | 0s 0.220348ms | 0s 0.166593ms | 0s 0.036526ms | 76 bytes |
|
||||
| 6 | 60 | 0s 0.773924ms | 0s 0.283423ms | 0s 0.063492ms | 186 bytes |
|
||||
| 7 | 196 | 0s 3.00331ms | 0s 0.827344ms | 0s 0.163653ms | 546 bytes |
|
||||
| 8 | 704 | 0s 13.142ms | 0s 3.68255ms | 0s 0.630044ms | 1 898 bytes |
|
||||
| 9 | 2500 | 0s 50.9272ms | 0s 16.1929ms | 0s 2.35157ms | 6889 bytes |
|
||||
| 10 | 9189 | 0s 204.031ms | 0s 87.1819ms | 0s 10.5841ms | 25302 bytes |
|
||||
| 11 | 33896 | 0s 832.82ms | 0s 412.466ms | 0s 57.6399ms | 93711 bytes |
|
||||
| 12 | 126759 | 3s 425.907ms | 1s 982.715ms | 0s 226.816ms | 350325 bytes |
|
||||
| 13 | 476270 | 14s 570.595ms | 9s 945.511ms | 0s 972.036ms | 1327156 bytes |
|
||||
| 14 | 1802312 | 56s 394.426ms | 41s 675.672ms | 4s 79.0436ms | 5035148 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._
|
||||
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/)!
|
||||
|
||||
Run it yourself by typing:
|
||||
``xmake f -m release``
|
||||
``xmake build bmark``
|
||||
``xmake run bmark``
|
||||
``xmake run bmark``
|
||||
|
||||
## Credits
|
||||
|
||||
@@ -124,3 +126,6 @@ Font used: [Press Start](https://www.zone38.net/font/#pressstart).
|
||||
|
||||
Inspired by other modern stacker games such as Techmino, jstris, tetr.io, etc.
|
||||
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).
|
||||
All the code in src/Common and src/Utils comes from him.
|
||||
|
||||
102
src/Benchmark/main.cpp
Normal file
102
src/Benchmark/main.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#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;
|
||||
|
||||
auto t1 = high_resolution_clock::now();
|
||||
auto t2 = high_resolution_clock::now();
|
||||
duration<double, std::milli> ms_double;
|
||||
bool ok;
|
||||
|
||||
for (int i = min_size; i <= max_size; i++) {
|
||||
std::cout << "| " << i;
|
||||
|
||||
t1 = high_resolution_clock::now();
|
||||
std::vector<Polyomino> polyominoes = gen.generatePolyominoes(i);
|
||||
t2 = high_resolution_clock::now();
|
||||
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();
|
||||
ok = 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);
|
||||
|
||||
if (!ok) {
|
||||
std::cerr << "\nERROR: Could not save pieces to file." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
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();
|
||||
ok = 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);
|
||||
|
||||
if (!ok) {
|
||||
std::cerr << "\nERROR: Could not load pieces from file." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -297,8 +297,8 @@ void Game::lockPiece() {
|
||||
|
||||
/* clearing one more line is worth 2x more
|
||||
clearing with a spin is worth as much as clearing 2x more lines */
|
||||
long int clearScore = LINE_CLEAR_BASE_SCORE;
|
||||
clearScore = clearScore << (clear.lines << (clear.isSpin));
|
||||
long int clearScore = LINE_CLEAR_BASE_SCORE / 2;
|
||||
clearScore = clearScore << (clear.lines << clear.isSpin);
|
||||
|
||||
if (this->B2BChain && B2BConditionsAreMet) {
|
||||
clearScore *= B2B_SCORE_MULTIPLIER;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Player.h"
|
||||
#include "Game.h"
|
||||
|
||||
static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the app were choosen with this number in mind
|
||||
static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the app were choosen with this number in mind
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,13 +27,12 @@ PiecesList::PiecesList() {
|
||||
this->pushBackEmptyVectors();
|
||||
}
|
||||
|
||||
bool PiecesList::loadPieces(int size) {
|
||||
if (size < 1) return false;
|
||||
if (size <= this->highestLoadedSize) return true;
|
||||
bool PiecesList::loadPieces(int max_size) {
|
||||
if (max_size < 1) return false;
|
||||
if (max_size <= this->highestLoadedSize) return true;
|
||||
|
||||
PiecesFiles piecesFiles;
|
||||
for (int i = this->highestLoadedSize + 1; i <= size; i++) {
|
||||
|
||||
for (int i = this->highestLoadedSize + 1; i <= max_size; i++) {
|
||||
if (!piecesFiles.loadPieces(i, this->loadedPieces.at(i), this->convexPieces.at(i), this->holelessPieces.at(i), this->otherPieces.at(i))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ class PiecesList {
|
||||
PiecesList();
|
||||
|
||||
/**
|
||||
* Makes the list load all pieces of the specified size
|
||||
* @return If it sucessfully loaded the pieces
|
||||
* Makes the list load all pieces up to the specified size
|
||||
* @return If all pieces up to the specified size are correctly loaded
|
||||
*/
|
||||
bool loadPieces(int size);
|
||||
[[nodiscard]] bool loadPieces(int max_size);
|
||||
|
||||
/**
|
||||
* Selects the specified piece
|
||||
|
||||
@@ -12,7 +12,7 @@ GameDistributionAppMenu::GameDistributionAppMenu(std::shared_ptr<MenuStack> menu
|
||||
AppMenu(menuStack, settings, renderWindow),
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ void GameDistributionAppMenu::drawFrame() const {
|
||||
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, this->settings->getMaximumPiecesSize() - 3);
|
||||
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 1, 0, this->settings->getLoadablePiecesSize() - 3);
|
||||
if (firstElem == 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),
|
||||
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);
|
||||
}
|
||||
|
||||
if (this->settings->getMaximumPiecesSize() < MAXIMUM_PIECES_SIZE) {
|
||||
this->playerCursor.addRow(this->settings->getMaximumPiecesSize() + 2, 1);
|
||||
if (this->settings->getLoadablePiecesSize() < MAXIMUM_PIECES_SIZE) {
|
||||
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));
|
||||
}
|
||||
|
||||
if (this->playerCursor.getPosition().y == (this->settings->getMaximumPiecesSize() + 2)) {
|
||||
int newMaxSize = this->settings->getMaximumPiecesSize() + 1;
|
||||
if (this->playerCursor.getPosition().y == (this->settings->getLoadablePiecesSize() + 2)) {
|
||||
int newMaxSize = this->settings->getLoadablePiecesSize() + 1;
|
||||
this->settings->loadPieces(newMaxSize);
|
||||
|
||||
this->playerCursor.removeRow(newMaxSize + 1);
|
||||
@@ -95,8 +95,8 @@ void GamePiecesAppMenu::drawFrame() const {
|
||||
this->drawSelectedPiecesRow(15.f);
|
||||
|
||||
bool drawFromFirstElem = (this->playerCursor.getPosition().y == 1);
|
||||
bool addExtraLine = (this->settings->getMaximumPiecesSize() < MAXIMUM_PIECES_SIZE);
|
||||
int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 2, 1, this->settings->getMaximumPiecesSize() - 2 + (addExtraLine ? 1 : 0));
|
||||
bool addExtraLine = (this->settings->getLoadablePiecesSize() < MAXIMUM_PIECES_SIZE);
|
||||
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 + 1, 35.f, drawFromFirstElem);
|
||||
this->drawRow(firstElem + 2, 45.f, drawFromFirstElem);
|
||||
@@ -130,7 +130,7 @@ void GamePiecesAppMenu::drawSelectedPiecesRow(float yPos) const {
|
||||
|
||||
int pieceSize = getSizeOfPieces(pieceType);
|
||||
if (pieceSize > 0) {
|
||||
if (!(pieceSize > this->settings->getMaximumPiecesSize())) {
|
||||
if (!(pieceSize > this->settings->getLoadablePiecesSize())) {
|
||||
const Piece& piece = this->settings->getMenu().readPiecesList().lookAtPiece({pieceSize, value});
|
||||
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());
|
||||
@@ -143,7 +143,7 @@ void GamePiecesAppMenu::drawSelectedPiecesRow(float yPos) const {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(value > this->settings->getMaximumPiecesSize())) {
|
||||
if (!(value > this->settings->getLoadablePiecesSize())) {
|
||||
this->placeText(text, {}, ((first) ? "" : " ") + getPiecesTypeName(pieceType) + "_" + std::to_string(value), xProgress, yPos, {});
|
||||
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 {
|
||||
if (piecesSize > this->settings->getMaximumPiecesSize()) {
|
||||
if (piecesSize > this->settings->getLoadablePiecesSize()) {
|
||||
sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2);
|
||||
text.setOutlineThickness(this->settings->getWindowSizeMultiplier() / 2);
|
||||
if (this->playerCursor.getPosition().y == (piecesSize + 1)) {
|
||||
|
||||
@@ -14,7 +14,7 @@ StartUpAppMenu::StartUpAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared
|
||||
AppMenu(menuStack, settings, renderWindow),
|
||||
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() {
|
||||
|
||||
@@ -27,41 +27,41 @@ Settings::Settings(bool loadPieces) {
|
||||
this->loadSettingsFromFile(loadPieces, {});
|
||||
}
|
||||
|
||||
void Settings::loadPieces(int maximumPiecesSizeRequest) {
|
||||
if (maximumPiecesSizeRequest < MINIMUM_PIECES_SIZE) {
|
||||
maximumPiecesSizeRequest = MINIMUM_PIECES_SIZE;
|
||||
void Settings::loadPieces(int loadablePiecesSizeRequest) {
|
||||
if (loadablePiecesSizeRequest < MINIMUM_PIECES_SIZE) {
|
||||
loadablePiecesSizeRequest = MINIMUM_PIECES_SIZE;
|
||||
}
|
||||
else if (maximumPiecesSizeRequest > MAXIMUM_PIECES_SIZE) {
|
||||
maximumPiecesSizeRequest = MAXIMUM_PIECES_SIZE;
|
||||
else if (loadablePiecesSizeRequest > MAXIMUM_PIECES_SIZE) {
|
||||
loadablePiecesSizeRequest = MAXIMUM_PIECES_SIZE;
|
||||
}
|
||||
|
||||
bool succeeded = true;
|
||||
int i = 1;
|
||||
while (succeeded && (i <= maximumPiecesSizeRequest)) {
|
||||
while (succeeded && (i <= loadablePiecesSizeRequest)) {
|
||||
succeeded = this->menu.getPiecesList().loadPieces(i);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (succeeded) {
|
||||
this->maximumPiecesSize = maximumPiecesSizeRequest;
|
||||
this->loadablePiecesSize = loadablePiecesSizeRequest;
|
||||
}
|
||||
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);
|
||||
char byte;
|
||||
|
||||
// file format version
|
||||
settingsFile.get(byte);
|
||||
|
||||
// maximum pieces size
|
||||
// loadable pieces size
|
||||
settingsFile.get(byte);
|
||||
this->maximumPiecesSize = byte;
|
||||
this->loadablePiecesSize = byte;
|
||||
|
||||
if (loadPieces) {
|
||||
if (maximumPiecesSizeRequest.has_value()) {
|
||||
this->loadPieces(maximumPiecesSizeRequest.value());
|
||||
if (loadablePiecesSizeRequest.has_value()) {
|
||||
this->loadPieces(loadablePiecesSizeRequest.value());
|
||||
}
|
||||
else {
|
||||
this->loadPieces(byte);
|
||||
@@ -165,8 +165,8 @@ void Settings::saveSettingsToFile() const {
|
||||
byte = CURRENT_FILE_FORMAT_VERSION;
|
||||
settingsFile.write(&byte, 1);
|
||||
|
||||
// maximum pieces size
|
||||
byte = this->maximumPiecesSize;
|
||||
// loadable pieces size
|
||||
byte = this->loadablePiecesSize;
|
||||
settingsFile.write(&byte, 1);
|
||||
|
||||
// keybind layout
|
||||
@@ -321,7 +321,7 @@ void Settings::confirmSelectedPieces() {
|
||||
int size = getSizeOfPieces(type);
|
||||
|
||||
if (size == 0) {
|
||||
if (!(value > this->maximumPiecesSize)) {
|
||||
if (!(value > this->loadablePiecesSize)) {
|
||||
switch (type) {
|
||||
case CONVEX_PIECES : {this->menu.getPiecesList().selectConvexPieces(value); break;}
|
||||
case HOLELESS_PIECES : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
|
||||
@@ -332,7 +332,7 @@ void Settings::confirmSelectedPieces() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(getSizeOfPieces(type) > this->maximumPiecesSize)) {
|
||||
if (!(getSizeOfPieces(type) > this->loadablePiecesSize)) {
|
||||
this->menu.getPiecesList().selectPiece(size, value);
|
||||
selectedNone = false;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ void Settings::confirmSelectedPieces() {
|
||||
|
||||
bool Settings::increaseDistribution(int size) {
|
||||
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) {
|
||||
this->distributions.at(size)++;
|
||||
@@ -358,7 +358,7 @@ bool Settings::increaseDistribution(int size) {
|
||||
|
||||
bool Settings::decreaseDistribution(int size) {
|
||||
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) {
|
||||
this->distributions.at(size)--;
|
||||
@@ -383,8 +383,8 @@ Keybinds& Settings::getKeybinds() {
|
||||
return this->keybinds.at(this->chosenKeybinds);
|
||||
}
|
||||
|
||||
int Settings::getMaximumPiecesSize() const {
|
||||
return this->maximumPiecesSize;
|
||||
int Settings::getLoadablePiecesSize() const {
|
||||
return this->loadablePiecesSize;
|
||||
}
|
||||
|
||||
bool Settings::hasLoadedPieces() const {
|
||||
|
||||
@@ -29,7 +29,7 @@ static const std::pair<PiecesType, int> DEFAULT_SELECTION = {ALL_PIECES, MINIMUM
|
||||
class Settings {
|
||||
private:
|
||||
Menu menu;
|
||||
int maximumPiecesSize;
|
||||
int loadablePiecesSize;
|
||||
bool loadedPieces;
|
||||
std::vector<Keybinds> keybinds;
|
||||
int chosenKeybinds;
|
||||
@@ -42,9 +42,9 @@ class Settings {
|
||||
public:
|
||||
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;
|
||||
|
||||
@@ -82,7 +82,7 @@ class Settings {
|
||||
|
||||
Keybinds& getKeybinds();
|
||||
|
||||
int getMaximumPiecesSize() const;
|
||||
int getLoadablePiecesSize() const;
|
||||
|
||||
bool hasLoadedPieces() const;
|
||||
|
||||
|
||||
@@ -4,42 +4,69 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
void resetSettingsFile();
|
||||
void resetKeybindFile(int layout);
|
||||
[[nodiscard]] bool resetSettingsFile();
|
||||
[[nodiscard]] bool resetKeybindFile(int layout);
|
||||
|
||||
|
||||
int main() {
|
||||
std::srand(std::time(NULL));
|
||||
|
||||
bool everythingIsOK = true;
|
||||
|
||||
// CHECK PIECES FILES
|
||||
|
||||
PiecesFiles pf;
|
||||
bool warned = false;
|
||||
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
||||
#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
|
||||
|
||||
std::cout << "INFO: Pieces files for size " << i << " not found, generating..." << std::endl;
|
||||
pf.savePieces(i);
|
||||
everythingIsOK &= pf.savePieces(i);
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
bool everythingGenerated = true;
|
||||
for (int i = DEBUG_PIECES_SIZE; i <= RELEASE_PIECES_SIZE; i++) {
|
||||
bool releasePiecesGenerated = true;
|
||||
for (int i = DEBUG_PIECES_SIZE + 1; i <= RELEASE_PIECES_SIZE; i++) {
|
||||
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;
|
||||
}
|
||||
#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")) {
|
||||
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 {
|
||||
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
|
||||
@@ -48,42 +75,49 @@ int main() {
|
||||
settingsFile.get(byte);
|
||||
if ((unsigned char) byte < CURRENT_FILE_FORMAT_VERSION) {
|
||||
std::cout << "INFO: Files format changed, regenerating..." << std::endl;
|
||||
resetSettingsFile();
|
||||
everythingIsOK &= resetSettingsFile();
|
||||
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
|
||||
resetKeybindFile(i);
|
||||
everythingIsOK &= resetKeybindFile(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 n°" << (i + 1) << "/" << NUMBER_OF_KEYBINDS << " not found, generating..." << std::endl;
|
||||
resetKeybindFile(i);
|
||||
}
|
||||
}
|
||||
// LAUNCH APP
|
||||
|
||||
GraphApp UI;
|
||||
UI.run();
|
||||
if (everythingIsOK) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void resetSettingsFile() {
|
||||
bool resetSettingsFile() {
|
||||
if (!std::filesystem::exists("data/config")) {
|
||||
std::filesystem::create_directories("data/config");
|
||||
}
|
||||
|
||||
std::ofstream settingsFile("data/config/settings.bin", std::ios::trunc | std::ios::binary);
|
||||
char byte;
|
||||
std::string filePath ="data/config/settings.bin";
|
||||
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;
|
||||
|
||||
// file format version
|
||||
byte = CURRENT_FILE_FORMAT_VERSION;
|
||||
settingsFile.write(&byte, 1);
|
||||
|
||||
// maximum pieces size
|
||||
// loadable pieces size
|
||||
byte = MINIMUM_PIECES_SIZE;
|
||||
settingsFile.write(&byte, 1);
|
||||
|
||||
@@ -132,16 +166,35 @@ void resetSettingsFile() {
|
||||
}
|
||||
|
||||
// selected pieces
|
||||
byte = ALL_PIECES;
|
||||
byte = DEFAULT_SELECTION.first;
|
||||
settingsFile.write(&byte, 1);
|
||||
byte = 4;
|
||||
byte = DEFAULT_SELECTION.second;
|
||||
settingsFile.write(&byte, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void resetKeybindFile(int layout) {
|
||||
if (layout < 0 || layout > 4) return;
|
||||
bool resetKeybindFile(int layout) {
|
||||
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;
|
||||
|
||||
if (layout != 4) {
|
||||
@@ -207,4 +260,6 @@ void resetKeybindFile(int layout) {
|
||||
byte = 0xFF;
|
||||
layoutFile.write(&byte, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,21 +18,21 @@ class PiecesFiles {
|
||||
|
||||
/**
|
||||
* Generate a file containing all the pieces of the specified size
|
||||
* @return If the file could be created
|
||||
* @return If the pieces are saved correctly
|
||||
*/
|
||||
bool savePieces(int polyominoSize) const;
|
||||
[[nodiscard]] bool savePieces(int polyominoSize) const;
|
||||
|
||||
/**
|
||||
* Generate a file containing all the pieces of the specified size, assuming they have been correctly generated
|
||||
* @return If the file could be created
|
||||
* @return If the piece are saved correctly
|
||||
*/
|
||||
bool savePieces(int polyominoSize, std::vector<Polyomino>& polyominoes) const;
|
||||
[[nodiscard]] bool savePieces(int polyominoSize, std::vector<Polyomino>& polyominoes) const;
|
||||
|
||||
/**
|
||||
* Replace the content of the vectors by the pieces of the specified size, if the file wasn't found the vectors stays untouched
|
||||
* @return If the file was found
|
||||
* Replace the content of the vectors by the pieces of the specified size, if the pieces can't be loaded correctly the vectors stays untouched
|
||||
* @return If the pieces could be loaded correctly
|
||||
*/
|
||||
bool loadPieces(int polyominoSize, std::vector<Piece>& pieces, std::vector<int>& convexPieces, std::vector<int>& holelessPieces, std::vector<int>& otherPieces) const;
|
||||
[[nodiscard]] bool loadPieces(int polyominoSize, std::vector<Piece>& pieces, std::vector<int>& convexPieces, std::vector<int>& holelessPieces, std::vector<int>& otherPieces) const;
|
||||
|
||||
/**
|
||||
* Puts the path to the piece file of the specified size in order, if the data folder wasn't found the string stays untouched
|
||||
|
||||
@@ -7,38 +7,35 @@
|
||||
#include <cmath>
|
||||
|
||||
static const int MAXIMUM_PIECES_SIZE = 10;
|
||||
static const int BENCHMARK_PIECES_SIZE = 15;
|
||||
|
||||
|
||||
void testGeneratorForAllSizes(int max_size);
|
||||
void testGeneratorForOneSize(int size);
|
||||
void printPiecesByTypesForOneSize(int size);
|
||||
void readStatsFromFilesForAllSizes(int max_size);
|
||||
|
||||
void benchmarking(int min_size, int max_size);
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::srand(std::time(NULL));
|
||||
|
||||
#ifdef BENCHMARK
|
||||
#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
|
||||
// CHECK PIECES FILES
|
||||
|
||||
benchmarking(1, BENCHMARK_PIECES_SIZE);
|
||||
#else
|
||||
PiecesFiles pf;
|
||||
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
||||
PiecesFiles pf;
|
||||
bool warned = false;
|
||||
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||
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;
|
||||
pf.savePieces(i);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
pf.savePieces(i);
|
||||
}
|
||||
}
|
||||
|
||||
TextApp UI;
|
||||
UI.run();
|
||||
#endif
|
||||
// LAUNCH APP
|
||||
|
||||
TextApp UI;
|
||||
UI.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -119,66 +116,3 @@ void readStatsFromFilesForAllSizes(int max_size) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user