Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reset usermod TetrisAI back to initial version #3897

Merged
merged 10 commits into from
May 27, 2024
95 changes: 0 additions & 95 deletions usermods/TetrisAI_v2/tetrisai.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,101 +202,6 @@ class TetrisAI
}
}
}

bool findBestMoveNonBlocking(GridBW grid, std::vector<Piece>::iterator start, std::vector<Piece>::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<Piece>::iterator start, std::vector<Piece>::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__ */
52 changes: 27 additions & 25 deletions usermods/TetrisAI_v2/usermod_v2_tetrisai.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

typedef struct TetrisAI_data
{
unsigned long lastTime = 0;
TetrisAIGame tetris;
uint8_t intelligence;
uint8_t rotate;
bool showNext;
Expand Down Expand Up @@ -96,6 +94,8 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data)
////////////////////////////
uint16_t mode_2DTetrisAI()
{
static unsigned long lastTime = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use static variables in an effect function.
You can either use SEGENV.aux0, SEGENV.aux1, SEGENV.step, or allocate persistent data by using SEGENV.allocateData(dataSize).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can find many good examples for this in wled00/FX.cpp

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started to create a 'non blocking' version of the AI part. The commits I took back were related to that.

I need to have a look in the 'static' part.


if (!strip.isMatrix || !SEGENV.allocateData(sizeof(tetrisai_data)))
{
// not a 2D set-up
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use static variables in an effect function (see previous comment).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you need a permanent and global object, instantiate it in your usermod class and then use a pointer to it within your effect function.
I would recommend against it though, as user may create multiple segments and have them display the same effect. This should not be prohibited.

You ca also keep the TetrisAI_data class unchanged but modify TetrisAIGame class to have a begin() like method which would take parameters as specified in this constructor. You would use begin(cols < 32 ? cols : 32, rows, 1, piecesData, numPieces); within if (SEGENV.call == 0) { ... }condition.

Be mindful though, that segment dimensions may change at any time and cols may not be the same on 100th call of the effect function than it was at 1st.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I need to keep the 'internal game grid' between calls. The 'effect' is a real game and has an internal state. How would I make sure

  1. that I provide separate 'game' for every segment (no single static game object possible, I guess)
  2. the segment is not changed to often as every change will reset and reinitialize the game as the game grid needs to change its shape

I am happy to get this feedback, BTW but struggle a bit to provide solutions.


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;
Expand All @@ -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));
}

Expand All @@ -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)
softhack007 marked this conversation as resolved.
Show resolved Hide resolved
{
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;
Expand Down