Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying Array from ArrayList Element

I'm building a Java based game in Swing, which is essentially a grid of Jbuttons

I have an Object called Cell, which is a custom JButton with additional parameters for storing objects. The game grid is represented by Cell[][]

I have an arraylist of type Cell[][] to allow me to store the state of the gamegrid after each move. If I want to undo the move, I need to copy the last element of the ArrayList to the game grid to allow it to be displayed on the UI.

My gamegrid is panelHolder and my arraylist is moveHolder.

So far I've tried Collections.copy(panelHolder, moveHolder.get(moveHolder.size())); which will not compile due to the "arguments not being applicable for the type Cell[][]"

I've also tried System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);, which throws and out of bounds exception. Initially I thought this was due to the moveHolder.size()-1, but even just as moveHolder.size() it has the same problem.

I've found numerous questions on StackOverflow and others that both show these two ways of doing it, but I can't seem to get it to work. Is there something more obvious I'm missing? Full class method below:

 public class UndoClass implements MoveCommand{

    public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();

    public Cell[][] execute(Cell[][] panelHolder) {
        if (moveHolder.size() > 0){
            Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));       
            if (moveHolder.size() > 0){
                moveHolder.remove(moveHolder.size());
            }
        }
        System.out.println("Move Undone. Undos available:" + moveHolder.size());
        return panelHolder;
    }
    public void addMove(Cell[][] panelHolder){
        moveHolder.add(panelHolder);
    }

    public ArrayList<Cell[][]> getMoves(){  
        return moveHolder;
    }
}

Cell Class

public class Cell extends JButton {

    int co_x = 0;
    int co_y = 0;


    ArrayList<Players> current = new ArrayList <Players>();

}
like image 562
jmo Avatar asked Aug 08 '26 02:08

jmo


1 Answers

Just wanted to point our your execute(...) method accepts the Cell[][] both as a parameter and the return argument. That approach is going to force all of your commands to keep copying your input param arrays to the return statement array. Notice if you don't need to keep the two in sync and you just use the return arg, you don't have to worry about copying at all:

Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState;  // Not updating the panelHolder array, just returning

But of course now the input parm and return are out of sync. Instead you might want to encapsulate that state into a single object to make your life easier. Something like this (note that the execute now returns a void):

public ArrayList<GameState> previousStates = new ArrayList<GameState>();

public void execute(GameState currentState) {
    if (previousStates .size() > 0) {
         GameState lastState = previousStates.get(previousStates.size()-1);
         currentState.restoreFrom(lastState);
         previousStates .remove(moveHolder.size()-1);
    }   
 }

Good luck on the game!

like image 100
brariden Avatar answered Aug 10 '26 16:08

brariden



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!