Java语言程序设计 第十五章(15.34、15.35、15.36)自回避*漫步
程序员文章站
2024-03-23 21:11:04
...
程序小白,希望和大家多交流,共同学习
15.34、15.35
//画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));
}
}
}
下一篇: PAT常用函数