无法在没有引用的情况下复制 ArrayList
Cannot copy ArrayList without reference
我正在尝试制作一个基本的国际象棋 AI。我有 class “Schach”,它存储白色图形和黑色图形的 ArrayLists。当轮到 AI 采取行动时,我首先添加所有的行动,在下一步中我想删除那些让自己受到控制的行动。但出于某种原因,AI 只会执行它拥有的每一个可能的动作。我什至没有更新主要 class 中的列表,问题在于列表总是引用 AI class.
中的列表
ALSO 我已经尝试了 clone() 方法,但它没有用。有什么建议吗??
public class Ai {
public static final Ai ai = new Ai();
private static int maxY = 8;
private static int maxX = 7;
private static int minY = 1;
private static int minX = 0;
private static ArrayList<Entity> whiteFigures;
private static ArrayList<Entity> blackFigures;
private static ArrayList<Move> moves;
public void processMoves() {
moves = new ArrayList<Move>();
resetLists();
for (Entity e : blackFigures) {
moves.addAll(calcMoves(e.getFigure(), blackFigures, whiteFigures));
}
System.out.println(moves.size());
//removeCheckMoves();
System.out.println(moves.size());
executeMove(moves.get((int) (Math.random() * moves.size())));
resetLists();
Schach.turn = true;
}
private void removeCheckMoves() {
Figure king = null;
for (Entity e : blackFigures) {
if (e.getFigure().type == Figure.king) {
king = e.getFigure();
break;
}
}
ArrayList<Move> legalMoves = new ArrayList<Move>();
for (Move m : moves) {
resetLists();
executeMove(m);
if(!isLegal(king)) {
legalMoves.add(m);
}
}
moves = legalMoves;
}
private boolean isLegal(Figure king) {
boolean check = false;
for (Entity w : whiteFigures) {
for (Move move : Utils.calcMoves(w.getFigure(), whiteFigures, blackFigures)) {
if (Utils.numToPos(move.to).x == king.x && Utils.numToPos(move.to).y == king.y) {
check = true;
break;
}
}
if(check) break;
}
return check;
}
private void executeMove(Move m) {
for (Entity e : blackFigures) {
if (e.getFigure().x == Utils.numToPos(m.from).x && e.getFigure().y == Utils.numToPos(m.from).y) {
e.getFigure().x = Utils.numToPos(m.to).x;
e.getFigure().y = Utils.numToPos(m.to).y;
e.gotoSquare(Utils.posToNum(e.getFigure()) - 8);
for (Entity w : whiteFigures) {
if (w.getFigure().x == e.getFigure().x && w.getFigure().y == e.getFigure().y) {
whiteFigures.remove(w);
break;
}
}
break;
}
}
}
private void resetLists() {
whiteFigures = new ArrayList<Entity>();
whiteFigures.clear();
whiteFigures.addAll(Schach.whiteFigures);
blackFigures = new ArrayList<Entity>();
blackFigures.clear();
blackFigures.addAll(Schach.blackFigures);
}
//calcMoves function (works fine no reference here for sure)
}
编辑
有了这个设置,人工智能根本不应该执行一个动作,只是计算它们...
编辑 2
resetLists 函数是主要问题(我猜)
好吧,我自己修好了。如果将来有人需要它,这是我的解决方案:D
public static ArrayList<Entity> cloneList (ArrayList<Entity> array){
ArrayList<Entity> arr = new ArrayList<Entity>();
for(Entity e : array) {
arr.add(cloneEntity(e));
}
return arr;
}
public static Entity cloneEntity(Entity e) {
Entity entity = new Entity(e.getPosition(), [etc...]);
return entity;
}
我正在尝试制作一个基本的国际象棋 AI。我有 class “Schach”,它存储白色图形和黑色图形的 ArrayLists。当轮到 AI 采取行动时,我首先添加所有的行动,在下一步中我想删除那些让自己受到控制的行动。但出于某种原因,AI 只会执行它拥有的每一个可能的动作。我什至没有更新主要 class 中的列表,问题在于列表总是引用 AI class.
中的列表ALSO 我已经尝试了 clone() 方法,但它没有用。有什么建议吗??
public class Ai {
public static final Ai ai = new Ai();
private static int maxY = 8;
private static int maxX = 7;
private static int minY = 1;
private static int minX = 0;
private static ArrayList<Entity> whiteFigures;
private static ArrayList<Entity> blackFigures;
private static ArrayList<Move> moves;
public void processMoves() {
moves = new ArrayList<Move>();
resetLists();
for (Entity e : blackFigures) {
moves.addAll(calcMoves(e.getFigure(), blackFigures, whiteFigures));
}
System.out.println(moves.size());
//removeCheckMoves();
System.out.println(moves.size());
executeMove(moves.get((int) (Math.random() * moves.size())));
resetLists();
Schach.turn = true;
}
private void removeCheckMoves() {
Figure king = null;
for (Entity e : blackFigures) {
if (e.getFigure().type == Figure.king) {
king = e.getFigure();
break;
}
}
ArrayList<Move> legalMoves = new ArrayList<Move>();
for (Move m : moves) {
resetLists();
executeMove(m);
if(!isLegal(king)) {
legalMoves.add(m);
}
}
moves = legalMoves;
}
private boolean isLegal(Figure king) {
boolean check = false;
for (Entity w : whiteFigures) {
for (Move move : Utils.calcMoves(w.getFigure(), whiteFigures, blackFigures)) {
if (Utils.numToPos(move.to).x == king.x && Utils.numToPos(move.to).y == king.y) {
check = true;
break;
}
}
if(check) break;
}
return check;
}
private void executeMove(Move m) {
for (Entity e : blackFigures) {
if (e.getFigure().x == Utils.numToPos(m.from).x && e.getFigure().y == Utils.numToPos(m.from).y) {
e.getFigure().x = Utils.numToPos(m.to).x;
e.getFigure().y = Utils.numToPos(m.to).y;
e.gotoSquare(Utils.posToNum(e.getFigure()) - 8);
for (Entity w : whiteFigures) {
if (w.getFigure().x == e.getFigure().x && w.getFigure().y == e.getFigure().y) {
whiteFigures.remove(w);
break;
}
}
break;
}
}
}
private void resetLists() {
whiteFigures = new ArrayList<Entity>();
whiteFigures.clear();
whiteFigures.addAll(Schach.whiteFigures);
blackFigures = new ArrayList<Entity>();
blackFigures.clear();
blackFigures.addAll(Schach.blackFigures);
}
//calcMoves function (works fine no reference here for sure)
}
编辑
有了这个设置,人工智能根本不应该执行一个动作,只是计算它们...
编辑 2 resetLists 函数是主要问题(我猜)
好吧,我自己修好了。如果将来有人需要它,这是我的解决方案:D
public static ArrayList<Entity> cloneList (ArrayList<Entity> array){
ArrayList<Entity> arr = new ArrayList<Entity>();
for(Entity e : array) {
arr.add(cloneEntity(e));
}
return arr;
}
public static Entity cloneEntity(Entity e) {
Entity entity = new Entity(e.getPosition(), [etc...]);
return entity;
}