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

Open
wants to merge 1 commit into
base: 0_15
Choose a base branch
from

Conversation

muebau
Copy link

@muebau muebau commented Apr 12, 2024

With this usermod TetrisAI compiles again.

@muebau
Copy link
Author

muebau commented Apr 12, 2024

fixes #3888

@muebau muebau mentioned this pull request Apr 12, 2024
1 task
@blazoncek blazoncek linked an issue Apr 13, 2024 that may be closed by this pull request
1 task
@blazoncek
Copy link
Collaborator

As you are using static variables in your effect function: How does that scale up to playing Tetris on multiple segments?

@softhack007
Copy link
Collaborator

softhack007 commented Apr 13, 2024

So this basicially reverts some of the last commits of the usermod (please correct me if I misunderstood)?

Wouldn't it be smarter to resolve the compiler errors in the code, instead of stripping out things until it compiles?

Copy link
Collaborator

@softhack007 softhack007 left a comment

Choose a reason for hiding this comment

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

Sorry I cannot approve this PR as it is now.

  • please avoid using static or global variables in your effect function.
  • please use strip.now in your effect function
  • I might have misunderstood - but reverting commits "until it compiles" is usually not a good solution. I would suggest to look at the compiler errors in detail, understand the root cause in the code, and then improve the source code to make the compiler happy.

@@ -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.

@@ -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 (millis() - tetrisai_data->lastTime > msDelayGameOver)
if (millis() - lastTime > msDelayGameOver)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use strip.now instead of millis()

Copy link
Author

Choose a reason for hiding this comment

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

OK it should be very easy to change that.

Copy link
Collaborator

@blazoncek blazoncek left a comment

Choose a reason for hiding this comment

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

I have to agree with @softhack007 and his review comments.

I also tried to provide a hint for better solution than this (which IMO is unacceptable). When you'll be updating the code, please also try to avoid double variables as they are slow compared to float counterparts (ESP32 has HW floating point but only for single precision, not double).

@@ -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.

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.

@muebau
Copy link
Author

muebau commented Apr 15, 2024

OK I need to test if float is good enough for the AI part.

@blazoncek
Copy link
Collaborator

@muebau is there any interest in bringing this usermod up to speed and adjust code as requested or do we pull the plug and remove it from WLED?
The code that does not compile is of no use and code that does not meet requirements cannot be included.

@blazoncek blazoncek added effect waiting for feedback addition information needed to better understand the issue usermod usermod related labels May 22, 2024
@muebau
Copy link
Author

muebau commented May 22, 2024

@muebau is there any interest in bringing this usermod up to speed and adjust code as requested or do we pull the plug and remove it from WLED? The code that does not compile is of no use and code that does not meet requirements cannot be included.

Well I will try to find time to fix at least the easy parts ( millis() ).

I am still not sure how to target the problem with the state:
static TetrisAIGame tetris(cols < 32 ? cols : 32, rows, 1, piecesData, numPieces);

I need an instance of TetrisAIGame for each segment, and it needs to be permanent. Every time the size of the segment (or other parameters) changes, I need to destroy the current instance and create a new one to be able to 'work' on the internal game grid.

I would appreciate suggestions from developers with more insight into WLED and C++.

@blazoncek
Copy link
Collaborator

I need to destroy the current instance and create a new one to be able to 'work' on the internal game grid

Do you really need to destroy it? It is just the two variables that change X and Y.
The other approach might be to just store relevant data in allocateData() buffer and use it as a POD.

Some other effects tackle this so take a look at other 2D effects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
effect usermod usermod related waiting for feedback addition information needed to better understand the issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Usermod TetrisAI compile error
3 participants