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;