2D Array: what's the order of x and y (Chess board)

Hello all,

I just wrote a simple chess board and make a mcve to demonstrate my problem.

It’s that when you have a 2d array that stores the x,y position for each of the 64 cells, you need in setup() to make the for-loop for Y BEFORE the for-loop for x. I find this a bit confusing.

(which is not stated here: Two-Dimensional Arrays / Processing.org)

Also, since the y-value 8 in chess is BELOW and 1 is on the top (of the board) that is also inverted in comparison to processing where 0 is on the top and height (max) at the bottom. I tackle this in setup() as well.

Maybe someone can check if my reproach (in setup() and in also in drawChessBoard()) is correct and shed some light on this.

Order of indices

For example, PVector [][] feldPos = new PVector [9] [9]; :

  • can I say feldPos [x][y] or is
    feldPos [y][x] (with swapped x and y) better / correct?

Thanks to you all!

Warm regards,

Chrisir


// mcve for Chess board

final int groesseZelle = 40; // Feldgröße (Kantenlänge einer Zelle)

// Hier werden die zwei Feldfarben benannt, also jeweils in einer Variable gespeichert:
final color weiss   = color (255.0, 206.0, 158.0); // Weiss
final color schwarz = color (209.0, 139.0, 71.0);  // schwarz
final color YELLOW  = color(255, 255, 44);
final color GREEN   = color(0, 255, 0);
final color RED     = color(255, 0, 0);

float sx = 216.0, //
  sy = 120;
float xadd = 3.4;            //
float g  = 10.0;            //

// wir speichern die Position aller Felder des Schabretts
PVector [][] feldPos = new PVector [9] [9];

// ======================================================================================

void setup() {                     // läuft nur einmal
  size (600, 700);                 //    X  /  Y

  int posx = 120;
  int posy = 180+7*groesseZelle;

  // define BOARD Schachbrett  /// first y THEN x for-loop!!!!
  for (int y=1; y<9; y= y+1) {                // for int  y   rows
    for (int x=1; x<9; x = x+1) {                 // for int  x   columns
      feldPos[x][y] = new PVector(posx, posy);

      // COLUMN x increase
      posx=posx+groesseZelle;
    }   // for x
    // New Row
    posy = posy-groesseZelle;                   // nächste Zeile  y
    posx=120;                                 // Grundstellung posx
  }    // for y
  background(200);
}                      // Ende sub-routine

void draw() {                      // läuft  60 mal pro Sekunde
  background(200);                 // löschen
  Ueberschrift();                  //  Schach
  drawChessBoard();                    // 64 Felder
  BuchstabenWaagerecht();          // a..h
  ZahlenSenkrecht();               // 1..8
}                                  // Ende sub-routine draw()

// ======================================================================================

void Ueberschrift() {                     //  Schach     <---  /  -->

  fill(255.0, 10.0, 0.0);

  // sx = sx + xadd;

  if (sx >=390)                        // nach rechts
    xadd = xadd * -1;
  g = g + 0.50;

  if (sx <= 0)                            // nach links
    xadd = xadd * -1;

  textSize(32);                            // " SCHACH "  -  grösse
  text(" Schach ", sx, sy);
}                                  // Ende Übersschrift

// ======================================================================================

void drawChessBoard () {
  for (int x=1; x<9; x = x+1) {                 // for int  x   columns
    for (int y=1; y<9; y= y+1) {                // for int  y   rows
      setzeDieFillFeldFarbe(x, y);
      noStroke();   // no frame
      rect (feldPos[x][y].x, feldPos[x][y].y, groesseZelle, groesseZelle); //
      textSize(12);
      fill(0);
      text ( str(x)+","+str(y),
        feldPos[x][y].x+12, feldPos[x][y].y+12);
    }                                         // end   for int y
  }                                          // End for X
}                                            // End func

// ======================================================================================

void setzeDieFillFeldFarbe(int xLokal, int yLokal) {
  // setzt die fill Farbe für das nächste Feld des Schachbretts

  if (xLokal % 2 == 0) {                         //  if  x   GERADE

    // Anfang x GERADE
    if (yLokal % 2 == 0)                         //  if  y
      fill(weiss);
    else
      fill(schwarz);
    //
  }                                       //    ende  if x

  else {                                  //   Anfang    x  UNGERADE

    // Anfang  x  UNGERADE
    if (yLokal % 2 == 0) {
      fill(schwarz);                        //  hell
    } else {
      fill(weiss);
    }                                       //  ende  else y
    //
  }                                        //  ende  else  x
}                                     // Ende sub-routine

// ======================================================================================

void BuchstabenWaagerecht() {                // Buchstaben a bis h  waagerecht

  char buchstabe = 'a';
  int  posz = 80;

  for ( int  z = 1; z < 9; z = z + 1 ) {
    posz = posz + 40;
    fill(255);
    textSize(30);
    text(buchstabe++, posz, 530);
  }                                             //   ende for Buchstaben
}                                              // Ende sub-routine

// ======================================================================================

void ZahlenSenkrecht() {
  // Zahlen  1 bis 8 senkrecht
  textSize(30);
  for (int b=1; b < 9; b = b+1) {
    int yposs=160 + (9-b) * 40;
    text( b, 80, yposs);
  }                                             // Ende for
}                                              // Ende sub-routine

Your chessboard uses algebraic notation which means that square A1 should be black but in your program it is white. This image is from wikipedia.

It can be difficult to get your head around using 2D arrays for instance in geometry we think of [x,y] coordinates but in text we thing of rows (y) of characters (x) so a position is [row, col] or [y,x]

In coding it makes little difference which you use, the best choice is the one that best fits the problem. In chess we talk about ranks (rows) and columns so I suggest [y, x] or better still think of it as [row, col]

So the board 2D array would be [row][col] and to iterate over the board it would be

for each row 
    for each col 
        do something with cell[row][col]

If I was to tackle this problem I would create a class to encapsulate the chessboard. This approach would allow you to code the chessboard step by step testing at each stage.

Once you have created the basic class you can add functionality as and when you need it without worrying about code already written.

1 Like

Oh, I have to rewrite a bit of my code now…

but thank you!

small update


// mcve for Chess board

final int groesseZelle = 40; // Feldgröße (Kantenlänge einer Zelle)

// Hier werden die zwei Feldfarben benannt, also jeweils in einer Variable gespeichert:
final color weiss   = color (255.0, 206.0, 158.0); // Weiss
final color schwarz = color (209.0, 139.0, 71.0);  // schwarz
final color YELLOW  = color(255, 255, 44);
final color GREEN   = color(0, 255, 0);
final color RED     = color(255, 0, 0);

float sx = 216.0,
  sy = 120;
float xadd = 3.4;
float g  = 10.0;

// we save Positions of chess board: [y][x] or [row][col]
PVector[][] feldPos = new PVector [9] [9];

// ======================================================================================

void setup() {                     //  runs only once
  size (600, 700);                 //    X  /  Y

  int posx = 120;
  int posy = 180+7*groesseZelle;

  // define BOARD Schachbrett  /// first y THEN x for-loop!!!!
  for (int y=1; y<9; y= y+1) {                // for int  y   rows
    for (int x=1; x<9; x = x+1) {                 // for int  x   columns
      feldPos[y][x] = new PVector( posx, posy);

      // COLUMN x increase
      posx=posx+groesseZelle;
    }   // for x
    // New Row
    posy = posy-groesseZelle;                   // nächste Zeile  y
    posx=120;                                 // Grundstellung posx
  }    // for y
  background(200);
}                      // Ende sub-routine

void draw() {                      // läuft  60 mal pro Sekunde
  background(200);                 // löschen
  Ueberschrift();                  //  Schach
  drawChessBoard();                // 64 Felder
  BuchstabenWaagerecht();          // a..h
  ZahlenSenkrecht();               // 1..8
}                                  // Ende sub-routine draw()

// ======================================================================================

void Ueberschrift() {                     //  Schach     <---  /  -->

  fill(255.0, 10.0, 0.0);

  // sx = sx + xadd;

  if (sx >=390)                        // nach rechts
    xadd = xadd * -1;
  g = g + 0.50;

  if (sx <= 0)                            // nach links
    xadd = xadd * -1;

  textSize(32);                            // " SCHACH "  -  grösse
  text(" Schach ", sx, sy);
}                                  // Ende Übersschrift

// ======================================================================================

void drawChessBoard () {
  for (int y=1; y<9; y= y+1) {                // for int  y   rows
    for (int x=1; x<9; x = x+1) {                 // for int  x   columns
      setzeDieFillFeldFarbe(x, y);
      noStroke();   // no frame
      rect (feldPos[y][x].x, feldPos[y][x].y, groesseZelle, groesseZelle); //
      textSize(12);
      fill(0);
      text ( str(x)+","+str(y),
        feldPos[y][x].x+12, feldPos[y][x].y+12);
    }                                         // end   for int y
  }                                          // End for X
}                                            // End func

// ======================================================================================

void setzeDieFillFeldFarbe(int xLokal, int yLokal) {
  // setzt die fill Farbe für das nächste Feld des Schachbretts

  if (xLokal % 2 == 0) {
    //  if  x   GERADE

    // Anfang x GERADE
    if (yLokal % 2 == 0) {
      fill(schwarz);
    } else {
      fill(weiss);
    }
    //
  } //    ende  if x

  else {
    // Anfang  x  UNGERADE

    if (yLokal % 2 == 0)
      fill(weiss);
    else
      fill(schwarz);
    //
  }      //  ende  else  x
}   // Ende sub-routine

// ======================================================================================

void BuchstabenWaagerecht() {                // Buchstaben a bis h  waagerecht

  char buchstabe = 'a';
  int  posz = 80;

  for ( int  z = 1; z < 9; z = z + 1 ) {
    posz = posz + 40;
    fill(255);
    textSize(30);
    text(buchstabe++, posz, 530);
  }                                             //   ende for Buchstaben
}                                              // Ende sub-routine

// ======================================================================================

void ZahlenSenkrecht() {
  // Zahlen  1 bis 8 senkrecht
  textSize(30);
  for (int b=1; b < 9; b = b+1) {
    int yposs=160 + (9-b) * 40;
    text( b, 80, yposs);
  }                                             // Ende for
}                                              // Ende sub-routine

Do you mean a class Chessboard or rather a class ChessboardCell that has 64 objects?

Or both. But definitely a class ChessboardCell because on this level information have to be stored such as cell pos, cell color, chess piece

so ?

// ===========================================

class Chessboard {

ChessboardCell[][] board =  new ChessboardCell[9][9];

void display() {
}

} // class 

// ===========================================

class ChessboardCell  {

PVector cellPos; 
color cellColor;
String chessPiece;

void display() {
}

} // class 

I would have a Chessboard class and this would have a 2D array of cells

class Chessboard {

Cell[][] grid =  new Cell[8][8];

void display() {
}

} // class 


class Cell  {

   PVector pos; 
   int clr;
   Piece piece;

    void display() {
    }

} // class 

I would also create a Piece class and child classes for the various type e.g.

abstract class Piece {
}

class Pawn extends Piece {
 String located; // location on board of if off board.
}

class Bishop extends Piece {
}

class Knight  extends Piece {
}

...

Note the array is 8x8 because there are 64 cells on a chessboard. The row (a-h) and column (1-8) legends names should be drawn separately.

This would be my approach but don’t feel that you have to implement it this way. There is always more than one way to skin the cat :grinning_cat:

2 Likes