2D Arrays in Setup and Loop - Problems with the Scope

Hi,

let me describe my Project first, so you know what I am up to.
I want to build a digital Go-Board which can replay Games. (Go is played on a 9x9/13x13/19x19 grid by putting black and white stones alternating see: Go (game) - Wikipedia for more information) I already have my 9x9 LED Matrix (WS2812B) ready and want to use the FastLED library.

The common format in which Go-Games are saved is called .sgf and looks something like this: ;B[de];W[fe];B[ee];W[fd];B[ff];W[gf];B[gg];W[fg];B[ef];W[gh];B[hg];W[hh];B[eg];W[fh];B[ge];W[hf]
B is the Black Player, W is the White player and the letters refer to the coordinates on the Board (here a 9x9 Board).
First, I figure out how many moves there are in the game and then create a 2-D array
(byte game[numberOfMoves][2]) to store the individual moves in a numeric form. Here is where I hit my Problem. I obviously want to do the parsing of the Game in the setup() but I want to use it in the Loop(). This results in Problems with the Scope. But I cannot define my Arrays before I know how many moves there are in the game.

My first target ist to display the Game using a Potentiometer (sliding through the game by turning the knob).

Here is my code (i removed some helper functions for accessing the Matrix)

#include <FastLED.h>  // Add Library
// #define NUM_LEDS 81   // Set Number of LEDs
// Params for width and height
const uint8_t kMatrixWidth = 9;
const uint8_t kMatrixHeight = 9;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
#define DATA_PIN 6    // Set Data Input pin
#define BRIGHTNESS 64
  
CRGB leds[NUM_LEDS];  // Prepare Memory
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];

void setup() { 
   FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
   FastLED.setBrightness( BRIGHTNESS );
   Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
    
   }
  
   Serial.println("Start analyzing the game...");
   String gameRaw =";B[de];W[fe];B[ee];W[fd];B[ff];W[gf];B[gg];W[fg];B[ef];W[gh];B[hg];W[hh];B[eg];W[fh];B[ge];W[hf];B[he];W[ig];B[fc];W[gd];B[gc];W[hd];B[ed];W[be];B[hc];W[ie];B[bc];W[cg];B[cf];W[bf];B[ch];W[cc];B[cb];W[dg];B[dh];W[bh];B[eh];W[dc];B[bd];W[ec];B[cd];W[fb];B[gb];W[bb];B[eb];W[db];B[fa];W[ca];B[ea];W[da];B[df];W[bg];B[bi];W[ab];B[ah];W[ci];B[di];W[ag];B[ae];W[ac];B[ad];W[ha];B[hb];W[fi];B[ce];W[ai];B[ci];W[ei];B[ah];W[ic];B[ib];W[ai];B[ba];W[aa];B[ah];W[ga];B[ia];W[ai];B[ga];W[id]";
   
   Serial.println("Figuring out the number of moves...");
   int numberOfMoves = gameRaw.length()/6 ;
 
   Serial.print("Moves: ") ;
   Serial.println(numberOfMoves);
 
   
   byte game[numberOfMoves][2];
   Serial.println("Parsing the game...");
    int ascii_a;
    int ascii_b;
    String a;
    String b;
   for (int i = 0; i < numberOfMoves ; i++) {
       a = gameRaw.substring(3+6*i,4+6*i);
       b = gameRaw.substring(4+6*i,5+6*i);

       ascii_a = a[0];
       ascii_b = b[0];
       ascii_a -= 96;
       ascii_b -= 96;
      
       game[i][0] = ascii_a;
       game[i][1] = ascii_b;           
   }

   Serial.println("Parsing complete"); 
  
     
}


void loop()
{

FastLED.clear();
 
for (int i = 0; i < numberOfMoves ; i++) {
  if (i%2 == 0) { 
    playBlack(game[i][0],game[i][1]) ;
    }
  else {
    playWhite(game[i][0],game[i][1]) ;
    }

}


}

void playBlack(uint8_t x, uint8_t y) 
{
    leds[XY(x-1,y-1)] =  CHSV(130,255,100);
        FastLED.show();
        delay(1000);
}

void playWhite(uint8_t x, uint8_t y) 
{
    leds[XY(x-1,y-1)] =  CHSV(0,180,100);
        FastLED.show();
        delay(1000);
}

Any further comments to make the code run smoothly is appreciated very much. A full game of Go is played on 19x19 board and consists of roughly 250 Moves

Declare global variables in global scope i.e. outside of functions.

Also don't use String type on ATmega controllers which don't have enough memory.

Readable input is fine for humans but a PITA for controllers. Storing a game can be done by coordinates (pairs of bytes) only. The starting player (b/w) is known and players drop or flip a stone in turn.

Put the moves constant (byte) into PROGMEM not into SRAM. If you want to read a game from Serial or SD card you better input and parse the data move by move.

So i should just generate an array with an arbitrary length outside the functions? Is there a way to know the number of turn beforehand?

I will handle the game in coordinates, but the given format is the standard in which games are stored. So if i want to review a game it will come in this fileformat.

Using PROGMEM sounds like i good idea. I did not know about that and will read about it.

Thanks for the help!

You have to set up all arrays of sufficient size. Forget about dynamic memory with ATmega's.

You only need a board of the intended size (9x9), then read one move after another and execute it.