递归创建树

发布于 2024-10-20 10:02:08 字数 12754 浏览 2 评论 0原文

我正在尝试递归地填充一棵树,但我的代码只是填充一个深度长度,然后退出。即每个节点只有一个子节点。有什么我没有考虑到的吗?

public static void populate(Node n, int depth, String player){
    System.out.println("Depth: " + depth);
    if(player.equalsIgnoreCase("X"))
        player = "O";
    else
        player = "X";
    int j = 0;
    System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
    for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
        if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
                || ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
            j++;
        else{
            Board tmp = new Board(((Board)n.getData()), j, player);
            Node newNode = new Node(tmp);
            tree.insert(n, newNode);
            populate(newNode, depth-1, player);
        }
    }
}

PS 和我检查 noOfEmpty() 返回值,该值应确定节点应具有的子节点数量。

编辑:@eznme 根据要求的完整代码:

public class MinMax {

    protected static Tree tree;


    public static void createTree(Board b){
        tree = new Tree();
        tree.setRoot(new Node(b));
        populate(tree.getRoot(), 5, "X");
        //System.out.println("printing tree");
        //tree.print(1);
    }

    public static void populate(Node n, int depth, String player){
        System.out.println("Depth: " + depth);
        if(player.equalsIgnoreCase("X"))
            player = "O";
        else
            player = "X";
        int j = 0;
        System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
        for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
            if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
                    || ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
                j++;
            else{
                Board tmp = new Board(((Board)n.getData()), j, player);
                Node newNode = new Node(tmp);
                tree.insert(n, newNode);
                populate(newNode, depth-1, player);
            }
        }
    }
}

import java.util.ArrayList;

/**
*
* @author Greg
*/
public class Node {

    protected Object data;
    protected int score; //fields to be used by the MaxMin class
    protected ArrayList<Node> children;

    //constructors
    public Node(){
        children = new ArrayList(0);
        data = null;
    }
    public Node(Object obj){
        children = new ArrayList(0);
        data = obj;
    }


    public void setChild(Node n){
        //EFFECT: set the ith child to node t
        children.add(n);
    }
    public void setChildren(Node[] t){
        //EFFECT: copy the array t, into the array children, effectively
        // setting all the chidern of this node simultaneouly
        int l = children.size();
        for(int i=0; i<t.length; i++){
            children.add(l, t[i]);
        }
    }
    public void setData(Object obj){
        //EFFECT: set the date of this node to obj, and also set the number of
        //  children this node has
        data = obj;
    }
    public Node getChild(int i){
        //EFFECT: returns the child at index i
        return children.get(i);
    }

    public int noOfChildren(){
        //EFFECT: return the length of this node
            return children.size();
    }

    public Object getData(){
        //EFFECT: returns the data of this node
        return data;
    }

    @Override
    public String toString(){
        //EFFECT: returns the string form of this node
        return "" + data.toString() + "\nwith " + noOfChildren()+ "\n";
    }

    public boolean isLeaf(){
        if(children.size()==0)
            return true;
        return false;
    }


    public void setScore(int scr){
        score = scr;
    }

    public int getScore(){
            return score;
    }
}

public class Tree {

    private Node root;

    public Tree(){
        setRoot(null);
    }

    public Tree(Node n){
        setRoot(n);
    }

    public Tree(Object obj){
        setRoot(new Node(obj));
    }

    protected Node getRoot(){
        return root;
    }

    protected void setRoot(Node n){
        root = n;
    }

    public boolean isEmpty(){
        return getRoot() == null;
    }

    public Object getData(){
        if(!isEmpty())
            return getRoot().getData();
        return null;
    }

    public Object getChild(int i){
        return root.getChild(i);
    }

    public void setData(Object obj){
        if(!isEmpty())
            getRoot().setData(obj);
    }

    public void insert(Node p,Node c){
        if(p != null)
            p.setChild(c);
    }

    public void print(int mode){
        if(mode == 1) pretrav();
        else if(mode == 2) postrav();
        else
            System.out.println("yeah... mode 1 or 2...nothing else, try agn");
    }

    public void pretrav(){
        pretrav(getRoot());
    }

    protected void pretrav(Node t){
        if(t == null)
            return;
        System.out.println(t.getData()+" \n");
            for(int i=0; i<t.noOfChildren(); i++)
                pretrav(t.getChild(i));
    }

    public void postrav(){
        postrav(getRoot());
    }

    protected void postrav(Node t){
        if(t == null)
            return;
        System.out.print(t.getData()+" ");
            for(int i=0; i<t.noOfChildren(); i++)
                pretrav(t.getChild(i));
        System.out.print(t.getData()+" ");
    }
}

public class Board {

    boolean isFull = false;         // a check to see if the board is full
    String[] grid = new String[9];  //an array represting the 9 square on a board
    int hV;
    String MIN, MAX;

    public Board(){
        for(int i=0; i<grid.length;i++)
            grid[i] = Integer.toString(i);
        hV = heuristicValue(this);
    }

    public Board(Board b, int x, String player){
        this.grid = b.getBoard();
        if(!(grid[x].equalsIgnoreCase("X")|| grid[x].equalsIgnoreCase("X")))
            grid[x] = player;
    }

    public boolean setSquare(String player, int position){
        /*
        EFFECT:set a square on the board to either a X or a O, debending on the player
        PRECON: square (x,y) is empty
        POATCON: square (x,y) has player 'symbol'
        */

        boolean isValidPlay = false;
        try{
            //as a sanity
            Integer.parseInt(grid[position]);
            grid[position] = player;
            isValidPlay = true;

        }catch(NumberFormatException e){
            System.out.println("positon " + position + "is already occupied");
        }
        return isValidPlay;
    }

    public boolean endGame(){
        /*
        * EFFECT: check to see if the game have been won or drawn
        */
        if(ticTacToe(0,1,2)){
            //System.out.println("Player " + grid[0] + " wins");
            return true;
        }
        else if(ticTacToe(3,4,5)){
            //System.out.println("Player " + grid[3] + " wins");
            return true;
        }
        else if(ticTacToe(6,7,8)){
            //System.out.println("Player " + grid[6] + " wins");
            return true;
        }
        else if(ticTacToe(0,4,8)){
            //System.out.println("Player " + grid[0]+ " wins");
            return true;
        }
        else if(ticTacToe(0,3,6)){
            //System.out.println("Player " + grid[0]+ " wins");
            return true;
        }
        else if(ticTacToe(1,4,7)){
            //System.out.println("Player " + grid[1] + " wins");
            return true;
        }
        else if(ticTacToe(2,5,8)){
            //System.out.println("Player " + grid[2] + " wins");
            return true;
        }else if(ticTacToe(2,4,6)){
            //System.out.println("Player " + grid[2] + " wins");
            return true;
        }
        else
            return isDrawn();
    }

    public boolean ticTacToe(int x, int y, int z){
        /*
        * check is x, y and z has the same value
        */
        try{
            Integer.parseInt(grid[x]);
            return false;
        }catch(NumberFormatException e){
        if( grid[x].equals(grid[y])
                && grid[x].equals(grid[z]))
            return true;
        else
            return false;
        }
    }

    public String getSquare(int i){
        return grid[i];
    }

    @Override
    public String toString(){
        String msg = "";
        for(int i=0; i<grid.length; i++){
            msg = msg + grid[i] + " ";
            if(i==2 || i==5)
                msg = msg+ "\n";
        }
        return msg;
    }

    public boolean isDrawn(){
        /*
        * check to see if there are any 'free' spaces on the board, if there are any
        * return false, else return true
        */
        for(int i=0; i<grid.length; i++){
        try{
            Integer.parseInt(grid[i]);
            return false;
            }catch(NumberFormatException e){
            }
        }
        System.out.println("Game drawn");
        return true;
    }

    public String[] getBoard(){
        return grid;
    }

    public int noOfEmpty(){
        //EFFECT: returns the number of empty squares
        int count = 0;
        for(int i=0; i<grid.length; i++)
            if (!(grid[i].equalsIgnoreCase("X") || grid[i].equalsIgnoreCase("O")))
                count++;
        return count;
    }

    public int heuristicValue(Board b){
        String MAX = "X", MIN = "O";
        /*
        * calculate a value that will be used as a heuristic function
        * the function works for ever X in a row WITHOUT O: 1 point,
        * for two X in a row WITHOUT a O: 5 points
        * and 3 X in a row: 100 points
        */
        //System.out.println("Computing heuristic");
        //System.out.println("Computing horizontals");
        int hCount = 0;
        //sum up the horizontals
        for(int i=0; i<9; i=i+3){
            int tmpMAX = playerCount(b, MAX,i,i+1,i+2);
            int tmpMIN = playerCount(b, MIN,i,i+1,i+2);
            //System.out.println(tmpMAX);
            //System.out.println(tmpMIN);
            if(tmpMIN > 0){
                //System.out.println("Min was zero");
            }
            else if(tmpMAX==1){
                //System.out.println("has one");
                hCount = hCount + 1;
            }
            else if(tmpMAX==2){
                //System.out.println("was tw0");
                hCount = hCount + 5;
            }
            else if(tmpMAX==3){
                //System.out.println("full 100");
                hCount = hCount + 100;
            }
        }
        //System.out.println("Computing verticals");
        //sum up the verticals
        for(int i=0; i<3; i++){
            int tmpMAX = playerCount(b, MAX,i,i+3,i+6);
            int tmpMIN = playerCount(b, MIN,i,i+3,i+6);
            if(tmpMIN > 0){}
            else if(tmpMAX==1){
                hCount = hCount +1;
            }
            else if(tmpMAX==2){
                hCount = hCount + 5;
            }
            else if(tmpMAX==3){
                hCount = hCount + 100;
            }
        }
        //System.out.println("Computing diagonals");
        //sum up diagonals
        if(playerCount(b, MIN,0,4,8)==0){

            if(playerCount(b, MAX,0,4,8)==1){
                hCount = hCount + 1;
            }
            if(playerCount(b, MAX,0,4,8)==2)
                hCount = hCount + 5;
            if(playerCount(b, MAX,0,4,8)==3)
                hCount = hCount + 100;
        }
        if(playerCount(b, MIN,2,4,6)==0){

            if(playerCount(b, MAX,2,4,6)==1){
                hCount = hCount + 1;
            }
            if(playerCount(b, MAX,2,4,6)==2)
                hCount = hCount + 5;
            if(playerCount(b, MAX,2,4,6)==3)
                hCount = hCount + 100;
        }
        //System.out.println("Computing completed");
        int hV = hCount;
        return hV;
    }

    int playerCount(Board b, String player, int x, int y, int z){
        int count = 0;
        if(b.getSquare(x).equals(player))
            count = count + 1;
        if(b.getSquare(y).equals(player))
            count = count + 1;
        if(b.getSquare(z).equals(player))
            count = count + 1;
        //System.out.println("playerCount; " + count);
        return count;
    }
}

import java.io.*;

import java.io.IOException;

公共类主要{

public static void main(String[] args) throws IOException{
    BufferedReader  reader = new BufferedReader(new
                                            InputStreamReader(System.in));
    Board thisGame = new Board();
    System.out.println("Start \n" + thisGame.toString());
    MinMax.createTree(thisGame);
    System.exit(0);
}

}

I am trying to recursively populate a tree, but my code is only only fill out one depth length, and then quiting. i.e. each node only has one child. Is there something am failing to take in to consideration?

public static void populate(Node n, int depth, String player){
    System.out.println("Depth: " + depth);
    if(player.equalsIgnoreCase("X"))
        player = "O";
    else
        player = "X";
    int j = 0;
    System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
    for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
        if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
                || ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
            j++;
        else{
            Board tmp = new Board(((Board)n.getData()), j, player);
            Node newNode = new Node(tmp);
            tree.insert(n, newNode);
            populate(newNode, depth-1, player);
        }
    }
}

P.S. and i check the noOfEmpty() return value, which should determine the number of children a node should have.

edit:@eznme the complete code as requested:

public class MinMax {

    protected static Tree tree;


    public static void createTree(Board b){
        tree = new Tree();
        tree.setRoot(new Node(b));
        populate(tree.getRoot(), 5, "X");
        //System.out.println("printing tree");
        //tree.print(1);
    }

    public static void populate(Node n, int depth, String player){
        System.out.println("Depth: " + depth);
        if(player.equalsIgnoreCase("X"))
            player = "O";
        else
            player = "X";
        int j = 0;
        System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
        for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
            if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
                    || ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
                j++;
            else{
                Board tmp = new Board(((Board)n.getData()), j, player);
                Node newNode = new Node(tmp);
                tree.insert(n, newNode);
                populate(newNode, depth-1, player);
            }
        }
    }
}

import java.util.ArrayList;

/**
*
* @author Greg
*/
public class Node {

    protected Object data;
    protected int score; //fields to be used by the MaxMin class
    protected ArrayList<Node> children;

    //constructors
    public Node(){
        children = new ArrayList(0);
        data = null;
    }
    public Node(Object obj){
        children = new ArrayList(0);
        data = obj;
    }


    public void setChild(Node n){
        //EFFECT: set the ith child to node t
        children.add(n);
    }
    public void setChildren(Node[] t){
        //EFFECT: copy the array t, into the array children, effectively
        // setting all the chidern of this node simultaneouly
        int l = children.size();
        for(int i=0; i<t.length; i++){
            children.add(l, t[i]);
        }
    }
    public void setData(Object obj){
        //EFFECT: set the date of this node to obj, and also set the number of
        //  children this node has
        data = obj;
    }
    public Node getChild(int i){
        //EFFECT: returns the child at index i
        return children.get(i);
    }

    public int noOfChildren(){
        //EFFECT: return the length of this node
            return children.size();
    }

    public Object getData(){
        //EFFECT: returns the data of this node
        return data;
    }

    @Override
    public String toString(){
        //EFFECT: returns the string form of this node
        return "" + data.toString() + "\nwith " + noOfChildren()+ "\n";
    }

    public boolean isLeaf(){
        if(children.size()==0)
            return true;
        return false;
    }


    public void setScore(int scr){
        score = scr;
    }

    public int getScore(){
            return score;
    }
}

public class Tree {

    private Node root;

    public Tree(){
        setRoot(null);
    }

    public Tree(Node n){
        setRoot(n);
    }

    public Tree(Object obj){
        setRoot(new Node(obj));
    }

    protected Node getRoot(){
        return root;
    }

    protected void setRoot(Node n){
        root = n;
    }

    public boolean isEmpty(){
        return getRoot() == null;
    }

    public Object getData(){
        if(!isEmpty())
            return getRoot().getData();
        return null;
    }

    public Object getChild(int i){
        return root.getChild(i);
    }

    public void setData(Object obj){
        if(!isEmpty())
            getRoot().setData(obj);
    }

    public void insert(Node p,Node c){
        if(p != null)
            p.setChild(c);
    }

    public void print(int mode){
        if(mode == 1) pretrav();
        else if(mode == 2) postrav();
        else
            System.out.println("yeah... mode 1 or 2...nothing else, try agn");
    }

    public void pretrav(){
        pretrav(getRoot());
    }

    protected void pretrav(Node t){
        if(t == null)
            return;
        System.out.println(t.getData()+" \n");
            for(int i=0; i<t.noOfChildren(); i++)
                pretrav(t.getChild(i));
    }

    public void postrav(){
        postrav(getRoot());
    }

    protected void postrav(Node t){
        if(t == null)
            return;
        System.out.print(t.getData()+" ");
            for(int i=0; i<t.noOfChildren(); i++)
                pretrav(t.getChild(i));
        System.out.print(t.getData()+" ");
    }
}

public class Board {

    boolean isFull = false;         // a check to see if the board is full
    String[] grid = new String[9];  //an array represting the 9 square on a board
    int hV;
    String MIN, MAX;

    public Board(){
        for(int i=0; i<grid.length;i++)
            grid[i] = Integer.toString(i);
        hV = heuristicValue(this);
    }

    public Board(Board b, int x, String player){
        this.grid = b.getBoard();
        if(!(grid[x].equalsIgnoreCase("X")|| grid[x].equalsIgnoreCase("X")))
            grid[x] = player;
    }

    public boolean setSquare(String player, int position){
        /*
        EFFECT:set a square on the board to either a X or a O, debending on the player
        PRECON: square (x,y) is empty
        POATCON: square (x,y) has player 'symbol'
        */

        boolean isValidPlay = false;
        try{
            //as a sanity
            Integer.parseInt(grid[position]);
            grid[position] = player;
            isValidPlay = true;

        }catch(NumberFormatException e){
            System.out.println("positon " + position + "is already occupied");
        }
        return isValidPlay;
    }

    public boolean endGame(){
        /*
        * EFFECT: check to see if the game have been won or drawn
        */
        if(ticTacToe(0,1,2)){
            //System.out.println("Player " + grid[0] + " wins");
            return true;
        }
        else if(ticTacToe(3,4,5)){
            //System.out.println("Player " + grid[3] + " wins");
            return true;
        }
        else if(ticTacToe(6,7,8)){
            //System.out.println("Player " + grid[6] + " wins");
            return true;
        }
        else if(ticTacToe(0,4,8)){
            //System.out.println("Player " + grid[0]+ " wins");
            return true;
        }
        else if(ticTacToe(0,3,6)){
            //System.out.println("Player " + grid[0]+ " wins");
            return true;
        }
        else if(ticTacToe(1,4,7)){
            //System.out.println("Player " + grid[1] + " wins");
            return true;
        }
        else if(ticTacToe(2,5,8)){
            //System.out.println("Player " + grid[2] + " wins");
            return true;
        }else if(ticTacToe(2,4,6)){
            //System.out.println("Player " + grid[2] + " wins");
            return true;
        }
        else
            return isDrawn();
    }

    public boolean ticTacToe(int x, int y, int z){
        /*
        * check is x, y and z has the same value
        */
        try{
            Integer.parseInt(grid[x]);
            return false;
        }catch(NumberFormatException e){
        if( grid[x].equals(grid[y])
                && grid[x].equals(grid[z]))
            return true;
        else
            return false;
        }
    }

    public String getSquare(int i){
        return grid[i];
    }

    @Override
    public String toString(){
        String msg = "";
        for(int i=0; i<grid.length; i++){
            msg = msg + grid[i] + " ";
            if(i==2 || i==5)
                msg = msg+ "\n";
        }
        return msg;
    }

    public boolean isDrawn(){
        /*
        * check to see if there are any 'free' spaces on the board, if there are any
        * return false, else return true
        */
        for(int i=0; i<grid.length; i++){
        try{
            Integer.parseInt(grid[i]);
            return false;
            }catch(NumberFormatException e){
            }
        }
        System.out.println("Game drawn");
        return true;
    }

    public String[] getBoard(){
        return grid;
    }

    public int noOfEmpty(){
        //EFFECT: returns the number of empty squares
        int count = 0;
        for(int i=0; i<grid.length; i++)
            if (!(grid[i].equalsIgnoreCase("X") || grid[i].equalsIgnoreCase("O")))
                count++;
        return count;
    }

    public int heuristicValue(Board b){
        String MAX = "X", MIN = "O";
        /*
        * calculate a value that will be used as a heuristic function
        * the function works for ever X in a row WITHOUT O: 1 point,
        * for two X in a row WITHOUT a O: 5 points
        * and 3 X in a row: 100 points
        */
        //System.out.println("Computing heuristic");
        //System.out.println("Computing horizontals");
        int hCount = 0;
        //sum up the horizontals
        for(int i=0; i<9; i=i+3){
            int tmpMAX = playerCount(b, MAX,i,i+1,i+2);
            int tmpMIN = playerCount(b, MIN,i,i+1,i+2);
            //System.out.println(tmpMAX);
            //System.out.println(tmpMIN);
            if(tmpMIN > 0){
                //System.out.println("Min was zero");
            }
            else if(tmpMAX==1){
                //System.out.println("has one");
                hCount = hCount + 1;
            }
            else if(tmpMAX==2){
                //System.out.println("was tw0");
                hCount = hCount + 5;
            }
            else if(tmpMAX==3){
                //System.out.println("full 100");
                hCount = hCount + 100;
            }
        }
        //System.out.println("Computing verticals");
        //sum up the verticals
        for(int i=0; i<3; i++){
            int tmpMAX = playerCount(b, MAX,i,i+3,i+6);
            int tmpMIN = playerCount(b, MIN,i,i+3,i+6);
            if(tmpMIN > 0){}
            else if(tmpMAX==1){
                hCount = hCount +1;
            }
            else if(tmpMAX==2){
                hCount = hCount + 5;
            }
            else if(tmpMAX==3){
                hCount = hCount + 100;
            }
        }
        //System.out.println("Computing diagonals");
        //sum up diagonals
        if(playerCount(b, MIN,0,4,8)==0){

            if(playerCount(b, MAX,0,4,8)==1){
                hCount = hCount + 1;
            }
            if(playerCount(b, MAX,0,4,8)==2)
                hCount = hCount + 5;
            if(playerCount(b, MAX,0,4,8)==3)
                hCount = hCount + 100;
        }
        if(playerCount(b, MIN,2,4,6)==0){

            if(playerCount(b, MAX,2,4,6)==1){
                hCount = hCount + 1;
            }
            if(playerCount(b, MAX,2,4,6)==2)
                hCount = hCount + 5;
            if(playerCount(b, MAX,2,4,6)==3)
                hCount = hCount + 100;
        }
        //System.out.println("Computing completed");
        int hV = hCount;
        return hV;
    }

    int playerCount(Board b, String player, int x, int y, int z){
        int count = 0;
        if(b.getSquare(x).equals(player))
            count = count + 1;
        if(b.getSquare(y).equals(player))
            count = count + 1;
        if(b.getSquare(z).equals(player))
            count = count + 1;
        //System.out.println("playerCount; " + count);
        return count;
    }
}

import java.io.*;

import java.io.IOException;

public class Main {

public static void main(String[] args) throws IOException{
    BufferedReader  reader = new BufferedReader(new
                                            InputStreamReader(System.in));
    Board thisGame = new Board();
    System.out.println("Start \n" + thisGame.toString());
    MinMax.createTree(thisGame);
    System.exit(0);
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蔚蓝源自深海 2024-10-27 10:02:08

为了递归地构建一棵 n 叉树,我会这样做:

public static void populate(Node n, int height){
    if(height = 0){
        n = new Node();  
    }else{
        n = new Node();
        for(int i = 0; i < n.nbChilds(); i++){
            populate(n.getChildAt(i), height - 1);
        }
    }
}

我希望它有帮助。

使用此算法创建节点的顺序(在二叉树上):

              1
      2                9
  3       6        10     13
4  5    7   8    11  12 14  15

In order to recursively build a n-ary tree, I would do this:

public static void populate(Node n, int height){
    if(height = 0){
        n = new Node();  
    }else{
        n = new Node();
        for(int i = 0; i < n.nbChilds(); i++){
            populate(n.getChildAt(i), height - 1);
        }
    }
}

I hope it helps.

Order of nodes creation with this algo (on a binary tree):

              1
      2                9
  3       6        10     13
4  5    7   8    11  12 14  15
有深☉意 2024-10-27 10:02:08

因此,这就是我在您的情况下要做的事情(最小最大井字棋):

术语:

  • 节点的高度:从该节点到其更远的叶子的距离。
  • 节点深度:从树根到该节点的距离。

你必须不断尝试所有情况,直到:棋盘已满或一名玩家获胜。因此,树的高度为 numberOfCells + 1
如果我们简化问题并且不用担心对称重复:
每个节点都有 numberOfcells - nodeDepth 子节点。

public static void main(String[] args){
    Tree t = new Tree();
    int nbCells = 9;
    t.setRoot(buildTree(new Board(nbCells), 0, -1));
}

public static Node buildTree(Board b, int player, int positionToPlay){
    if(player != 0){
        b.setCellAt(positionToPlay, player);
    }
    Node n = new Node(b, b.nbEmptyCells());

    int j = 0;
    for(int i = 0; i < b.nbCells(); i++){
        if(b.getCellAt(i) == 0)
            n.setChildAt(j++, buildTree(new Board(b), changePlayer(player), i));
    }

return n;
}

public static int changePlayer(int p){
    switch(p){
    case 0:
        return 1;
    case 1:
        return 2;
    case 2:
        return 1;
    default:
        return 0;
    }
}

节点类:

public class Node {
    private Board board;
    private Node[] childs;

    public Node(Board b, int nbChilds){
        this.board = new Board(b);
        this.childs = new Node[nbChilds];
    }

    public Node getChildAt(int i){
        return childs[i];
    }

    public int nbChilds(){
        return childs.length;
    }

    public void setChildAt(int i, Node n){
        this.childs[i] = n;
    }

    public Board getBoard(){
        return this.board;
    }

So here is what I would do in your case (minimax tic-tac-toe):

Terminology:

  • Height of a node: Distance from this node to it's further leaf.
  • Depth of a node: Distance from the root of the tree, to this node.

You have to keep trying all cases until: the board is full OR one player won. So, your tree's height is numberOfCells + 1.
If we simplify the problem and don't worry about symmetric duplicates:
Each node will have numberOfcells - nodeDepth childs.

public static void main(String[] args){
    Tree t = new Tree();
    int nbCells = 9;
    t.setRoot(buildTree(new Board(nbCells), 0, -1));
}

public static Node buildTree(Board b, int player, int positionToPlay){
    if(player != 0){
        b.setCellAt(positionToPlay, player);
    }
    Node n = new Node(b, b.nbEmptyCells());

    int j = 0;
    for(int i = 0; i < b.nbCells(); i++){
        if(b.getCellAt(i) == 0)
            n.setChildAt(j++, buildTree(new Board(b), changePlayer(player), i));
    }

return n;
}

public static int changePlayer(int p){
    switch(p){
    case 0:
        return 1;
    case 1:
        return 2;
    case 2:
        return 1;
    default:
        return 0;
    }
}

Node class:

public class Node {
    private Board board;
    private Node[] childs;

    public Node(Board b, int nbChilds){
        this.board = new Board(b);
        this.childs = new Node[nbChilds];
    }

    public Node getChildAt(int i){
        return childs[i];
    }

    public int nbChilds(){
        return childs.length;
    }

    public void setChildAt(int i, Node n){
        this.childs[i] = n;
    }

    public Board getBoard(){
        return this.board;
    }
以可爱出名 2024-10-27 10:02:08

我认为你的方法是错误的。
首先,您正在执行循环递归,除了使用没有意义的深度变量之外,因为您从不检查它的值来结束递归,或者了解你想做什么。
在循环本身中使用动态函数不太好,因为应该从循环开始就很好地定义迭代。
i 在您的上下文中毫无用处。

因此,如果我理解您的代码,有问题的情况是存在 3 个空方块和 4 个非空方块,因为您将从 0 迭代到 3,除了递增 j 之外什么都不做 从 0 到 3 然后退出,因为 i 会达到 3。

当然,我可能在某些点上犯了错误,因为我不知道 tree 是什么,它从哪里来?和n有关系吗?什么是板子。

我希望我的贡献可以帮助您,并鼓励您发布更多详细信息以澄清漏洞,并使我能够为您提供更多帮助。

I think you got a wrong approach.
First of all, you're doing a loop and recursion, besides using a depth variable that has no meaning since you never check it's value either to end the recursion, or to know something about what you want to do.
The use a a dynamic function within the loop itself is not quite good, since the iteration should be well defined from the beginning of the loop.
i is just useless in your context.

So if I understand your code, a problematic case would be a case where there is 3 empty squares and 4 non empty squares since you would iterate i from 0 to 3 and do nothing but incrementing j from 0 to 3 then exit because i would have reach 3.

Of course I may be mistaken on some points because I don't know what tree is, from where did it come from? is it related to n? What is a board.

I hope my contribution can help you and I encourage you to post more details to clarify the holes and enable me to help you a bit more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文