Je travaille sur un solveur de freecell solitaire avec Java et j'ai un problème. Mon solveur semblait fonctionner correctement mais après l'avoir exécuté, je n'ai pas obtenu la réponse que je cherchais. J'ai reprogrammé deux fois de zéro et il semblait que le problème était que certaines cartes disparaissaient en créant de nouveaux états .freecell solitare intelligence artificielle
Ceci est un algorithme Depth First et une carte (ou 2 dans certains cas) ne disparaît que si le dernier état créé (avant celui qui est en cours de création) était de la même profondeur ou plus bas. Je poste ma classe d'état avec une partie de mon algorithme (seulement 2 types de mouvements peuvent être faits: pile à fondation et pile à freecell).
La recherche s'exécute dans le constructeur de l'état "parent". S'il vous plaît aidez si vous le pouvez parce que les cartes qui disparaissent ne peuvent être amusantes que par un magicien qui les exécute devant vous et non par votre ordinateur.
Voici mon code.
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;
}
}
Il vous est. Tu es le magicien. –
Sur une note plus sérieuse, veuillez faire un effort pour affiner votre problème. Vous venez de nous jeter quelques centaines de lignes de code sans analyse ni apparence d'effort de votre part. –
ce n'est pas un algorithme compliqué. Un arbre des "états" est en cours de création et en remontant une branche (un état ne peut pas avoir d'enfants) la dernière carte déplacée disparaît simplement. –