From 1bdf3876fc08b5b13c4fc75223c983bc95bf3723 Mon Sep 17 00:00:00 2001 From: muebau Date: Fri, 12 Apr 2024 12:00:15 +0200 Subject: [PATCH 1/9] reset usermod TetrisAI back to initial version --- usermods/TetrisAI_v2/tetrisai.h | 95 ---------------------- usermods/TetrisAI_v2/usermod_v2_tetrisai.h | 52 ++++++------ 2 files changed, 27 insertions(+), 120 deletions(-) diff --git a/usermods/TetrisAI_v2/tetrisai.h b/usermods/TetrisAI_v2/tetrisai.h index ef7868a47..12afbb2fa 100644 --- a/usermods/TetrisAI_v2/tetrisai.h +++ b/usermods/TetrisAI_v2/tetrisai.h @@ -202,101 +202,6 @@ public: } } } - - bool findBestMoveNonBlocking(GridBW grid, std::vector::iterator start, std::vector::iterator end, Rating* bestRating) - { - //vector with pieces - //for every piece - //for every - switch (expression) - { - case INIT: - break; - - default: - break; - } - } - - bool findBestMoveNonBlocking(GridBW grid, std::vector::iterator start, std::vector::iterator end, Rating* bestRating) - { - //INIT - grid.cleanupFullLines(); - Rating curRating(grid.width); - Rating deeperRating(grid.width); - Piece piece = *start; - - // for every rotation of the piece - piece.rotation = 0; - - //HANDLE - while (piece.rotation < piece.pieceData->rotCount) - { - // put piece to top left corner - piece.x = 0; - piece.y = 0; - - //test for every column - piece.x = 0; - while (piece.x <= grid.width - piece.getRotation().width) - { - - //todo optimise by the use of the previous grids height - piece.landingY = 0; - //will set landingY to final position - grid.findLandingPosition(&piece); - - // draw piece - grid.placePiece(&piece, piece.x, piece.landingY); - - if(start == end - 1) - { - //at the deepest level - updateRating(grid, &curRating); - } - else - { - //go deeper to take another piece into account - findBestMove(grid, start + 1, end, &deeperRating); - curRating = deeperRating; - } - - // eraese piece - grid.erasePiece(&piece, piece.x, piece.landingY); - - if(findWorstMove) - { - //init rating for worst - if(bestRating->score == -DBL_MAX) - { - bestRating->score = DBL_MAX; - } - - // update if we found a worse one - if (bestRating->score > curRating.score) - { - *bestRating = curRating; - (*start) = piece; - } - } - else - { - // update if we found a better one - if (bestRating->score < curRating.score) - { - *bestRating = curRating; - (*start) = piece; - } - } - piece.x++; - } - piece.rotation++; - } - - //EXIT - - return true; - } }; #endif /* __AI_H__ */ \ No newline at end of file diff --git a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h index 1c077d048..a312508b5 100644 --- a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h +++ b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h @@ -9,8 +9,6 @@ typedef struct TetrisAI_data { - unsigned long lastTime = 0; - TetrisAIGame tetris; uint8_t intelligence; uint8_t rotate; bool showNext; @@ -96,6 +94,8 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) //////////////////////////// uint16_t mode_2DTetrisAI() { + static unsigned long lastTime = 0; + if (!strip.isMatrix || !SEGENV.allocateData(sizeof(tetrisai_data))) { // not a 2D set-up @@ -116,14 +116,16 @@ uint16_t mode_2DTetrisAI() //range 0 - 16 tetrisai_data->colorInc = SEGMENT.custom2 >> 4; - if (!tetrisai_data->tetris || (tetrisai_data->tetris.nLookAhead != nLookAhead + static TetrisAIGame tetris(cols < 32 ? cols : 32, rows, 1, piecesData, numPieces); + + if (tetris.nLookAhead != nLookAhead || tetrisai_data->showNext != SEGMENT.check1 || tetrisai_data->showBorder != SEGMENT.check2 - ) ) { tetrisai_data->showNext = SEGMENT.check1; tetrisai_data->showBorder = SEGMENT.check2; + tetris.nLookAhead = nLookAhead; //not more than 32 as this is the limit of this implementation uint8_t gridWidth = cols < 32 ? cols : 32; @@ -142,7 +144,7 @@ uint16_t mode_2DTetrisAI() } } - tetrisai_data->tetris = TetrisAIGame(gridWidth, gridHeight, nLookAhead, piecesData, numPieces); + tetris = TetrisAIGame(gridWidth, gridHeight, nLookAhead, piecesData, numPieces); SEGMENT.fill(SEGCOLOR(1)); } @@ -151,48 +153,48 @@ uint16_t mode_2DTetrisAI() tetrisai_data->intelligence = SEGMENT.custom1; double dui = 0.2 - (0.2 * (tetrisai_data->intelligence / 255.0)); - tetrisai_data->tetris.ai.aHeight = -0.510066 + dui; - tetrisai_data->tetris.ai.fullLines = 0.760666 - dui; - tetrisai_data->tetris.ai.holes = -0.35663 + dui; - tetrisai_data->tetris.ai.bumpiness = -0.184483 + dui; + tetris.ai.aHeight = -0.510066 + dui; + tetris.ai.fullLines = 0.760666 - dui; + tetris.ai.holes = -0.35663 + dui; + tetris.ai.bumpiness = -0.184483 + dui; } - if (tetrisai_data->tetris.state == TetrisAIGame::ANIMATE_MOVE) + if (tetris.state == TetrisAIGame::ANIMATE_MOVE) { - if (millis() - tetrisai_data->lastTime > msDelayMove) + if (millis() - lastTime > msDelayMove) { - drawGrid(&tetrisai_data->tetris, tetrisai_data); - tetrisai_data->lastTime = millis(); - tetrisai_data->tetris.poll(); + drawGrid(&tetris, tetrisai_data); + lastTime = millis(); + tetris.poll(); } } - else if (tetrisai_data->tetris.state == TetrisAIGame::ANIMATE_GAME_OVER) + else if (tetris.state == TetrisAIGame::ANIMATE_GAME_OVER) { - if (millis() - tetrisai_data->lastTime > msDelayGameOver) + if (millis() - lastTime > msDelayGameOver) { - drawGrid(&tetrisai_data->tetris, tetrisai_data); - tetrisai_data->lastTime = millis(); - tetrisai_data->tetris.poll(); + drawGrid(&tetris, tetrisai_data); + lastTime = millis(); + tetris.poll(); } } - else if (tetrisai_data->tetris.state == TetrisAIGame::FIND_BEST_MOVE) + else if (tetris.state == TetrisAIGame::FIND_BEST_MOVE) { if (SEGMENT.check3) { if(tetrisai_data->mistaceCountdown == 0) { - tetrisai_data->tetris.ai.findWorstMove = true; - tetrisai_data->tetris.poll(); - tetrisai_data->tetris.ai.findWorstMove = false; + tetris.ai.findWorstMove = true; + tetris.poll(); + tetris.ai.findWorstMove = false; tetrisai_data->mistaceCountdown = SEGMENT.custom3; } tetrisai_data->mistaceCountdown--; } - tetrisai_data->tetris.poll(); + tetris.poll(); } else { - tetrisai_data->tetris.poll(); + tetris.poll(); } return FRAMETIME; From 5f0c6fce748d9e4beaea93d53503ead67246ca95 Mon Sep 17 00:00:00 2001 From: muebau Date: Thu, 23 May 2024 18:51:55 +0200 Subject: [PATCH 2/9] fixed static or global variables use of strip.now instead of millis() use float instead of double respond to changes in segment size make effect usable with multible segments --- usermods/TetrisAI_v2/gridbw.h | 11 ++++ usermods/TetrisAI_v2/gridcolor.h | 8 +++ usermods/TetrisAI_v2/tetrisai.h | 10 ++-- usermods/TetrisAI_v2/tetrisaigame.h | 8 ++- usermods/TetrisAI_v2/tetrisbag.h | 11 ++++ usermods/TetrisAI_v2/usermod_v2_tetrisai.h | 63 ++++++++++++---------- 6 files changed, 75 insertions(+), 36 deletions(-) diff --git a/usermods/TetrisAI_v2/gridbw.h b/usermods/TetrisAI_v2/gridbw.h index af3f5bcf0..1b90150b7 100644 --- a/usermods/TetrisAI_v2/gridbw.h +++ b/usermods/TetrisAI_v2/gridbw.h @@ -112,6 +112,17 @@ public: { return pixels[y] == (uint32_t)((1 << width) - 1); } + + void reset() + { + if (width > 32) + { + throw std::invalid_argument("maximal width is 32"); + } + + pixels.clear(); + pixels.resize(height); + } }; #endif /* __GRIDBW_H__ */ \ No newline at end of file diff --git a/usermods/TetrisAI_v2/gridcolor.h b/usermods/TetrisAI_v2/gridcolor.h index 5c5ce7e42..815c2a560 100644 --- a/usermods/TetrisAI_v2/gridcolor.h +++ b/usermods/TetrisAI_v2/gridcolor.h @@ -127,6 +127,14 @@ public: } } } + + void reset() + { + gridBW.reset(); + pixels.clear(); + pixels.resize(width* height); + clear(); + } }; #endif /* __GRIDCOLOR_H__ */ \ No newline at end of file diff --git a/usermods/TetrisAI_v2/tetrisai.h b/usermods/TetrisAI_v2/tetrisai.h index 12afbb2fa..690489f82 100644 --- a/usermods/TetrisAI_v2/tetrisai.h +++ b/usermods/TetrisAI_v2/tetrisai.h @@ -22,10 +22,10 @@ class TetrisAI { private: public: - double aHeight; - double fullLines; - double holes; - double bumpiness; + float aHeight; + float fullLines; + float holes; + float bumpiness; bool findWorstMove = false; uint8_t countOnes(uint32_t vector) @@ -110,7 +110,7 @@ public: TetrisAI(): TetrisAI(-0.510066, 0.760666, -0.35663, -0.184483) {} - TetrisAI(double aHeight, double fullLines, double holes, double bumpiness): + TetrisAI(float aHeight, float fullLines, float holes, float bumpiness): aHeight(aHeight), fullLines(fullLines), holes(holes), diff --git a/usermods/TetrisAI_v2/tetrisaigame.h b/usermods/TetrisAI_v2/tetrisaigame.h index de3c86e7e..e4766d18b 100644 --- a/usermods/TetrisAI_v2/tetrisaigame.h +++ b/usermods/TetrisAI_v2/tetrisaigame.h @@ -54,6 +54,7 @@ public: uint8_t width; uint8_t height; uint8_t nLookAhead; + uint8_t nPieces; TetrisBag bag; GridColor grid; TetrisAI ai; @@ -65,6 +66,7 @@ public: width(width), height(height), nLookAhead(nLookAhead), + nPieces(nPieces), bag(nPieces, 1, nLookAhead), grid(width, height + 4), ai(), @@ -142,8 +144,10 @@ public: void reset() { - grid.clear(); - bag.init(); + grid.width = width; + grid.height = height + 4; + grid.reset(); + bag.reset(); } }; diff --git a/usermods/TetrisAI_v2/tetrisbag.h b/usermods/TetrisAI_v2/tetrisbag.h index 3ecadbc0b..592dac6c7 100644 --- a/usermods/TetrisAI_v2/tetrisbag.h +++ b/usermods/TetrisAI_v2/tetrisbag.h @@ -25,6 +25,7 @@ private: public: uint8_t nPieces; uint8_t nBagLength; + uint8_t queueLength; uint8_t bagIdx; std::vector bag; std::vector piecesQueue; @@ -32,6 +33,7 @@ public: TetrisBag(uint8_t nPieces, uint8_t nBagLength, uint8_t queueLength): nPieces(nPieces), nBagLength(nBagLength), + queueLength(queueLength), bag(nPieces * nBagLength), piecesQueue(queueLength) { @@ -95,6 +97,15 @@ public: std::rotate(piecesQueue.begin(), piecesQueue.begin() + 1, piecesQueue.end()); piecesQueue[piecesQueue.size() - 1] = Piece(idx % nPieces); } + + void reset() + { + bag.clear(); + bag.resize(nPieces * nBagLength); + piecesQueue.clear(); + piecesQueue.resize(queueLength); + init(); + } }; #endif /* __TETRISBAG_H__ */ diff --git a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h index a312508b5..6c5a3737c 100644 --- a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h +++ b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h @@ -9,6 +9,8 @@ typedef struct TetrisAI_data { + unsigned long lastTime = 0; + TetrisAIGame tetris; uint8_t intelligence; uint8_t rotate; bool showNext; @@ -16,6 +18,8 @@ typedef struct TetrisAI_data uint8_t colorOffset; uint8_t colorInc; uint8_t mistaceCountdown; + uint16_t segcols; + uint16_t segrows; } tetrisai_data; void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) @@ -94,8 +98,6 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) //////////////////////////// uint16_t mode_2DTetrisAI() { - static unsigned long lastTime = 0; - if (!strip.isMatrix || !SEGENV.allocateData(sizeof(tetrisai_data))) { // not a 2D set-up @@ -116,16 +118,17 @@ uint16_t mode_2DTetrisAI() //range 0 - 16 tetrisai_data->colorInc = SEGMENT.custom2 >> 4; - static TetrisAIGame tetris(cols < 32 ? cols : 32, rows, 1, piecesData, numPieces); - - if (tetris.nLookAhead != nLookAhead + if (tetrisai_data->tetris.nLookAhead != nLookAhead + || tetrisai_data->segcols != cols + || tetrisai_data->segrows != rows || tetrisai_data->showNext != SEGMENT.check1 || tetrisai_data->showBorder != SEGMENT.check2 - ) + ) { + tetrisai_data->segcols = cols; + tetrisai_data->segrows = rows; tetrisai_data->showNext = SEGMENT.check1; tetrisai_data->showBorder = SEGMENT.check2; - tetris.nLookAhead = nLookAhead; //not more than 32 as this is the limit of this implementation uint8_t gridWidth = cols < 32 ? cols : 32; @@ -144,57 +147,59 @@ uint16_t mode_2DTetrisAI() } } - tetris = TetrisAIGame(gridWidth, gridHeight, nLookAhead, piecesData, numPieces); + tetrisai_data->tetris = TetrisAIGame(gridWidth, gridHeight, nLookAhead, piecesData, numPieces); + tetrisai_data->tetris.state = TetrisAIGame::States::INIT; SEGMENT.fill(SEGCOLOR(1)); } if (tetrisai_data->intelligence != SEGMENT.custom1) { tetrisai_data->intelligence = SEGMENT.custom1; - double dui = 0.2 - (0.2 * (tetrisai_data->intelligence / 255.0)); + float dui = 0.2 - (0.2 * (tetrisai_data->intelligence / 255.0)); - tetris.ai.aHeight = -0.510066 + dui; - tetris.ai.fullLines = 0.760666 - dui; - tetris.ai.holes = -0.35663 + dui; - tetris.ai.bumpiness = -0.184483 + dui; + tetrisai_data->tetris.ai.aHeight = -0.510066f + dui; + tetrisai_data->tetris.ai.fullLines = 0.760666f - dui; + tetrisai_data->tetris.ai.holes = -0.35663f + dui; + tetrisai_data->tetris.ai.bumpiness = -0.184483f + dui; } - if (tetris.state == TetrisAIGame::ANIMATE_MOVE) + if (tetrisai_data->tetris.state == TetrisAIGame::ANIMATE_MOVE) { - if (millis() - lastTime > msDelayMove) + + if (strip.now - tetrisai_data->lastTime > msDelayMove) { - drawGrid(&tetris, tetrisai_data); - lastTime = millis(); - tetris.poll(); + drawGrid(&tetrisai_data->tetris, tetrisai_data); + tetrisai_data->lastTime = strip.now; + tetrisai_data->tetris.poll(); } } - else if (tetris.state == TetrisAIGame::ANIMATE_GAME_OVER) + else if (tetrisai_data->tetris.state == TetrisAIGame::ANIMATE_GAME_OVER) { - if (millis() - lastTime > msDelayGameOver) + if (strip.now - tetrisai_data->lastTime > msDelayGameOver) { - drawGrid(&tetris, tetrisai_data); - lastTime = millis(); - tetris.poll(); + drawGrid(&tetrisai_data->tetris, tetrisai_data); + tetrisai_data->lastTime = strip.now; + tetrisai_data->tetris.poll(); } } - else if (tetris.state == TetrisAIGame::FIND_BEST_MOVE) + else if (tetrisai_data->tetris.state == TetrisAIGame::FIND_BEST_MOVE) { if (SEGMENT.check3) { if(tetrisai_data->mistaceCountdown == 0) { - tetris.ai.findWorstMove = true; - tetris.poll(); - tetris.ai.findWorstMove = false; + tetrisai_data->tetris.ai.findWorstMove = true; + tetrisai_data->tetris.poll(); + tetrisai_data->tetris.ai.findWorstMove = false; tetrisai_data->mistaceCountdown = SEGMENT.custom3; } tetrisai_data->mistaceCountdown--; } - tetris.poll(); + tetrisai_data->tetris.poll(); } else { - tetris.poll(); + tetrisai_data->tetris.poll(); } return FRAMETIME; From caf0a5bbe8e72824c12746f667cef5f4885c11b5 Mon Sep 17 00:00:00 2001 From: muebau Date: Sun, 26 May 2024 11:01:57 +0200 Subject: [PATCH 3/9] changed the last double variables and values to float and add more hints to readme --- usermods/TetrisAI_v2/rating.h | 4 ++-- usermods/TetrisAI_v2/readme.md | 2 +- usermods/TetrisAI_v2/tetrisai.h | 6 +++--- usermods/TetrisAI_v2/usermod_v2_tetrisai.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/usermods/TetrisAI_v2/rating.h b/usermods/TetrisAI_v2/rating.h index 4504ff468..88320818e 100644 --- a/usermods/TetrisAI_v2/rating.h +++ b/usermods/TetrisAI_v2/rating.h @@ -32,7 +32,7 @@ public: uint8_t fullLines; uint16_t bumpiness; uint16_t aggregatedHeight; - double score; + float score; uint8_t width; std::vector lineHights; @@ -57,7 +57,7 @@ public: this->fullLines = 0; this->bumpiness = 0; this->aggregatedHeight = 0; - this->score = -DBL_MAX; + this->score = -FLT_MAX; } }; diff --git a/usermods/TetrisAI_v2/readme.md b/usermods/TetrisAI_v2/readme.md index b21bc5fde..62b2da1c8 100644 --- a/usermods/TetrisAI_v2/readme.md +++ b/usermods/TetrisAI_v2/readme.md @@ -10,7 +10,7 @@ Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become ## Usage -It is best to set the background color to black, the border color to light grey and the game over color (foreground) to dark grey. +It is best to set the background color to black 🖤, the border color to light grey 🤍, the game over color (foreground) to dark grey 🩶, and color palette to 'Rainbow' 🌈. ### Sliders and boxes diff --git a/usermods/TetrisAI_v2/tetrisai.h b/usermods/TetrisAI_v2/tetrisai.h index 690489f82..ba4fe60e4 100644 --- a/usermods/TetrisAI_v2/tetrisai.h +++ b/usermods/TetrisAI_v2/tetrisai.h @@ -107,7 +107,7 @@ public: rating->score = (aHeight * (rating->aggregatedHeight)) + (fullLines * (rating->fullLines)) + (holes * (rating->holes)) + (bumpiness * (rating->bumpiness)); } - TetrisAI(): TetrisAI(-0.510066, 0.760666, -0.35663, -0.184483) + TetrisAI(): TetrisAI(-0.510066f, 0.760666f, -0.35663f, -0.184483f) {} TetrisAI(float aHeight, float fullLines, float holes, float bumpiness): @@ -178,9 +178,9 @@ public: if(findWorstMove) { //init rating for worst - if(bestRating->score == -DBL_MAX) + if(bestRating->score == -FLT_MAX) { - bestRating->score = DBL_MAX; + bestRating->score = FLT_MAX; } // update if we found a worse one diff --git a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h index 6c5a3737c..587fa9a36 100644 --- a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h +++ b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h @@ -155,7 +155,7 @@ uint16_t mode_2DTetrisAI() if (tetrisai_data->intelligence != SEGMENT.custom1) { tetrisai_data->intelligence = SEGMENT.custom1; - float dui = 0.2 - (0.2 * (tetrisai_data->intelligence / 255.0)); + float dui = 0.2f - (0.2f * (tetrisai_data->intelligence / 255.0f)); tetrisai_data->tetris.ai.aHeight = -0.510066f + dui; tetrisai_data->tetris.ai.fullLines = 0.760666f - dui; From 69b99abb7d2d783f18883120b32859a5b067dab3 Mon Sep 17 00:00:00 2001 From: muebau Date: Sun, 26 May 2024 15:46:23 +0200 Subject: [PATCH 4/9] improved readme --- usermods/TetrisAI_v2/readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/usermods/TetrisAI_v2/readme.md b/usermods/TetrisAI_v2/readme.md index 62b2da1c8..d702a0459 100644 --- a/usermods/TetrisAI_v2/readme.md +++ b/usermods/TetrisAI_v2/readme.md @@ -1,6 +1,6 @@ # Tetris AI effect usermod -This usermod brings you a effect brings a self playing Tetris game. The mod needs version 0.14 or above as it is based on matrix support. The effect was tested on an ESP32 with a WS2812B 16x16 matrix. +This usermod adds a self-playing Tetris game as an 'effect'. The mod requires version 0.14 or higher as it relies on matrix support. The effect was tested on an ESP32 4MB with a WS2812B 16x16 matrix. Version 1.0 @@ -19,15 +19,15 @@ It is best to set the background color to black 🖤, the border color to light * speed: speed the game plays * look ahead: how many pieces is the AI allowed to know the next pieces (0 - 2) * intelligence: how good the AI will play -* Rotate color: make the colors shift (rotate) every few cicles -* Mistakes free: how many good moves between mistakes (if activated) +* Rotate color: make the colors shift (rotate) every few moves +* Mistakes free: how many good moves between mistakes (if enabled) #### Checkboxes -* show next: if true a space of 5 pixels from the right is used to show the next pieces. The whole segment is used for the grid otherwise. +* show next: if true, a space of 5 pixels from the right will be used to show the next pieces. Otherwise the whole segment is used for the grid. * show border: if true an additional column of 1 pixel is used to draw a border between the grid and the next pieces -* mistakes: if true the worst instead of the best move is choosen every few moves (read above) +* mistakes: if true, the worst decision will be made every few moves instead of the best (see above). ## Best results - If the speed is set to be a little bit faster than a good human could play with maximal intelligence and very few mistakes it makes people furious/happy at a party. \ No newline at end of file + If the speed is set to be a little bit faster than a good human could play with maximal intelligence and very few mistakes it makes people furious/happy at a party 😉. \ No newline at end of file From 97e4eec5be51ff74703159df4360411c4d40fa0a Mon Sep 17 00:00:00 2001 From: muebau Date: Sun, 26 May 2024 21:00:13 +0200 Subject: [PATCH 5/9] avoid exceptions to stay compatible with ESP8266 add limitaion information to readme --- usermods/TetrisAI_v2/gridbw.h | 2 +- usermods/TetrisAI_v2/readme.md | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/usermods/TetrisAI_v2/gridbw.h b/usermods/TetrisAI_v2/gridbw.h index 1b90150b7..6e4966f38 100644 --- a/usermods/TetrisAI_v2/gridbw.h +++ b/usermods/TetrisAI_v2/gridbw.h @@ -34,7 +34,7 @@ public: { if (width > 32) { - throw std::invalid_argument("maximal width is 32"); + this->width = 32; } } diff --git a/usermods/TetrisAI_v2/readme.md b/usermods/TetrisAI_v2/readme.md index d702a0459..57febdf11 100644 --- a/usermods/TetrisAI_v2/readme.md +++ b/usermods/TetrisAI_v2/readme.md @@ -30,4 +30,7 @@ It is best to set the background color to black 🖤, the border color to light ## Best results - If the speed is set to be a little bit faster than a good human could play with maximal intelligence and very few mistakes it makes people furious/happy at a party 😉. \ No newline at end of file + If the speed is set to be a little bit faster than a good human could play with maximal intelligence and very few mistakes it makes people furious/happy at a party 😉. + +## Limits +The game grid is limited to a maximum width of 32 and a maximum height of 255 due to the internal structure of the code. \ No newline at end of file From 46f6a257d0689be2c44b191b7486b2b862c30aaa Mon Sep 17 00:00:00 2001 From: muebau Date: Sun, 26 May 2024 22:08:01 +0200 Subject: [PATCH 6/9] fixed another throw statement --- usermods/TetrisAI_v2/gridbw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/TetrisAI_v2/gridbw.h b/usermods/TetrisAI_v2/gridbw.h index 6e4966f38..deea027d7 100644 --- a/usermods/TetrisAI_v2/gridbw.h +++ b/usermods/TetrisAI_v2/gridbw.h @@ -117,7 +117,7 @@ public: { if (width > 32) { - throw std::invalid_argument("maximal width is 32"); + width = 32; } pixels.clear(); From abb55f8e4b468b1b0793f34d6cc550a42e23853b Mon Sep 17 00:00:00 2001 From: muebau Date: Mon, 27 May 2024 13:29:03 +0200 Subject: [PATCH 7/9] center the canvas if the segment exceeds the maximum width or height --- usermods/TetrisAI_v2/readme.md | 4 +- usermods/TetrisAI_v2/usermod_v2_tetrisai.h | 45 ++++++++++++++++------ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/usermods/TetrisAI_v2/readme.md b/usermods/TetrisAI_v2/readme.md index 57febdf11..d9f989b8c 100644 --- a/usermods/TetrisAI_v2/readme.md +++ b/usermods/TetrisAI_v2/readme.md @@ -6,7 +6,7 @@ Version 1.0 ## Installation -Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become available under the name 'Tetris AI'. +Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become available under the name 'Tetris AI'. If you are running out of flash memory, use a different memory layout (e.g. https://github.com/MoonModules/WLED/blob/mdev/tools/WLED_ESP32_4MB_256KB_FS.csv). ## Usage @@ -33,4 +33,4 @@ It is best to set the background color to black 🖤, the border color to light If the speed is set to be a little bit faster than a good human could play with maximal intelligence and very few mistakes it makes people furious/happy at a party 😉. ## Limits -The game grid is limited to a maximum width of 32 and a maximum height of 255 due to the internal structure of the code. \ No newline at end of file +The game grid is limited to a maximum width of 32 and a maximum height of 255 due to the internal structure of the code. The canvas of the effect will be centred in the segment if the segment exceeds the maximum width or height. \ No newline at end of file diff --git a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h index 587fa9a36..0f7039dac 100644 --- a/usermods/TetrisAI_v2/usermod_v2_tetrisai.h +++ b/usermods/TetrisAI_v2/usermod_v2_tetrisai.h @@ -20,6 +20,10 @@ typedef struct TetrisAI_data uint8_t mistaceCountdown; uint16_t segcols; uint16_t segrows; + uint16_t segOffsetX; + uint16_t segOffsetY; + uint16_t effectWidth; + uint16_t effectHeight; } tetrisai_data; void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) @@ -51,7 +55,7 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) color = ColorFromPalette(SEGPALETTE, colorIndex, 255, NOBLEND); } - SEGMENT.setPixelColorXY(index_x, index_y - 4, color); + SEGMENT.setPixelColorXY(tetrisai_data->segOffsetX + index_x, tetrisai_data->segOffsetY + index_y - 4, color); } } tetrisai_data->colorOffset += tetrisai_data->colorInc; @@ -63,14 +67,14 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) if (tetrisai_data->showBorder) { //draw a line 6 pixels from right with the border color - for (auto index_y = 0; index_y < SEGMENT.virtualHeight(); index_y++) + for (auto index_y = 0; index_y < tetrisai_data->effectHeight; index_y++) { - SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() - 6, index_y, SEGCOLOR(2)); + SEGMENT.setPixelColorXY(tetrisai_data->segOffsetX + tetrisai_data->effectWidth - 6, tetrisai_data->segOffsetY + index_y, SEGCOLOR(2)); } } //NEXT PIECE - int piecesOffsetX = SEGMENT.virtualWidth() - 4; + int piecesOffsetX = tetrisai_data->effectWidth - 4; int piecesOffsetY = 1; for (uint8_t nextPieceIdx = 1; nextPieceIdx < tetris->nLookAhead; nextPieceIdx++) { @@ -85,7 +89,7 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data) if (piece.getPixel(pieceX, pieceY)) { uint8_t colIdx = ((piece.pieceData->colorIndex * 32) + tetrisai_data->colorOffset); - SEGMENT.setPixelColorXY(piecesOffsetX + pieceX, piecesOffsetY + pieceNbrOffsetY + pieceY, ColorFromPalette(SEGPALETTE, colIdx, 255, NOBLEND)); + SEGMENT.setPixelColorXY(tetrisai_data->segOffsetX + piecesOffsetX + pieceX, tetrisai_data->segOffsetY + piecesOffsetY + pieceNbrOffsetY + pieceY, ColorFromPalette(SEGPALETTE, colIdx, 255, NOBLEND)); } } } @@ -130,23 +134,42 @@ uint16_t mode_2DTetrisAI() tetrisai_data->showNext = SEGMENT.check1; tetrisai_data->showBorder = SEGMENT.check2; - //not more than 32 as this is the limit of this implementation - uint8_t gridWidth = cols < 32 ? cols : 32; - uint8_t gridHeight = rows; + //not more than 32 columns and 255 rows as this is the limit of this implementation + uint8_t gridWidth = cols > 32 ? 32 : cols; + uint8_t gridHeight = rows > 255 ? 255 : rows; + + tetrisai_data->effectWidth = 0; + tetrisai_data->effectHeight = 0; // do we need space for the 'next' section? if (tetrisai_data->showNext) { - // make space for the piece and one pixel of space - gridWidth = gridWidth - 5; + //does it get to tight? + if (gridWidth + 5 > cols) + { + // yes, so make the grid smaller + // make space for the piece and one pixel of space + gridWidth = (gridWidth - ((gridWidth + 5) - cols)); + } + tetrisai_data->effectWidth += 5; // do we need space for a border? if (tetrisai_data->showBorder) { - gridWidth = gridWidth - 1; + if (gridWidth + 5 + 1 > cols) + { + gridWidth -= 1; + } + tetrisai_data->effectWidth += 1; } } + tetrisai_data->effectWidth += gridWidth; + tetrisai_data->effectHeight += gridHeight; + + tetrisai_data->segOffsetX = cols > tetrisai_data->effectWidth ? ((cols - tetrisai_data->effectWidth) / 2) : 0; + tetrisai_data->segOffsetY = rows > tetrisai_data->effectHeight ? ((rows - tetrisai_data->effectHeight) / 2) : 0; + tetrisai_data->tetris = TetrisAIGame(gridWidth, gridHeight, nLookAhead, piecesData, numPieces); tetrisai_data->tetris.state = TetrisAIGame::States::INIT; SEGMENT.fill(SEGCOLOR(1)); From 1bd051d7038e49da9391035df6b092cf82c9b4ed Mon Sep 17 00:00:00 2001 From: muebau Date: Mon, 27 May 2024 18:15:39 +0200 Subject: [PATCH 8/9] fixed link to partition table --- usermods/TetrisAI_v2/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/TetrisAI_v2/readme.md b/usermods/TetrisAI_v2/readme.md index d9f989b8c..3ca1813ea 100644 --- a/usermods/TetrisAI_v2/readme.md +++ b/usermods/TetrisAI_v2/readme.md @@ -6,7 +6,7 @@ Version 1.0 ## Installation -Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become available under the name 'Tetris AI'. If you are running out of flash memory, use a different memory layout (e.g. https://github.com/MoonModules/WLED/blob/mdev/tools/WLED_ESP32_4MB_256KB_FS.csv). +Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become available under the name 'Tetris AI'. If you are running out of flash memory, use a different memory layout (e.g. [WLED_ESP32_4MB_256KB_FS.csv](https://github.com/Aircoookie/WLED/blob/0_15/tools/WLED_ESP32_4MB_256KB_FS.csv)). ## Usage From d5da84dcb2c06ee42f7b678891b212950fe7102b Mon Sep 17 00:00:00 2001 From: muebau Date: Mon, 27 May 2024 18:36:48 +0200 Subject: [PATCH 9/9] add more information of the partition table to readme --- usermods/TetrisAI_v2/readme.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/usermods/TetrisAI_v2/readme.md b/usermods/TetrisAI_v2/readme.md index 3ca1813ea..b56f801a8 100644 --- a/usermods/TetrisAI_v2/readme.md +++ b/usermods/TetrisAI_v2/readme.md @@ -6,7 +6,13 @@ Version 1.0 ## Installation -Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become available under the name 'Tetris AI'. If you are running out of flash memory, use a different memory layout (e.g. [WLED_ESP32_4MB_256KB_FS.csv](https://github.com/Aircoookie/WLED/blob/0_15/tools/WLED_ESP32_4MB_256KB_FS.csv)). +Just activate the usermod with `-D USERMOD_TETRISAI` and the effect will become available under the name 'Tetris AI'. If you are running out of flash memory, use a different memory layout (e.g. [WLED_ESP32_4MB_256KB_FS.csv](https://github.com/Aircoookie/WLED/blob/main/tools/WLED_ESP32_4MB_256KB_FS.csv)). + +If needed simply add to `platformio_override.ini` (or `platformio_override.ini`): + +```ini +board_build.partitions = tools/WLED_ESP32_4MB_256KB_FS.csv +``` ## Usage