Java语言程序设计基础篇_编程练习题***18.33 (游戏:骑士旅途的动画)

目录

***18.33 (游戏:骑士旅途的动画)

习题思路

代码示例

动画演示


***18.33 (游戏:骑士旅途的动画)

  为骑士旅途的问题编写一个程序,该程序应该允许用户将骑士放到任何一个起始正方形,并单击Solve按钮,用动画展示骑士沿着路径的移动,如图18-16所示

  • 习题思路

  1. 初始化棋盘和骑士位置

    1. Board类:这个内部类继承自Pane,用于绘制棋盘和骑士。棋盘通过绘制水平和垂直线来创建,而骑士则通过红色圆圈表示。
    2. draw方法:此方法用于绘制棋盘和骑士。首先清除所有子节点,然后绘制棋盘网格和初始骑士位置(红色圆圈)。骑士有两个圆圈表示:theKnight(静态位置)和movingKnight(用于动画的移动位置)。
    3. startX和startY:这两个变量用于记录骑士的起始位置。初始时,它们被设置为(0, 0),即棋盘的左上角。但用户可以通过点击棋盘上的任意格子来改变这些值。
  2. 点击事件处理

    1. 当用户在棋盘上点击时,Board类中的setOnMouseClicked事件处理器会被触发。
    2. 事件处理器计算点击位置对应的格子索引(startXstartY),这是通过将鼠标点击的坐标除以每个格子的大小(棋盘宽度/SIZE或棋盘高度/SIZE)并取整来实现的。
    3. 随后,重置moves列表,即骑士的移动历史,为新的求解过程做准备。
  3. 求解按钮点击事件

    1. 当用户点击“Solve”按钮时,会触发一个事件处理器,该处理器执行以下步骤:
    2. 初始化棋盘状态:创建一个boolean[][] moves数组来跟踪哪些格子已被访问。将起始位置标记为已访问。
    3. 重置和添加起始移动:调用resetMoves()addMove(startX, startY)来重置移动历史并添加起始位置到历史中。
    4. 递归求解:调用solvePuzzle(moves, 1, startX, startY)开始递归求解过程。该方法尝试从当前位置出发,找到所有可能的下一步,并评估哪一步能导致最少的未访问格子数(通过lookAheadCount方法)。然后,它选择最优的下一步,并递归地尝试解决剩余的问题。
    5. 动画展示:如果找到解决方案,draw方法会被再次调用以更新棋盘上的骑士位置(尽管在这个实现中,movingKnight并未在动画中实际移动),然后调用playAnimation方法来展示骑士的移动路径。
  4. 动画展示

    1. playAnimation方法:此方法使用SequentialTransitionPathTransition来创建动画,展示骑士沿着求解路径移动的过程。对于moves列表中的每一对相邻点,它创建一个PathTransition,该过渡使一个红色圆圈沿着两点之间的直线移动。所有这些过渡被添加到一个SequentialTransition中,以便按顺序播放。
  • 代码示例

编程练习题18_33TheKnightJourney.java

package chapter_18;  import java.util.ArrayList;
import javafx.animation.PathTransition;
import javafx.animation.SequentialTransition;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;  
import javafx.scene.Scene;  
import javafx.scene.control.Button;  
import javafx.scene.layout.BorderPane;  
import javafx.scene.layout.Pane;  
import javafx.scene.paint.Color;  
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.util.Duration;  public class 编程练习题18_33TheKnightJourney extends Application {private static final int SIZE = 8;private int startX = 0;private int startY = 0;private ArrayList<Point2D> moves = null;private ArrayList<Line> pathList;public static void main(String[] args) {  Application.launch(args);  }  @Override  public void start(Stage primaryStage) throws Exception {pathList = new ArrayList<Line>();BorderPane pane = new BorderPane();Board board = new Board();pane.setCenter(board);Button btSolve = new Button("Solve");pane.setBottom(btSolve);BorderPane.setAlignment(btSolve, Pos.CENTER);Scene scene = new Scene(pane,400,400);primaryStage.setTitle("编程练习题18_33TheKnightJourney");primaryStage.setScene(scene);primaryStage.show();board.draw();btSolve.setOnAction(e -> {boolean[][] moves = new boolean[SIZE][SIZE];moves[startX][startY] = true;resetMoves();addMove(startX,startY);solvePuzzle(moves,1,startX,startY);board.draw();board.playAnimation(pathList);});}private boolean solvePuzzle(boolean[][] moves,int numberMoves,int x,int y) {int nextX = 0;int nextY = 0;int bestMoveX = 0;int bestMoveY = 0;int bestMoveX2 = 0;int bestMoveY2 = 0;int minMoveCount = SIZE;int moveCount = 0;for(int i = 2;i >= -2;i += -4) {for(int j = 1;j >= -1;j += -2) {nextX = x + i;nextY = y + j;if(nextX >= 0&&nextX <= SIZE-1&&nextY >= 0&&nextY <= SIZE-1&&!moves[nextX][nextY]) {moveCount = lookAheadCount(moves,nextX,nextY);if(moveCount <= minMoveCount) {minMoveCount = moveCount;bestMoveX2 = bestMoveX;bestMoveY2 = bestMoveY;bestMoveX = nextX;bestMoveY = nextY;}}nextX = x + j;nextY = y + i;if(nextX >= 0&&nextX <= SIZE-1&&nextY >= 0&&nextY <= SIZE-1&&!moves[nextX][nextY]) {moveCount = lookAheadCount(moves,nextX,nextY);if(moveCount <= minMoveCount) {minMoveCount = moveCount;bestMoveX2 = bestMoveX;bestMoveY2 = bestMoveY;bestMoveX = nextX;bestMoveY = nextY;}}}}moves[bestMoveX][bestMoveY] = true;addMove(bestMoveX,bestMoveY);numberMoves++;if(numberMoves == (SIZE * SIZE))return true;if(moveCount > 0&&solvePuzzle(moves, numberMoves, bestMoveX, bestMoveY))return true;moves[bestMoveX][bestMoveY] = false;moves[bestMoveX2][bestMoveY2] = true;removeLastMoveHistory();addMove(bestMoveX2,bestMoveY2);if(moveCount > 1&&solvePuzzle(moves, numberMoves, bestMoveX2, bestMoveY2)) {return true;}moves[bestMoveX2][bestMoveY2] = false;removeLastMoveHistory();numberMoves--;return false;}private int lookAheadCount(boolean[][] moves,int x,int y) {int maxCount = 0;for(int i = -2;i<=2;i+=4) {for(int j = -1;j <= 1;j += 2) {int nextX = x + i;int nextY = y + j;if(nextX >= 0&&nextX <= SIZE-1&&nextY >=0 && nextY <= SIZE-1&&!moves[nextX][nextY]) {maxCount++;}nextX = x + j;nextY = y + i;if(nextX >= 0&&nextX <= SIZE-1&&nextY >= 0&&nextY <= SIZE-1&&!moves[nextX][nextY])maxCount++;}}return maxCount;}public void resetMoves() {moves = new ArrayList(63);}public void addMove(int x,int y) {moves.add(new Point2D(x, y));}public void removeLastMoveHistory() {moves.remove(moves.size()-1);}private class Board extends Pane{Circle theKnight = new Circle();Circle movingKnight = new Circle();Board(){this.setOnMouseClicked(e ->{startX = (int)(e.getX()/(getWidth()/SIZE));startY = (int)(e.getY()/(getHeight()/SIZE));resetMoves();draw();});}protected void draw() {this.getChildren().clear();this.getChildren().add(theKnight);theKnight.setCenterX(startX * getWidth()/SIZE +15);theKnight.setCenterY(startY * getHeight()/SIZE + 15);theKnight.setRadius(5);theKnight.setFill(Color.RED);movingKnight.setCenterX(startX * getWidth()/SIZE +15);movingKnight.setCenterY(startY * getHeight()/SIZE + 15);movingKnight.setRadius(5);movingKnight.setFill(Color.RED);this.getChildren().add(movingKnight);for(int i = 1;i <= SIZE;i++) {this.getChildren().add(new Line(0,i*getHeight()/SIZE,getWidth(),i*getHeight()/SIZE));			                     this.getChildren().add(new Line(i*getWidth()/SIZE,0,i*getWidth()/SIZE,getHeight()));}if(moves != null) {for(int i = 1;i < moves.size();i++) {Point2D p1 = moves.get(i - 1);Point2D p2 = moves.get(i);Line line = new Line(p1.getX()*(getWidth()/SIZE)+(getWidth()/SIZE/2),p1.getY()*(getHeight()/SIZE)+(getHeight()/SIZE/2),p2.getX()*(getWidth()/SIZE)+(getWidth()/SIZE/2),p2.getY()*(getHeight()/SIZE)+(getHeight()/SIZE/2));pathList.add(line);}}}private void playAnimation(ArrayList<Line> lines) {int i = 0;SequentialTransition sequentialTransition = new  SequentialTransition();Circle c;c = new Circle(5);c.setFill(Color.RED);getChildren().add(c);for(Line l: lines) {PathTransition transition = new PathTransition(Duration.seconds(1), l, c);transition.setOnFinished(e->{if(i<lines.size()-2) {getChildren().add(l);}});sequentialTransition.getChildren().add(transition);}sequentialTransition.play();}}
}
  • 动画演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/54692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习之表示学习 - 贪心逐层无监督预训练篇

引言 在人工智能的浩瀚星空中&#xff0c;深度学习以其强大的数据处理与模式识别能力&#xff0c;成为了一颗璀璨的明星。而表示学习&#xff0c;作为深度学习的核心基石之一&#xff0c;正引领着这一领域不断突破边界。表示学习旨在将原始数据转换为更加抽象、更有意义的特征…

leetcode第二十六题:删去有序数组的重复项

给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你…

Rasa对话模型——做一个语言助手

1、Rasa模型 1.1 模型介绍 Rasa是一个用于构建对话 AI 的开源框架&#xff0c;主要用于开发聊天机器人和语音助手。Rasa 提供了自然语言理解&#xff08;NLU&#xff09;和对话管理&#xff08;DM&#xff09;功能&#xff0c;使开发者能够创建智能、交互式的对话系统。 1.2…

Apache Iceberg 数据类型参考表

Apache Iceberg 概述-链接 Apache Iceberg 数据类型参考表 数据类型描述实例方法注意事项BOOLEAN布尔类型&#xff0c;表示真或假true, false用于条件判断&#xff0c;例如 WHERE is_active true。确保逻辑条件的正确性。INTEGER32位有符号整数42, -7可用于计算、聚合&#xf…

【系统架构设计师】专题:中间件技术

更多内容请见: 备考系统架构设计师-核心总结目录 文章目录 一、中间件概述二、中间件特点三、中间件的分类四、中间件产品介绍一、中间件概述 中间件(middleware) 是基础软件的一大类,属于可复用软件的范畴。顾名思义,中间件处在操作系统、网络和数据库之上,应用软件的下层…

着色器ShaderMask

说明 实现一个渐变进度条&#xff0c;要求&#xff1a; 颜色渐变的过程是循序渐进的&#xff0c;而不是看起来像是将渐变条逐渐拉长了。 效果 源码 // 渐变进度条Stack(children: [// 背景色板Container(width: 300,height: 8,decoration: BoxDecoration(borderRadius: Bord…

ollama 部署教程(window、linux)

目录 一、官网 二、安装方式一&#xff1a;window10版本下载 三、安装方式二&#xff1a;linux版本docker 四、 模型库 五、运行模型 六、API服务 七、python调用 ollama库调用 langchain调用 requests调用 aiohttp调用 八、模型添加方式 1.线上pull 2.导入 GGU…

Parallels Desktop 20 for Mac 推出:完美兼容 macOS Sequoia 与 Win11 24H2

Parallels Desktop 20 for Mac 近日正式发布&#xff0c;这一新版本不仅全面支持 macOS Sequoia 和 Windows 11 24H2&#xff0c;还在企业版中引入了一个全新的管理门户。新版本针对 Windows、macOS 和 Linux 虚拟机进行了多项改进&#xff0c;其中最引人注目的当属 Parallels …

C++编程语言:基础设施:源文件和程序(Bjarne Stroustrup)

第15章 源文件和程序 (Source Files and Programs) 目录 15.1 单独编译(Separate Compilation) 15.2 链接(Linkage) 15.2.1 文件局部名(File-Local Names) 15.2.2 头文件(Header Files) 15.2.3 一次定义原则(The One-Definition Rule) 15.2.4 标准库头文件 1…

基于YOLOv8+LSTM的商超扶梯场景下行人安全行为姿态检测识别

基于YOLOv8LSTM的商超扶梯场景下行人安全行为姿态检测识别 手扶电梯 行为识别 可检测有人正常行走&#xff0c;有人 跌倒&#xff0c;有人逆行三种行为 跌倒检测 电梯跌倒 扶梯跌倒 人体行为检测 YOLOv8LSTM。 基于YOLOv8LSTM的商超扶梯场景下行人安全行为姿态检测识别&#xf…

STM32上实现FFT算法精准测量正弦波信号的幅值、频率和相位差(标准库)

在研究声音、电力或任何形式的波形时&#xff0c;我们常常需要穿过表面看本质。FFT&#xff08;快速傅里叶变换&#xff09;就是这样一种强大的工具&#xff0c;它能够揭示隐藏在复杂信号背后的频率成分。本文将带你走进FFT的世界&#xff0c;了解它是如何将时域信号转化为频域…

如何将Excel表格嵌入Web网页在线预览、编辑并保存到自己服务器上?

猿大师办公助手作为一款专业级的网页编辑Office方案&#xff0c;不仅可以把微软Office、金山WPS和永中Office的Word文档内嵌到浏览器网页中实现在线预览、编辑保存等操作&#xff0c;还可以把微软Office、金山WPS和永中Office的Excel表格实现网页中在线预览、编辑并保存到服务器…

python中ocr图片文字识别样例(二)

一、说明 本次解决图片相关出现中文乱码问题&#xff0c;属于上篇文章的优化&#xff0c;前提条件依赖上篇文章的包&#xff0c;当然ocr的具体应用场景很多&#xff0c;根据自身需求进行调整 二、具体实现 2.1 代码实现&#xff1a; # -*- coding: utf-8 -*- import easyoc…

3.《DevOps》系列K8S部署CICD流水线之部署MetalLB负载均衡器和Helm部署Ingress-Nginx

架构 服务器IP服务名称硬件配置192.168.1.100k8s-master8核、16G、120G192.168.1.101k8s-node18核、16G、120G192.168.1.102k8s-node28核、16G、120G192.168.1.103nfs2核、4G、500G操作系统:Rocky9.3 后续通过K8S部署GitLab、Harbor、Jenkins 为什么使用MetalLB 当使用云平…

在vue中:style 的几种使用方式

在日常开发中:style的使用也是比较常见的&#xff1a; 亲测有效 1.最通用的写法 <p :style"{fontFamily:arr.conFontFamily,color:arr.conFontColor,backgroundColor:arr.conBgColor}">{{con.title}}</p> 2.三元表达式 <a :style"{height:…

如何快速连接超2100家国内外快递物流公司、实现查询结果翻译为中/英文?

近年来&#xff0c;中国企业正不断加快“出海”步伐&#xff0c;“中企出海”也成为了2024年最重要的投资主题之一。 百递云API开放平台深刻理解这一趋势&#xff1a;在我们的客户群体中&#xff0c;既有贸易规模增长超数倍的跨境电商&#xff0c;还有国际业务越来越成为增长新…

ADB 安装教程:如何在 Windows、macOS 和 Linux 上安装 Android Debug Bridge

目录 一、ADB 介绍 二、Windows 系统安装 ADB 1. 下载 ADB 2. 解压文件 3. 验证 ADB 安装 4. 配置环境变量 5. 验证全局 ADB 使用 三、macOS 系统安装 ADB 1. 下载 ADB 2. 解压文件 3. 配置环境变量 4. 验证 ADB 安装 四、Linux 系统安装 ADB 1. 使用包管理器安装…

C++初阶学习——探索STL奥秘——模拟实现list类

1、基本框架 list 由三个类构建而成: 节点类:每个节点必须的三部分(指向前一个节点的指针、指向后一个节点的指针、当前节点存储的数据) 迭代器类:此时的迭代器为双向迭代器&#xff0c;比较特殊&#xff0c;需要对其进行封装&#xff0c;如 it并非使迭代器单纯向后移动&…

Python气象辐射光谱能量平衡模型

&#x1f3af;要点 根据温室模型&#xff0c;计算不同情景下辐射通量和评估能量平衡&#xff0c;构建复杂温室模型计算计算和绘图大气、海洋、陆地表面和海冰复合模型数据建立简单能量平衡情景模型&#xff0c;并根据模型计算释放温度和时滞&#xff0c;计算并绘制地面辐射和吸…

【QT】系统-下

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;QTheadrun() &#x1f449;&#x1f3fb;QMutex&#x1f449;&#x1f3fb;QWaitCondition&#x1f449;&#x1f3fb;Q…