나는 자바가있는 freecell solitaire solver에서 일하고 있는데 문제가있다. 내 솔버가 잘 작동하는 것처럼 보였지만 실행 한 후에 내가 찾은 답을 얻지 못했습니다. 처음부터 두 번 다시 프로그래밍했는데 문제가있는 것처럼 보였습니다 새로운 상태 인을 만드는 동안 일부 카드가 사라졌습니다.freecell solitare 인공 지능
이것은 깊이 우선 알고리즘이며 카드 (또는 경우에 따라 2)가 마지막으로 생성 된 상태 (현재 작성중인 상태)가 같거나 더 낮은 경우에만 사라집니다.. 내 알고리즘의 일부로 내 State 클래스를 게시하고 있습니다 (단 두 가지 유형의 이동 만 가능합니다 : 기초로 스택하고 프리셀로 스택).
"상위"상태의 생성자에서 검색이 실행 중입니다. 카드가 사라지는 것은 마술사가 컴퓨터가 아닌 당신 앞에서 그것을 수행하는 것만으로 재미있을 수 있기 때문에 가능하면 도움을주십시오.
여기 내 코드입니다.
import java.util.ArrayList;
public class State {
public static ArrayList<State> stateHistory = new ArrayList<State>(); // containing all the states met so far, used to avoid duplicates and endless loops
public static State bestReached = null; // this state is used to print the best state reached
// unique elements of the state
ArrayList<ArrayList<Card>> stackList = new ArrayList<ArrayList<Card>>();
ArrayList<ArrayList<Card>> foundationList = new ArrayList<ArrayList<Card>>();
ArrayList<Card> freecellList = new ArrayList<Card>();
ArrayList<String> previousMoves = new ArrayList<String>();
State parent = null;
int depth;
// elements used for new state creation
protected ArrayList<ArrayList<Card>> tempStackList = new ArrayList<ArrayList<Card>>();
protected ArrayList<ArrayList<Card>> tempFoundationList = new ArrayList<ArrayList<Card>>();
protected ArrayList<Card> tempFreecellList = new ArrayList<Card>();
protected Card tempCard;
protected String tempLastMove = null;
public State(State s) {
this.stackList = s.stackList;
this.foundationList = s.foundationList;
this.freecellList = s.freecellList;
}
public State(ArrayList<ArrayList<Card>> stack, ArrayList<ArrayList<Card>> found, ArrayList<Card> free) {
this.stackList = stack;
this.foundationList = found;
this.freecellList = free;
System.out.println("Just created a State successfully!");
}
//the following constructor only works for Depth First search
public State(ArrayList<ArrayList<Card>> xCardLists, ArrayList<ArrayList<Card>> xFoundationList, ArrayList<Card> xFreecells, ArrayList<String> xPreviousMoves, String xLastMove, State xParent, int xDepth, boolean xIsDepthFirst) {
// setting the elements
this.stackList = new ArrayList<ArrayList<Card>>(xCardLists);
this.foundationList = new ArrayList<ArrayList<Card>>(xFoundationList);
this.freecellList = new ArrayList<Card>(xFreecells);
if (xPreviousMoves != null) {
this.previousMoves = new ArrayList<String>(xPreviousMoves);
}
if (xLastMove != null) {
this.previousMoves.add(xLastMove);
}
this.parent = xParent;
this.depth = xDepth;
// checking if it's the best state reached
checkIfBestReached();
if (parent != null && parent.totalStateCards() > this.totalStateCards()) {
System.out.println(" - ! - WARNING: Cards have been lost! -> Before: " + parent.totalStateCards() + ", Now: " + totalStateCards() + ", Last Move: " + xLastMove);
}
// delay between state creations for easier error monitoring
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String allPrevious = "";
for (String move : previousMoves) {
allPrevious += move + ", ";
}
// checking the state history and moving on
if (shouldHaveChildren() == false) {
System.out.println(this.depth + "-> BAD: (total card count: " + totalStateCards() + ", last moves: " + allPrevious + ")");
} else {
System.out.println(this.depth + "-> GOOD: (total card count: " + totalStateCards() + ", last moves: " + allPrevious + ")");
// checking for stack to foundation moves
for (ArrayList<Card> alc : stackList) {
if (alc.isEmpty() == false) {
tempCard = alc.get(alc.size()-1); // creating a pointer with the card that is currently being checked
if (tempCard.value == GUI.maxN) {
// creating the required ArrayLists
tempStackList = new ArrayList<ArrayList<Card>>(stackList);
tempFoundationList = new ArrayList<ArrayList<Card>>(foundationList);
tempFreecellList = new ArrayList<Card>(freecellList);
// moving the card
tempFoundationList.get(tempCard.type).add(tempCard);
tempStackList.get(stackList.indexOf(alc)).remove(tempCard);
// creating the last move String
tempLastMove = "foundation " + tempCard.fullName;
new State(tempStackList, tempFoundationList, tempFreecellList, previousMoves, tempLastMove, this, depth+1, true);
// setting all temps to null
tempStackList = null;
tempFoundationList = null;
tempFreecellList = null;
tempCard = null;
tempLastMove = null;
} else {
if (foundationList.get(tempCard.type).isEmpty() == false) {
if (tempCard.value - foundationList.get(tempCard.type).get(foundationList.get(tempCard.type).size()-1).value == -1) {
// creating the required ArrayLists
tempStackList = new ArrayList<ArrayList<Card>>(stackList);
tempFoundationList = new ArrayList<ArrayList<Card>>(foundationList);
tempFreecellList = new ArrayList<Card>(freecellList);
// moving the card
tempFoundationList.get(tempCard.type).add(tempCard);
tempStackList.get(stackList.indexOf(alc)).remove(tempCard);
// creating the last move String
tempLastMove = "foundation " + tempCard.fullName;
new State(tempStackList, tempFoundationList, tempFreecellList, previousMoves, tempLastMove, this, depth+1, true);
// setting all temps to null
tempStackList = null;
tempFoundationList = null;
tempFreecellList = null;
tempCard = null;
tempLastMove = null;
}
}
}
}
} // here ends the stack to foundation for loop
//checking for stack to freecell moves
for (ArrayList<Card> alc : stackList) {
if (alc.isEmpty() == false) {
tempCard = alc.get(alc.size()-1); // creating a pointer with the card that is currently being checked
if (freecellList.size() < 4) {
// creating the required ArrayLists
tempStackList = new ArrayList<ArrayList<Card>>(stackList);
tempFoundationList = new ArrayList<ArrayList<Card>>(foundationList);
tempFreecellList = new ArrayList<Card>(freecellList);
// moving the card
tempFreecellList.add(tempCard);
tempStackList.get(stackList.indexOf(alc)).remove(tempCard);
// creating the last move String
tempLastMove = "freecell " + tempCard.fullName;
new State(tempStackList, tempFoundationList, tempFreecellList, previousMoves, tempLastMove, this, depth+1, true);
// setting all temps to null
tempStackList = null;
tempFoundationList = null;
tempFreecellList = null;
tempCard = null;
tempLastMove = null;
}
}
}
}
// setting all temps to null
tempStackList = null;
tempFoundationList = null;
tempFreecellList = null;
tempCard = null;
tempLastMove = null;
}
public boolean shouldHaveChildren() {
if (stateHistory.isEmpty() == true) {
stateHistory.add(this);
return true;
} else {
for (State state : stateHistory) {
if (statesAreEqual(state, this) == true) {
return false;
}
}
stateHistory.add(this);
return true;
}
}
public static boolean statesAreEqual(State s1, State s2) { // checks if 2 states are equal or not
// checking foundationList equality
if (s1.foundationList.size() != s2.foundationList.size()) {
return false;
} else {
for (int i = 0; i < s1.foundationList.size(); i++) {
if (s1.foundationList.get(i).size() != s2.foundationList.size()) {
return false;
} else {
for (int j = 0; j < s1.foundationList.get(i).size(); j++) {
if (s1.foundationList.get(i).get(j) != s2.foundationList.get(i).get(j)) {
return false;
}
}
}
}
}
// checking stackList equality
if (s1.stackList.size() != s2.stackList.size()) {
return false;
} else {
for (int i = 0; i < s1.stackList.size(); i++) {
if (s1.stackList.get(i).size() != s2.stackList.size()) {
return false;
} else {
for (int j = 0; j < s1.stackList.get(i).size(); j++) {
if (s1.stackList.get(i).get(j) != s2.stackList.get(i).get(j)) {
return false;
}
}
}
}
}
// checking for freecellList equality
if (s1.freecellList.size() != s2.freecellList.size()) {
return false;
} else {
for (Card c : s1.freecellList) {
if (s2.freecellList.contains(c) == false) {
return false;
}
}
}
return true;
}
// checks if the current state is the best state reached (most cards in the foundations)
public void checkIfBestReached() {
if (stateHistory.isEmpty()) {
bestReached = this;
} else {
int sum = 0;
for (ArrayList<Card> alc : foundationList) {
sum += alc.size();
}
int sum2 = 0;
for (ArrayList<Card> alc : bestReached.foundationList) {
sum2 += alc.size();
}
if (sum > sum2) {
bestReached = this;
}
}
}
public int totalStateCards() {
int sum = 0;
for (ArrayList<Card> alc : stackList) {
sum += alc.size();
}
for (ArrayList<Card> alc : foundationList) {
sum += alc.size();
}
sum += freecellList.size();
return sum;
}
}
처럼 복사하는 최초의 생성자를 사용하지 말아야한다는 것입니다. 당신은 마술사입니다. –
더 심각한 점은 문제의 범위를 좁히려 고 노력하십시오. 몇 백 줄의 코드를 방금 분석이나 분석을하지 않고 방치했습니다. –
복잡한 알고리즘은 아닙니다. "상태"의 트리가 만들어지고 분기를 올라갈 때 (상태는 자식을 가질 수 없음) 마지막으로 이동 한 카드가 사라집니다. –