Spielbaum für 4gewinnt

Status
Nicht offen für weitere Antworten.

sakri

Neues Mitglied
Hiho,

ich habe eine Klasse GameNode geschrieben, die einen knoten in einem 4gewinnt-spielbaum darstellen soll. Jetzt möchte ich in der methode setChildren zu einer gegebenen Spielkonfiguration (board) alle möglichen folgekonfigurationen bestimmen und die in die liste children ablegen. Nun habe ich das Problem das am Ende alle "Kinder" gleich sind, d.h. bei jedem Kind wurde in jede Zeile geworfen.
Es soll aber so sein, dass das 1.element in children das spielfeld zeigt, wenn in die 1. spalte eingeworfenen wurde, das 2. wenn in spalte 2 geworfen wurde usw... Ich habe nun alles mögliche ausprobiert, aber ich bekomms nicht hin (java anfänger und so).

Hier der Code:

Code:
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

public class GameNode implements Cloneable {
	
	GameBoard board; // the current game state.
	List<GameNode> children; // our children, one for each move available from here
	GameNode parent; // our parent in the game tree

	public GameNode(GameBoard initialBoard) {
		board = initialBoard;
		children = new ArrayList<GameNode>();
	}
	
	[b]public void setChildren(Color color) {
		int[] allowed = board.allowedMoves();
		for (int move: allowed) {
		    GameNode child = (GameNode) childClone();
		    child.throwIn(move, color);
		    this.children.add(child);
		}
	}	[/b]

	public GameNode throwIn(int col, Color color) {
		boolean gesetzt = false;
		for (int i = 0; i < board.getRows(); i++) {
			if (board.getLayout()[col][i] == Color.BLACK && !gesetzt) {
				board.getLayout()[col][i] = color;
				gesetzt = true;
			}
		}
		GameNode node = new GameNode(board);
		return node;
	}
	
	public GameNode childClone() {
		GameNode child = (GameNode) clone();
		child.parent = this;
		return child;
    }
	
	 public Object clone() {
		try {
		    return super.clone();
		}
		catch (CloneNotSupportedException e) {
		    throw new RuntimeException ("This class does not implement Cloneable.");
		}
	 }

Thx for help
 
Ich hab grad nicht den Nerv, mich durch die Logik durchzuwurschteln, aber ein Tipp: Vermeide clone wenn möglich! Clone ist böse (siehe "Angriff der Klonkrieger"), und die beiden einzigen Gründe, es zu nehmen sind:
- man muss "fremde" Objekte (z.B. aus Bibliothek ohne Quellcode) duplizieren
- man braucht das allerletzte Quentchen Performance

Der bessere Weg ist meist ein Copy-Constructor
Code:
class Foo {
   private int i;
   private String s;

   //normaler Constructor
   Foo(String s, int i) {
        this.i = i;
        this.s = s;
   }

   //Copy-Constructor
   Foo(Foo that) {
      this.i = that.i;
      this.s = that.s;
   }
}
 
danke schonmal, werds in zukunft beachten 😀

löst aber leider mein problem nicht.

ich erklär setchildren mal was genauer:

allowedmoves liefert mir die spalten die noch nicht voll sind. bei einem leeren 4*4 spielfeld also 0,1,2,3.
in der for-schleife soll jetzt das startspielfeld kopiert werden, in die kopie soll zunächst ins erste mögliche, also spalte 0, eingeworfen werden und dieses spielfeld in die liste einfügen. dann soll wieder das startspielfeld kopiert werden und dort in die 2.spalte eingeworfen werden usw. Am ende sieht es aber dann bei dem beispiel so aus, dass bei allen kindern in alle spalten engeworfen wurde.

Code:
public void setChildren(Color color) { 
      int[] allowed = board.allowedMoves(); 
      for (int move: allowed) { 
          GameNode child = (GameNode) childClone(); 
          child.throwIn(move, color); 
          this.children.add(child); 
      } 
   }

Hilfe wäre :toll:
 
Code:
public GameNode(GameBoard initialBoard) {
      board = initialBoard;
      children = new ArrayList<GameNode>();
   }
Alle Nodes haben dasSELBE board. Du wirst in jedem Node ein neues Board erstellen müssen.

Mach dir notfalls eine Methode "printBoard", mit der du das Board an der Konsole ausgeben kannst, und mach'dann
Code:
public void setChildren(Color color) {
      int[] allowed = board.allowedMoves();
      for (int move: allowed) {
          GameNode child = (GameNode) childClone();
          child.throwIn(move, color);

          System.out.println("Board before:");
          printBoard(this.board); 
          System.out.println("Board after trowing "+color+" in "+move);
          printBoard(child.board); 

          this.children.add(child);
      }
   }


BTW: Bei 4gewinnt ist das wohl nicht nicht so kritisch, aber ... i.a. macht es keinen Sinn, den kompletten Spielbaum "statisch" aufzubauen. Man will ja (im allgemeinen!) nur einmal runterrechnen, um zu sehen, wo man gewinnt. Recht einfach geht das, wenn man zwei Methoden anbietet
Code:
class Board
{
    doMove(Move move) { ... }
    undoMove(Move move) { ... }
}
die man dann entsprechend aufrufen kann
Code:
for (all moves)
{
    board.doMove(move);
    doRecursion(...);
    board.undoMove(move);
}
z.B. für eine MinMax- oder Alpha-Beta-Suche...
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben