欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java语言程序设计 第十五章(15.34、15.35、15.36)自回避*漫步

程序员文章站 2024-03-23 21:11:04
...

程序小白,希望和大家多交流,共同学习
Java语言程序设计 第十五章(15.34、15.35、15.36)自回避*漫步
15.34、15.35
Java语言程序设计 第十五章(15.34、15.35、15.36)自回避*漫步

//画16 x 16网格
import javafx.scene.shape.Line;
import javafx.scene.paint.Color;
import javafx.scene.layout.Pane;

public class Grid_16X16Pane extends Pane
{
    private Color color;
    private int length = 20;//此大小合适,不给出控制方法

    public Grid_16X16Pane()
    {
        this(Color.color(0, 0, 0, 0.5));
    }

    public Grid_16X16Pane(Color color)
    {
        this.color = color;
        paintLines();
    }

    public void paintLines()
    {
        for (int i = 0; i < 17; i++)
        {
            Line line = new Line(0, i * length, 16 * length, i * length);
            line.setStroke(color);
            super.getChildren().add(line);
        }
        for (int j = 0; j < 17; j++)
        {
            Line line = new Line(j * length, 0, j * length, 16 * length);
            line.setStroke(color);
            super.getChildren().add(line);
        }
    }
}
//画路径
import javafx.scene.shape.Polyline;
import javafx.collections.ObservableList;
import javafx.scene.paint.Color;
import java.util.Arrays;

public class DrawPath extends Grid_16X16Pane 
{
    private int[][] points;
    private boolean[] direction;
    private int pX;
    private int pY;
    private Polyline path;
    private ObservableList<Double> list;
    private double x;
    private double y;
    private int totalPoints;

    public DrawPath()
    {
        points = new int[17][17];
        direction = new boolean[4];

        path = new Polyline();
        list = path.getPoints();
        path.setStroke(Color.RED);
        super.getChildren().add(path);
    }
    public void stroll()
    {
        list.remove(0, totalPoints);//去除已有的所有点
        super.getChildren().remove(path);//去除旧的路径

        pX = 8;//路径起始点在二维数组中的位置
        pY = 8;
        x = 160.0;//路径的起始点,在折线中的位置
        y = 160.0;
        totalPoints = 2;//起始中心点连个数据

        //将二维数组的各个数值初始为0
        for (int i = 0; i < 17; i++)
        {
            Arrays.fill(points[i], 0);
        }

        points[pX][pY] = 1;//封住已走的路
        list.add(x);
        list.add(y);

        boolean start = true;
        while (start)
        {
            int record = 0;//确定有几条路可以走
            Arrays.fill(direction, false);
            if (points[pX][pY - 1] == 0)
            {
                record++;
                direction[0] = true;
            }

            if (points[pX + 1][pY] == 0)
            {
                record++;
                direction[1] = true;
            }

            if (points[pX][pY + 1] == 0)
            {
                record++;
                direction[2] = true;
            }

            if (points[pX - 1][pY] == 0)
            {
                record++;
                direction[3] = true;
            }

            int random = (int)(Math.random() * record);//选择走第几条可以走的路从0开始
            int trueNum = -1;//统计可以走的路
            for (int i = 0; i < 4; i++)
            {
                if (direction[i])
                {
                    trueNum++;
                    if (random == trueNum)//可以走的路和选中第几条匹配
                    {
                        //System.out.println(record + " " + random + " " + trueNum);
                        //System.out.println(Arrays.toString(direction));
                        switch (i)//i此时表示的才是哪一种路径,0上1有2下3左
                        {
                        case 0:
                            y -= 20; --pY; break;
                        case 1:
                            x += 20; ++pX; break;
                        case 2:
                            y += 20; ++pY; break;
                        case 3:
                            x -= 20; --pX; break;
                        }
                        points[pX][pY] = 1;//封住已走的路
                        totalPoints += 2;//每加上一个点,就多两个数据
                        break;
                    }
                }
            }

            if (trueNum == -1)//无路可走
            {
                break;
            }
            list.add(x);//添加路径节点
            list.add(y);

            if (x  <= 0 || x >= 320 || y <= 0 || y >= 320)//到达边界,无路可走
            {
                break;
            }
        }
    }

    public void start()
    {
        stroll();
        super.getChildren().add(path);
    }
}
//测试DrawPath

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.geometry.Pos;

public class TestDrawPath extends Application
{
    @Override
    public void start(Stage primaryStage)
    {
        BorderPane pane = new BorderPane();
        DrawPath grid = new DrawPath();
        pane.setCenter(grid);

        Button start = new Button("Start");
        pane.setBottom(start);
        pane.setAlignment(start, Pos.CENTER);

        start.setOnAction(e -> {
            grid.start();
        });
        Scene scene = new Scene(pane, 320, 350);
        primaryStage.setTitle("TestDrawPath");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
//画路径动画
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.animation.Timeline;
import javafx.animation.Animation;
import javafx.util.Duration;
import javafx.animation.KeyFrame;
import java.util.Arrays;
import java.util.ArrayList;
import javafx.event.EventHandler;
import javafx.event.ActionEvent;

public class DrawPathAnimationPane extends Grid_16X16Pane
{
    private Timeline animation;
    private ArrayList<Double> pathList;//路径点集
    private int[][] pointsArray;//确定路径节点是否已走,未走为0,已走为1
    private boolean[] direction;//存储下一步可走方向0上1有2下3左
    private int arrayX;//路径节点数组坐标
    private int arrayY;
    private double pointsX;//路径列表坐标
    private double pointsY;
    private int pointsDataNum;//路径总数据个数
    private int pathListIndex;

    public DrawPathAnimationPane()
    {
        pointsArray = new int[17][17];
        direction = new boolean[4];
        pathList = new ArrayList<>();
        pointsDataNum = 0;
    }

    public void showAnimation()
    {
        updatePath();
        EventHandler<ActionEvent> eventHandler = e -> {
            drawLine();
        };

        animation = new Timeline(new KeyFrame(Duration.millis(1000), eventHandler));
        animation.setCycleCount(pointsDataNum / 2 - 1);
        animation.play();
    }

    public void drawLine()
    {
        Line line = new Line(pathList.get(pathListIndex), pathList.get(pathListIndex + 1),
            pathList.get(pathListIndex + 2), pathList.get(pathListIndex + 3));
        line.setStroke(Color.RED);
        super.getChildren().add(line);
        pathListIndex += 2;
    }

    public void updatePath()
    {
        pathListIndex = 0;
        pathList.clear();

        for (int i = 0; i < 17; i++)
        {
            Arrays.fill(pointsArray[i], 0);
        }

        arrayX = 8;
        arrayY = 8;
        pointsX = 160.0;
        pointsY = 160.0;

        pathList.add(pointsX);
        pathList.add(pointsY);

        pointsArray[arrayX][arrayY] = 1;
        pointsDataNum += 2;

        boolean start = true;

        while (start)
        {
            Arrays.fill(direction, false);
            int access = 0;

            if (pointsArray[arrayX][arrayY - 1] == 0)
            {
                access++;
                direction[0] = true;
            }
            if (pointsArray[arrayX + 1][arrayY] == 0)
            {
                access++;
                direction[1] = true;
            }
            if (pointsArray[arrayX][arrayY + 1] == 0)
            {
                access++;
                direction[2] = true;
            }
            if (pointsArray[arrayX - 1][arrayY] == 0)
            {
                access++;
                direction[3] = true;
            }

            int whichWay = (int)(Math.random() * access);

            int getWay = -1;
            for (int i = 0; i < 4; i++)
            {
                if (direction[i] == true)
                {
                    getWay++;
                    if (getWay == whichWay)
                    {
                        switch (i)
                        {
                        case 0:
                            arrayY--; pointsY -= 20; break;
                        case 1:
                            arrayX++; pointsX += 20; break;
                        case 2:
                            arrayY++; pointsY += 20; break;
                        case 3:
                            arrayX--; pointsX -= 20; break;
                        }
                        pointsArray[arrayX][arrayY] = 1;
                        pathList.add(pointsX);
                        pathList.add(pointsY);
                        pointsDataNum += 2;
                        break;
                    }
                }
            }

            if (getWay == -1)
            {
                break;
            }

            if (pointsX <= 0 || pointsX >= 320 || pointsY <= 0 || pointsY >= 320)
            {
                break;
            }
        }
    }
}
//测试DrawPathAnimation

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.geometry.Pos;

public class TestDrawPathAnimation extends Application
{
    private boolean first;
    @Override
    public void start(Stage primaryStage)
    {
        BorderPane pane = new BorderPane();
        DrawPathAnimationPane grid = new DrawPathAnimationPane();
        pane.setTop(grid);

        Button start = new Button("Start");
        pane.setCenter(start);
        pane.setAlignment(start, Pos.CENTER);

        first = true;
        start.setOnAction(e -> {
            if (first)
            {
                grid.showAnimation();
                first = false;
            }

        });
        Scene scene = new Scene(pane, 320, 370);
        primaryStage.setTitle("TestDrawPathAnimation");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

15.36

//获得漫步最后结果
import java.util.Arrays;

public class GetPath 
{
    private int[][] points;
    private boolean[] direction;
    private int pX;
    private int pY;

    private int number;
    private int totalPoints;

    public GetPath(int number)
    {
        this.number = number;
        points = new int[number][number];
        direction = new boolean[4];
    }
    public int stroll()
    {
        pX = 8;
        pY = 8;
        totalPoints = 2;

        //将二维数组的各个数值初始为0
        for (int i = 0; i < number; i++)
        {
            Arrays.fill(points[i], 0);
        }

        points[pX][pY] = 1;//封住已走的路

        boolean start = true;
        while (start)
        {
            int record = 0;//确定有几条路可以走
            Arrays.fill(direction, false);
            if (points[pX][pY - 1] == 0)
            {
                record++;
                direction[0] = true;
            }

            if (points[pX + 1][pY] == 0)
            {
                record++;
                direction[1] = true;
            }

            if (points[pX][pY + 1] == 0)
            {
                record++;
                direction[2] = true;
            }

            if (points[pX - 1][pY] == 0)
            {
                record++;
                direction[3] = true;
            }

            int random = (int)(Math.random() * record);//选择走第几条可以走的路从0开始
            int trueNum = -1;//统计可以走的路
            for (int i = 0; i < 4; i++)
            {
                if (direction[i])
                {
                    trueNum++;
                    if (random == trueNum)//可以走的路和选中第几条匹配
                    {
                        switch (i)//i此时表示的才是哪一种路径,0上1有2下3左
                        {
                        case 0:
                            pY--; break;
                        case 1:
                            pX++; break;
                        case 2:
                            pY++; break;
                        case 3:
                            pX--; break;
                        }
                        points[pX][pY] = 1;//封住已走的路
                        break;
                    }
                }
            }

            if (trueNum == -1)//无路可走
            {
                return -1;
            }

            if (pX <= 0 || pX >= number - 1 || pY <= 0 || pY >= number - 1)
            {
                return 1;
            }
        }
        return 0;
    }
}
public class UseGetPath
{
    public static void main(String[] args)
    {
        for (int i = 10; i <= 80; i++)
        {
            int totalEnd = 0;
            GetPath path = new GetPath(i);
            for (int j = 0; j < 10000; j++)
            {
                int num = path.stroll();
                if (num == -1)
                {
                    totalEnd++;
                }
            }
            double result = totalEnd / 100;
            System.out.print("For a lattice of size " + i + ", the probability of dead-end paths is ");
            System.out.println(String.format("%.1f%%", result));
        }

    }
}