我正在使用java的freecell solitaire求解器,我遇到了問題。我的求職者似乎工作正常,但運行後我沒有得到我期待的答案。我重新編程了兩次,從頭開始,似乎問題是某些卡正在消失,同時創建新狀態。freecell solitare人工智能
這是一個深度優先算法和卡(或2在某些情況下),如果最後狀態產生(當前正在創建一個前)只消失了深度相同或更低。我用我的算法的一部分發布我的狀態類(只有兩種類型的動作可用:堆棧到基礎和堆棧到空閒單元)。
搜索在「父」狀態的構造函數內部運行。如果可以,請提供幫助,因爲卡片消失只能由魔術師在您面前而不是您的計算機上進行遊戲。
這是我的代碼。
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;
}
}
這是你的。你是魔術師。 –
更嚴肅的說明,請儘量縮小您的問題範圍。您剛剛在我們身上丟棄了幾百行代碼,而您沒有分析或顯示任何努力。 –
它不是一個複雜的算法。正在創建一個「州」樹,當上一個分支(一個州不能有孩子)時,最後一張卡移動消失。 –