2014-12-10 3 views
-2

У меня проблема с рекурсивным заливом в моем тральщике на основе Swing JTable.Floodfill с рекурсией в Java

Вот моя заливка функция:

 public void floodfill(MouseEvent e, int row, int column) { 
      JTable target = (JTable)e.getSource(); 
      if (target.getValueAt(row, column) == this.getIconForValue(DataTable.getDataTableCellValue(row, column))) return; 
      target.setValueAt(this.getIconForValue(DataTable.getDataTableCellValue(row, column)), row, column); 

      if (row>0 && (DataTable.getDataTableCellValue(row-1, column)==0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row-1,column); 

      if (row>0 && column>0 && (DataTable.getDataTableCellValue(row-1, column-1)!=0 && DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row-1,column-1); 

      if (column>0 &&  (DataTable.getDataTableCellValue(row, column-1)==0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row,column-1); 

      if (row<DataTable.getNumberOfRows()-1  && column>0 && (DataTable.getDataTableCellValue(row+1, column-1)!=0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row+1,column-1); 

      if (row<DataTable.getNumberOfRows()-1  &&  (DataTable.getDataTableCellValue(row+1, column)==0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row+1,column); 

      if (row<DataTable.getNumberOfRows()-1  && column<DataTable.getNumberOfCols()-1 && (DataTable.getDataTableCellValue(row+1, column+1)!=0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row+1,column+1); 

      if (column<DataTable.getNumberOfCols()-1 &&  (DataTable.getDataTableCellValue(row, column+1)==0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row,column+1); 

      if (row>0  &&  column<DataTable.getNumberOfCols()-1 && (DataTable.getDataTableCellValue(row-1, column+1)!=0 || DataTable.getDataTableCellValue(row, column)==0)) 
       floodfill(e,row-1,column+1); 

     } 

getIconForValue функция:

public ImageIcon getIconForValue(int value) { 
     ImageIcon icon = new ImageIcon("2.png"); 
     switch (value) { 
      case 0: 
       icon = new ImageIcon("0.png"); 
       break; 
      case 1: 
       icon = new ImageIcon("1.png"); 
       break; 
      case 2: 
       icon = new ImageIcon("2.png"); 
       break; 
      case 3: 
       icon = new ImageIcon("3.png"); 
       break; 
      case 4: 
       icon = new ImageIcon("4.png"); 
       break; 
      case 5: 
       icon = new ImageIcon("5.png"); 
       break; 
      case 6: 
       icon = new ImageIcon("6.png"); 
       break; 
      case 7: 
       icon = new ImageIcon("7.png"); 
       break; 
      case 8: 
       icon = new ImageIcon("8.png"); 
       break; 
      case 9: 
       icon = new ImageIcon("mine.png"); 
       break; 
     } 
     return icon; 
    } 

DataTable.java:

import java.util.Random; 
import javax.swing.ImageIcon; 

public class DataTable { 

private static int numberOfRows; 
private static int numberOfCols; 
private static int numberOfMines; 
private static Cell[][] dataTable; 

public static void createDataTable(int numberOfRowsX, int numberOfColsX, int numberOfMinesX) { 
    numberOfRows = numberOfRowsX; 
    numberOfCols = numberOfColsX; 
    numberOfMines = numberOfMinesX; 
    dataTable = new Cell[numberOfRows][numberOfCols]; 
    for (int i = 0;i < numberOfRows;i++) { 
     for (int j = 0; j < numberOfCols;j++) { 
      dataTable[i][j] = new NumberCell(); 
     } 
    } 
} 

public static void scatterMines() { 
    int rowCoordOfMine, colCoordOfMine; 
    Random randY = new Random(); 
    Random randX = new Random(); 

    for (int i = 1;i < numberOfMines+1;i++){ 
     do { 
      rowCoordOfMine = randY.nextInt(10)+0; 
      colCoordOfMine = randX.nextInt(15)+0; 
     } while(dataTable[rowCoordOfMine][colCoordOfMine].getValue() == 9); 
     dataTable[rowCoordOfMine][colCoordOfMine] = new MineCell(); 
    } 
} 

public static void increaseFieldValues() { 
    for (int i = 0;i < numberOfRows;i++) { 
     for (int j = 0;j < numberOfCols;j++) { 
      if (dataTable[i][j].getValue() == 9) { 
       if (i>0) { 
        if (dataTable[i-1][j].getValue() != 9) dataTable[i-1][j].increase(); 
       } 
       if ((i>0) && (j>0)) { 
        if (dataTable[i-1][j-1].getValue() != 9) dataTable[i-1][j-1].increase(); 
       } 
       if (j>0) { 
        if (dataTable[i][j-1].getValue() != 9) dataTable[i][j-1].increase(); 
       } 
       if ((i<9) && (j>0)) { 
        if (dataTable[i+1][j-1].getValue() != 9) dataTable[i+1][j-1].increase(); 
       } 
       if (i<9) { 
        if (dataTable[i+1][j].getValue() != 9) dataTable[i+1][j].increase(); 
       } 
       if ((i<9) && (j<9)) { 
        if (dataTable[i+1][j+1].getValue() != 9) dataTable[i+1][j+1].increase(); 
       } 
       if (j<9) { 
        if (dataTable[i][j+1].getValue() != 9) dataTable[i][j+1].increase(); 
       } 
       if ((i>0) && (j<9)) { 
        if (dataTable[i-1][j+1].getValue() != 9) dataTable[i-1][j+1].increase(); 
       } 
      } 
     } 
    } 
} 

public static int getDataTableCellValue(int rowCoord, int colCoord) { 
    return dataTable[rowCoord][colCoord].getValue(); 
} 

public static int getNumberOfRows() { 
    return numberOfRows; 
} 

public static int getNumberOfCols() { 
    return numberOfCols; 
} 

}

UserTable.java:

package java_hf; 
import java.util.Random; 
import javax.swing.ImageIcon; 

public class UserTable { 

    private static int numberOfRows; 
    private static int numberOfCols; 
    private static ImageIcon[][] userTable; 

    public static void createUserTable(int numberOfRowsX, int numberOfColsX) { 
     numberOfRows = numberOfRowsX; 
     numberOfCols = numberOfColsX; 
     userTable = new ImageIcon[numberOfRows][numberOfCols]; 
     for (int i = 0;i < numberOfRows;i++) { 
      for (int j = 0; j < numberOfCols;j++) { 
       userTable[i][j] = new ImageIcon("empty.png"); 
      } 
     } 
    } 

    public static ImageIcon[][] getUserTable() { 
     return userTable; 
    } 
} 

JTable основан на модели DefaultTableModel с 2D-массивом, который содержит ImageIcons. DataTable - это класс, который содержит статический целочисленный 2D-массив, который содержит данные минного поля (0-8 -> количество мин на соседних ячейках, 9 -> мое). Функции DataTable.getNumberOfCols() и DataTable.getNumberOfRows() возвращают количество столбцов и строк в массиве DataTable. Функция getIconForValue() возвращает ImageIcon для данного номера. Наконец, DataTable.getDataTableCellValue() возвращает значение данной ячейки в массиве DataTable.

Оба массива заполнены содержимым от [0] [0].

Проблема заключается в переполнении стека. Странно, что одна и та же функция в моем коде C работает без проблем.

Извините за маленький хаотичный код, но я надеюсь, что кто-то может мне помочь. Благодаря!

Обновление: я добавил функции getIconValue и классы DataTable и UserTable.

+0

Не использовать == для сравнения объектов. – BevynQ

+0

Проблема все еще сохраняется с .equals(). – andrew1515

+0

_Извините за маленький хаотичный код_ действительно, но я надеюсь, что кто-то может помочь мне, вряд ли, если вы не опубликуете [MCVE] (http://stackoverflow.com/help/mcve). Я сомневаюсь, что использование «equals» над «==» решит вашу проблему. –

ответ

0

Не создавайте новый ImageIcon каждый раз. == между разными объектами с одинаковым значением всегда будет возвращать false. ImageIcon не реализует equals, поэтому использование будет делать то же самое.

либо используют статические экземпляры изображения, либо выполняют поиск по карте.

private static ImageIcon _0 = new ImageIcon("0.png"); 

public ImageIcon getIconForValue(int value) { 
    ImageIcon icon; 
    switch (value) { 
     case 0: 
      icon = _0; 
      break; 
     ... 
     default: 
      icon = _2; 
      break; 
    } 
    return icon; 
} 

или

public ImageIcon getIconForValue(int value) { 
    ImageIcon icon = iconMap.get(value); 
    if(icon == null){ 
     icon = new ImageIcon(value+".png"); 
     iconMap.put(value,icon); 
    } 
    return icon; 
}