英文:
Java arraylist does not keep values that I am passing inside a method
问题
I am making an AI game where the cpu stacks N numbered cubes in a table in 3 rows using the Uniform Cost Search algorithm. What I'm trying to do is the generateMoves()
method, which will return an ArrayList with all the possible moves from a given state.
Cube is a class representing a cube with its own ID (the number of the cube), X-axis position, and Y-axis position.
K is user input.
getCubes()
is a method that returns an ArrayList<Cube>
which is the current state of the table.
setCubes()
is a method that takes an ArrayList<Cube>
and sets that list as the current state.
isValid()
is a Cube method that checks the copyOfTable list if the given cube is in a valid position.
isFree()
is a Cube method that checks the copyOfTable list if the given cube is free to be moved.
public class Table{
// private fields
// constructor
public ArrayList<Table> generateMoves(){
ArrayList<Table> moves = new ArrayList<Table>();
ArrayList<Cube> currentTable = this.getCubes();
ArrayList<Cube> copyOfTable = new ArrayList<Cube>(currentTable);
int X = 1;
int Y = 1;
int K = this.getK();
for(Cube cube : currentTable){
int backupX = cube.getPosX();
int backupY = cube.getPosY();
for(Y = 1; Y <= 3; Y++){
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
this.setCubes(currentTable);
moves.add(this);
moves.get(0).printTable();
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
}
}
moves.get(anyIndex).printTable();
return moves;
}
}
// main is in a different file
main(){
ArrayList<Table> moves = new ArrayList<Table>();
Table table = new Table();
moves = table.generateMoves();
}
What I want is the moves.add(this)
to add the current state of the board in the moves
ArrayList, so that I can return all the tables (states) that are possible to be generated by the given table.
The problem is that the first printTable()
(inside the 3rd for loop) prints every state that can be generated, not only the first one that I ask it for.
The second printTable()
(above the return statement), no matter the index, only prints the first state of the table.
What am I missing here?
英文:
I am making an AI game where the cpu stacks N numbered cubes in a table in 3 rows using the Uniform Cost Search algorithm. What I'm trying to do is the generateMoves()
method, which will return an ArrayList with all the possible moves from a given state.
Cube is a class representing a cube with its own ID (the number of the cube), X axis position and Y axis position.
K is user input
getCubes()
is a method that returns an ArrayList<Cube>
which is the current state of the table.
setCubes()
is a method that takes an ArrayList<Cube>
and sets that list as the current state.
isValid()
is a Cube method that checks the copyOfTable list if the given cube is in a valid position.
isFree()
is a Cube method that checks the copyOfTable list if the given cube is free to be moved.
public class Table{
private fields
constructor{}
public Arraylist<Table> generateMoves(){
Arraylist<Table> moves = new ArrayList<Table>();
ArrayList<Cube> currentTable = this.getCubes();
ArrayList<Cube> copyOfTable = new ArrayList<Cube>(currentTable);
int X = 1;
int Y = 1;
int K = this.getK();
for(Cube cube : currentTable){
int backupX = cube.getPosX();
int backupY = cube.getPosY();
for(Y = 1; Y <= 3; Y++){
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
this.setCubes(currentTable);
moves.add(this);
moves.get(0).printTable();
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
}
}
moves.get(anyIndex).printTable();
return moves;
}
}
// main is in a different file
main(){
ArrayList<Table> moves = new ArrayList<Table>();
Table table = new Table();
moves = table.generateMoves();
}
What I want is the moves.add(this)
to add the current state of the board in the moves
arraylist, so that I can return all the tables (states) that are possible to be generated by the given table.
The problem is that the first printTable()
(inside the 3rd for loop), prints every state that can be generated. Not only the first one that I ask it for.
The second printTable()
(above the return statement), no matter the index, only prints the first state of the table.
What am I missing here?
I tried the above code
答案1
得分: 0
> "... 我在这里漏掉了什么? ..."
你的代码是正确的,只是你误解了_generateMoves_方法的上下文。返回的_ArrayList_不会保留,每次调用都会创建一个新的_ArrayList_。
这种类型的方法需要放在不同的类中。在这个类中,你可以利用一个_ArrayList_类字段来填充一个列表。
考虑以下内容。
通过将_Table_对象传递给_generateMoves_,你可以填充类字段_moves_。
class TableUtil {
static ArrayList<Table> moves = new ArrayList<>();
static ArrayList<Table> getMoves() {
return moves;
}
static void generateMoves(Table table) {
ArrayList<Cube> currentTable = table.getCubes();
ArrayList<Cube> copyOfTable = new ArrayList<Cube>(currentTable);
int X = 1;
int Y = 1;
int K = table.getK();
for(Cube cube : currentTable){
int backupX = cube.getPosX();
int backupY = cube.getPosY();
for(Y = 1; Y <= 3; Y++){
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
table.setCubes(currentTable);
moves.add(table);
moves.get(0).printTable();
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
}
}
moves.get(table.anyIndex).printTable();
}
}
创建你的_Table_对象,然后为每个实例调用_generateMoves_方法。
例如,
Table tableA = new Table();
Table tableB = new Table();
Table tableC = new Table();
TableUtil.generateMoves(tableA);
TableUtil.generateMoves(tableB);
TableUtil.generateMoves(tableC);
ArrayList<Table> moves = TableUtil.getMoves();
英文:
> "... What am I missing here? ..."
Your code is correct, you are just misinterpreting the context of the generateMoves method.
The returned ArrayList will not persist, for each call—there will be a new ArrayList per call.
This type of method will need to be placed within a different class.
In which, you can utilize a ArrayList class field, to populate a list.
Consider the following.
By passing the Table object to generateMoves, you can populate the class field moves.
class TableUtil {
static ArrayList<Table> moves = new ArrayList<>();
static ArrayList<Table> getMoves() {
return moves;
}
static void generateMoves(Table table) {
ArrayList<Cube> currentTable = table.getCubes();
ArrayList<Cube> copyOfTable = new ArrayList<Cube>(currentTable);
int X = 1;
int Y = 1;
int K = table.getK();
for(Cube cube : currentTable){
int backupX = cube.getPosX();
int backupY = cube.getPosY();
for(Y = 1; Y <= 3; Y++){
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
table.setCubes(currentTable);
moves.add(table);
moves.get(0).printTable();
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
}
}
moves.get(table.anyIndex).printTable();
}
}
Create your Table objects, and then call the generateMoves method, for each instance.
For example,
Table tableA = new Table();
Table tableB = new Table();
Table tableC = new Table();
TableUtil.generateMoves(tableA);
TableUtil.generateMoves(tableB);
TableUtil.generateMoves(tableC);
ArrayList<Table> moves = TableUtil.getMoves();
答案2
得分: 0
I don't know why (please someone explain that to me), but after I spent a very long time trial-and-erroring, the solution is to make a method that creates a "deep" copy of the ArrayList in question like so:
private ArrayList<Cube> createCopyOfTable(ArrayList<Cube> toCopy){
ArrayList<Cube> copy = new ArrayList<>();
for(Cube cube : toCopy){
Cube _cube = new Cube(cube.getID(), cube.getPosX(), cube.getPosY());
copy.add(_cube);
}
return copy;
}
and the updated part on my generateMoves()
method:
.
.
.
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
ArrayList<Cube> copyOfTable = createCopyOfTable(currentTable);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
Table table = new Table(K);
table.setCubes(copyOfTable);
this.moves.add(table);
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
.
.
.
英文:
I don't know why (please someone explain that to me), but after i spent a very long time trial-and-erroring, the solution is to make a method that creates a "deep" copy of the ArrayList in question like so:
private ArrayList<Cube> createCopyOfTable(ArrayList<Cube> toCopy){
ArrayList<Cube> copy = new ArrayList<>();
for(Cube cube : toCopy){
Cube _cube = new Cube(cube.getID(), cube.getPosX(), cube.getPosY());
copy.add(_cube);
}
return copy;
}
and the updated part on my generateMoves()
method:
.
.
.
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
ArrayList<Cube> copyOfTable = createCopyOfTable(currentTable);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
Table table = new Table(K);
table.setCubes(copyOfTable);
this.moves.add(table);
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
.
.
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论