Cómo obtener el estado de las celdas de la cuadrícula en función de una ubicación específica en una matriz 2D

Considere una cuadrícula 2D conn rows yn columns (aquí 75x75). Los símbolos (tokens) se dibujan en cada celda al hacer clic con el mouse. El siguiente código se utiliza para dibujar líneas de cuadrícula y símbolos dentro de las celdas:

class DrawCanvas extends JPanel{

        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            setBackground(Color.WHITE);

            //Lines
            g.setColor(Color.BLACK);
            for(int ligne = 1; ligne < ROWS; ++ligne){
                g.fillRoundRect(0, cellSize * ligne - halfGridWidth, canvasWidth - 1,
                        gridWidth, gridWidth, gridWidth);
            }
            for(int colonne = 1; colonne < COLS; ++colonne){
                g.fillRoundRect(cellSize * colonne - halfGridWidth, 0
                        , gridWidth, canvasHeight - 1,
                        gridWidth, gridWidth);
            }

            //Symbols
            Graphics2D g2d = (Graphics2D)g;
            g2d.setStroke(new BasicStroke(symbolStrokeWidth,
                    BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 
            for(int ligne = 0; ligne < ROWS; ++ligne){
                for(int colonne = 0; colonne < COLS; ++colonne){
                    int x1 = colonne * cellSize + cellPadding;
                    int y1 = ligne * cellSize + cellPadding;

                    if(board[ligne][colonne] == Token.CERCLE_ROUGE){
                        g2d.setColor(Color.RED);
                        g2d.drawOval(x1, y1, symbolSize, symbolSize);
                        g2d.fillOval(x1, y1, symbolSize, symbolSize);
                    } else
                        if(board[ligne][colonne] == Token.CERCLE_BLEU){
                            int x2 = colonne * cellSize + cellPadding;
                            g2d.setColor(Color.BLUE);
                            g2d.drawOval(x1, y1, symbolSize, symbolSize);
                            g2d.fillOval(x2, y1, symbolSize, symbolSize);
                        }
                }

            }

Con el siguiente código, puedo encontrar a todos los vecinos de una celda determinada:

private void neighbours(int  col, int row) {

     //find all serouding cell by adding +/- 1 to col and row 
    for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1  ) {

        for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1  ) {

             //if not the center cell 
            if(! ((colNum == col) && (rowNum == row))) {

                //make sure it is within  grid
                if(withinGrid (colNum, rowNum)) {
                    System.out.println("Neighbor of "+ col+ " "+ row + " - " + colNum +" " + rowNum );
                }
            }
        }
    }
}

 //define if cell represented by colNum, rowNum is inside grid
private boolean withinGrid(int colNum, int rowNum) {

    if((colNum < 0) || (rowNum <0) ) {
        return false;    //false if row or col are negative
    }
    if((colNum >= COLS) || (rowNum >= ROWS)) {
        return false;    //false if row or col are > 75
    }
    return true;
}

Considere el contenido de las celdas:

public enum Token{
VIDE, CERCLE_BLEU, CERCLE_ROUGE
}

Ahora quiero saber si hay una manera de determinar qué contiene una celda: está vacía:Token.VIDE, tieneToken.CERCLE_BLEU o tieneToken.CERCLE_ROUGE. Y cómo puedo lograr eso.

ACTUALIZACIÓN: A continuación se muestra mi código:

import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;


public final class Pha extends JFrame {

    public static int ROWS = 75;
    public static int COLS = 75;


    public static int cellSize = 15; 
    public static int canvasWidth = cellSize * COLS + (ROWS *4) ;
    public static int canvasHeight = cellSize * ROWS ; 
    public static int gridWidth = 1; 
    public static int halfGridWidth = gridWidth / 2;

    public static int cellPadding = cellSize / 5;
    public static int symbolSize = cellSize - cellPadding * 2; 
    public static int symbolStrokeWidth = 3; 

    public enum GameState{
        JOUE, NUL, CERCLE_ROUGE_GAGNE, CERCLE_BLEU_GAGNE
    }

    private GameState actualState;

    public enum Token{
        VIDE, CERCLE_ROUGE, CERCLE_BLEU
    }

    private Token actualPlayer;

    private Token[][] board;
    private final DrawCanvas canvas; 
    private JLabel statusBar; 

    public Pha(){

        canvas = new DrawCanvas(); 
        canvas.setPreferredSize(new Dimension(canvasWidth, canvasHeight));


        canvas.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) { 
        int x = e.getX();
        int y = e.getY();

        int selectedRow = y / cellSize;
        int selectedCol;
            selectedCol = x / cellSize;


        if(actualState == GameState.JOUE){
            if(selectedRow >= 0 && selectedRow < ROWS && selectedCol >= 0
                    && selectedCol < COLS &&
                    board[selectedRow][selectedCol] == Token.VIDE){
                board[selectedRow][selectedCol] = actualPlayer; 
                updateGame(actualPlayer, selectedRow, selectedCol); 
                actualPlayer = (actualPlayer == Token.CERCLE_BLEU)? Token.CERCLE_ROUGE : Token.CERCLE_BLEU;

                neighbours(selectedRow, selectedCol);
            }
        } else { 
            initGame(); 
        }

        repaint();
    }

  });

    statusBar = new JLabel("  ");
    statusBar.setFont(new Font(Font.DIALOG_INPUT, Font.ITALIC, 15));
    statusBar.setBorder(BorderFactory.createEmptyBorder(2, 5, 4, 5));

    Container cp = getContentPane();
    cp.setLayout(new BorderLayout());
    cp.add(canvas, BorderLayout.EAST);
    cp.add(statusBar, BorderLayout.NORTH);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack(); 
    setTitle("Pha par esQmo");
    setVisible(true); 

    board = new Token[ROWS][COLS]; 
    initGame();   
}

    public void initGame(){
        for(int ligne = 0; ligne < ROWS; ++ligne){
            for(int colonne = 0; colonne < COLS; ++colonne){
                board[ligne][colonne] = Token.VIDE; 
            }
        }
        actualState = GameState.JOUE;
        actualPlayer = Token.CERCLE_ROUGE;
    }

    public void updateGame(Token theSeed, int ligneSelectionnee, int colonneSelectionnee) {
      if (aGagne(theSeed, ligneSelectionnee, colonneSelectionnee)) {  
         actualState= (theSeed == Token.CERCLE_ROUGE) ? GameState.CERCLE_ROUGE_GAGNE : GameState.CERCLE_BLEU_GAGNE;
      } else if (estNul()) { 
         actualState = GameState.CERCLE_BLEU_GAGNE;       
      }

   }
 public boolean estNul() {
      /*for (int row = 0; row < ROWS; ++row) {
         for (int col = 0; col < COLS; ++col) {
            if (board[row][col] == Token.VIDE) {
               return false; 
            }
         }
      }*/
      return false; 
   }

   public boolean aGagne(Token token, int ligneSelectionnee, int colonneSelectionnee) {
      return false; 

}


   public void neighbours(int  row, int col) {

    for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1  ) {

        for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1  ) {

            if(!((colNum == col) && (rowNum == row))) {

                if(withinGrid (rowNum, colNum )) {

                    System.out.println("Neighbor of "+ row + " " + col + " is " + rowNum +" " + colNum );

                }
            }
        }
    }
}

private boolean withinGrid(int colNum, int rowNum) {

    if((colNum < 0) || (rowNum <0) ) {
        return false;
    }
    if((colNum >= COLS) || (rowNum >= ROWS)) {
        return false;
    }
    return true;
}

class DrawCanvas extends JPanel{

        @Override
        public void paintComponent(Graphics g){ //Invoqué via repaint()
            super.paintComponent(g); //Pour remplir l'arriere plan
            setBackground(Color.WHITE); //Defini la couleur de l'arriere plan


            g.setColor(Color.BLACK);
            for(int ligne = 1; ligne < ROWS; ++ligne){
                g.fillRoundRect(0, cellSize * ligne - halfGridWidth, canvasWidth - 1,
                        gridWidth, gridWidth, gridWidth);
            }
            for(int colonne = 1; colonne < COLS; ++colonne){
                g.fillRoundRect(cellSize * colonne - halfGridWidth, 0
                        , gridWidth, canvasHeight - 1,
                        gridWidth, gridWidth);
            }


            Graphics2D g2d = (Graphics2D)g;
            g2d.setStroke(new BasicStroke(symbolStrokeWidth,
                    BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 
            for(int ligne = 0; ligne < ROWS; ++ligne){
                for(int colonne = 0; colonne < COLS; ++colonne){
                    int x1 = colonne * cellSize + cellPadding;
                    int y1 = ligne * cellSize + cellPadding;

                    if(board[ligne][colonne] == Token.CERCLE_ROUGE){
                        g2d.setColor(Color.RED);
                        g2d.drawOval(x1, y1, symbolSize, symbolSize);
                        g2d.fillOval(x1, y1, symbolSize, symbolSize);
                    } else
                        if(board[ligne][colonne] == Token.CERCLE_BLEU){
                            int x2 = colonne * cellSize + cellPadding;
                            g2d.setColor(Color.BLUE);
                            g2d.drawOval(x1, y1, symbolSize, symbolSize);
                            g2d.fillOval(x2, y1, symbolSize, symbolSize);
                        }
                }

            }

            if(actualState == GameState.JOUE){
                if(actualPlayer == Token.CERCLE_ROUGE){
                    statusBar.setText("ROUGE, c'est votre tour");
                    statusBar.setForeground(Color.RED);

                } else {
                    statusBar.setText("BLEU, c'est votre tour");
                    statusBar.setForeground(Color.BLUE);
                    statusBar.addMouseMotionListener(null);
                }
            } else
                if(actualState == GameState.NUL){
                    statusBar.setForeground(Color.yellow);
                    statusBar.setText("Match nul! Cliquez pour rejouer");
                } else
                    if(actualState == GameState.CERCLE_ROUGE_GAGNE){
                        statusBar.setText("Le jouer X a remporté la partie, cliquez pour rejouer");
                        statusBar.setForeground(Color.RED);
                    } else
                        if(actualState == GameState.CERCLE_BLEU_GAGNE){
                            statusBar.setForeground(Color.BLUE);
                            statusBar.setText("Le joueur O a remporté la partie, cliquez pour rejouer");
                        }
        }
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(() -> {
            Pha pha = new Pha();
        });
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta