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

目录

题目:***18.32 (游戏:骑士的旅途)

习题思路

代码示例

 输出结果


题目:***18.32 (游戏:骑士的旅途)

骑士的旅途是一个古老的谜题,它的目的是使骑从棋盘上的任意一个正方 形开始移动,经过其他的每个正方形一次,如图18-15a 所示。注意,骑士只能做L形的移动(两个空格在一个方向上而一个空格在垂直的方向上)。如图18-15b 所示,骑士可以移动到八个正方形的位置。编写一个程序,显示骑士的移动,如图 18-15C 所示。当单击一个单元格的时候,骑士被放置在该单元格中。该单元格作为骑士的起始点。单击Solve按钮显示作为解答的路径。

  • 习题思路
  1. 界面设置
    • 使用BorderPane作为主布局,中心放置一个Board(自定义的Pane),用于绘制棋盘和骑士的移动路径。
    • 在底部添加一个按钮btSolve,用于触发求解过程。
    • 舞台(Stage)和场景(Scene)的设置,包括尺寸和标题。
  2. 棋盘和骑士的初始化
    • Board类中,通过draw方法绘制棋盘(网格线)和初始位置的骑士(红色圆圈)。
    • 骑士的初始位置(startXstartY)默认为(0, 0),但可通过鼠标点击棋盘上的任意格子来设置新的起始位置。
  3. 求解逻辑
    • 使用一个二维布尔数组moves来记录棋盘上的格子是否已被访问过。
    • solvePuzzle方法是一个递归函数,用于尝试不同的移动路径,直到找到一种能够遍历所有格子并返回起点的解决方案。
    • 在每一步尝试中,通过lookAheadCount方法评估每个可能的下一步移动,并选择看起来最有前景的(即下一步后能够访问最多新格子的)移动。
    • 使用回溯法,如果当前路径无法找到解决方案,则撤销上一步的选择,尝试其他可能的移动。
  4. 用户交互
    • 点击棋盘上的格子设置新的起始位置,并清空之前的移动历史。
    • 点击“Solve”按钮触发求解过程,并在找到解决方案后重新绘制棋盘,显示骑士的移动路径。
  5. 移动历史记录
    • 使用ArrayList<Point2D>来记录骑士的移动历史,以便在求解过程中回溯和重新绘制路径。
    • 提供resetMovesaddMoveremoveLastMoveHistory方法来管理移动历史记录。
  6. 棋盘绘制
    • Board类的draw方法中,除了绘制棋盘网格和骑士外,还根据移动历史记录绘制骑士的移动路径。
  • 代码示例

编程练习题18_32TheKnightJourney.java

package chapter_18;  import java.util.ArrayList;
import java.util.List;
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.HBox;  
import javafx.scene.layout.Pane;  
import javafx.scene.paint.Color;  
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;  public class 编程练习题18_32TheKnightJourney extends Application {  private static final int SIZE = 8;private int startX = 0;private int startY = 0;private ArrayList<Point2D> moves = null;public static void main(String[] args) {  Application.launch(args);  }  @Override  public void start(Stage primaryStage) throws Exception {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("");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();});}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();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);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);this.getChildren().add(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)));}}}}
}
  •  输出结果

 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3:v-model实现组件通信

目录 一.性质 1.双向绑定 2.语法糖 3.响应式系统 4.灵活性 5.可配置性 6.多属性绑定 7.修饰符支持 8.defineModel使用 二.使用 1.父组件 2.子组件 三.代码 1.父组件代码 2.子组件代码 四.效果 一.性质 在Vue3中&#xff0c;v-model指令的性质和作用主要体现在…

【漏洞复现】Casbin casdoor static 任意文件读取漏洞

漏洞描述 Casdoor 是 Casbin 开源社区推出的基于 OAuth 2.0 / OIDC 的中心化的单点登录(SSO)身份验证平台。 Casdoor static 存在任意文件读取漏洞,攻击者通过发送特殊的请求包可以获取服务器中的敏感文件。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵…

【第十一章:Sentosa_DSML社区版-机器学习分类】

目录 11.1 逻辑回归分类 11.2 决策树分类 11.3 梯度提升决策树分类 11.4 XGBoost分类 11.5 随机森林分类 11.6 朴素贝叶斯分类 11.7 支持向量机分类 11.8 多层感知机分类 11.9 LightGBM分类 11.10 因子分解机分类 11.11 AdaBoost分类 11.12 KNN分类 【第十一章&…

vue3+Element-plus el-input 输入框组件二次封装(支持金额、整数、电话、小数、身份证、小数点位数控制,金额显示中文提示等功能)

一、效果图 二、组件集成了以下功能 1、输入金额--支持千分号显示、可设置decimalLimit来调整小数点位数 2、金额鼠标移入提示中文--标签添加isTip开启中文提示则不允许开启千分号显示showThousands 3、输入手机号--设置inputTypephone 4、输入整数---设置inputTypeinteger 5、…

spring boot admin集成,springboot2.x集成监控

服务端&#xff1a; 1. 新建monitor服务 pom依赖 <!-- 注意这些只是pom的核心东西&#xff0c;不是完整的pom.xml内容&#xff0c;不能直接使用&#xff0c;仅供参考使用 --><packaging>jar</packaging><dependencies><dependency><groupId&g…

【图像检索】基于灰度共生矩的纹理图像检索,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于灰度共生矩的纹理图像检索&#xff0c;用matlab实现。 一、案例背景和算法介绍 …

供应商管理系统,比价系统,在线询价系统一体化(代码)

前言&#xff1a; 随着互联网和数字技术的不断发展&#xff0c;企业采购管理逐渐走向数字化和智能化。数字化采购平台作为企业采购管理的新模式&#xff0c;能够提高采购效率、降低采购成本、优化供应商合作效率&#xff0c;已成为企业实现效益提升的关键手段。系统获取在文末…

50k star!Openpilot这个开源项目,赶紧给自己的车安排上自动驾驶了

你有没有想过,有一天你的车可能比你更懂得如何开车?如果你每天被城市的堵车和高强度驾驶折磨,那么这篇文章一定能给你带来一些惊喜。今天我们要聊的是一个让车子“自学成才”的系统——Openpilot。该项目是 GitHub 上一个开局不到一个月的项目,目前已经快 50K 的 star 了。…

【C++掌中宝】深入解析C++命名空间:有效管理代码的利器

文章目录 前言1. namespace 的价值2. namespace 的定义3. 命名空间的本质4. 嵌套的命名空间5. 命名空间的使用6. using 指令7. 补充结语 前言 假设这样一种情况&#xff0c;当一个班上有两个名叫 Zara 的学生时&#xff0c;为了明确区分它们&#xff0c;我们在使用名字之外&am…

Modular Elven Archer 幻想精灵女弓箭手游戏角色模型

可爱的精灵射手的3D模型。用额外的骨骼固定到人形。完全模块化,包括一个没有衣服的身体。包含苹果混合形状。 下载:​​Unity资源商店链接资源下载链接 效果图:

Java-数据结构-优先级队列(堆)-(二) (゚▽゚*)

文本目录&#xff1a; ❄️一、PriorityQueue的常用接口&#xff1a; ➷ 1、PriorityQueue的特性&#xff1a; ➷ 2、使用PriorityQueue的注意&#xff1a; ➷ 3、PriorityQueue的构造&#xff1a; ☞ 1、无参数的构造方法&#xff1a; ☞ 2、有参数的构造方法&#xff1a; …

Error when custom data is added to Azure OpenAI Service Deployment

题意&#xff1a;在向 Azure OpenAI 服务部署添加自定义数据时出现错误。 问题背景&#xff1a; I receive the following error when adding my custom data which is a .txt file (it doesnt matter whether I add it via Azure Cognitive Search, Azure Blob Storage, or F…

uniApp微信小程序扫描普通二维码跳转到小程序指定页面操作方法

这篇文章主要给大家介绍了关于微信小程序扫描普通二维码跳转到小程序指定页面操作的相关资料,需要的朋友可以参考下 1、首先我们需要在微信公众平台的开发管理——>开发设置&#xff0c;找到&#xff08;扫普通链接二维码打开小程序&#xff09;&#xff0c;点击添加,根据提…

C++ 9.20

练习&#xff1a;定义一个矩形类&#xff08;Rectangle&#xff09;&#xff0c;包含私有成员宽度&#xff08;width&#xff09;、高度&#xff08;height&#xff09; 包含公共成员函数&#xff1a; 初始化矩形&#xff08;init&#xff09; 设置宽度&#xff08;set_w&am…

给儿童掏耳朵用哪个好?儿童耳勺最建议买的五个牌子

儿童的耳朵清洁是家长最烦恼的事情之一&#xff0c;近年来传统耳勺出现的意外新闻颇多&#xff0c;棉签等工具的表面粗糙&#xff0c;稍不注意就会刮伤儿童脆弱的耳道肌肤&#xff0c;那么除了这些以外&#xff0c;给儿童掏耳朵用哪个好&#xff1f; 小编建议家长都入一个可视挖…

唤醒数据中台潜力,加速数据飞轮转动:数据驱动秘籍

在这个数据爆炸的时代&#xff0c;企业的数据资产正变得越来越重要。然而&#xff0c;收集和存储数据只是数据驱动旅程的第一步。如何唤醒这些沉睡的数据&#xff0c;真正让它们为业务服务&#xff1f; 这才是企业成功的关键。 数据中台曾被视为整合企业内外数据资源的利器&am…

javascript 3 个有序点的方向(Orientation of 3 ordered points)

给定三个点 p1、p2 和 p3&#xff0c;任务是确定这三个点的方向。 平面中有序三重点的方向可以是 逆时针 顺时针 共线 下图显示了 (a,b,c) 的不同可能方向 如果 (p1, p2, p3) 的方向共线&#xff0c;则 (p3, p2, p1) 的方向也共线。 如果 (p1, p2, p3) 的方向是顺时针&a…

Python GUI 编程:tkinter 初学者入门指南——窗口

目录&#xff1a; 创建窗口更改窗口标题更改窗口大小和位置窗口在屏幕上居中窗口设置的其他属性 Tkinter 是在 Python 中开发 GUI&#xff08;图形用户界面&#xff09;最常用的库。在本指南中&#xff0c;我们将引导您了解 Tkinter 的基本知识&#xff0c;学习如何使用 Tkinte…

Vue3:自定义事件实现组件通信

目录 一.性质 1.双向通信 2.灵活性 3.传参能力 4.声明机制 5.事件验证 6.修饰符支持 7.响应式更新 8.解耦组件 9.易于测试 10.性能优化 二.使用 1.父组件 2.子组件 三.代码 1.父组件代码 2.子组件代码 四.效果 在Vue3中&#xff0c;自定义事件是实现组件间通…

NLP(二)-文本表示

One-hot One-hot&#xff08;独热&#xff09;编码是一种最简单的文本表示方式。如果有一个大小为V的词表&#xff0c;对于第i个词$w_i$&#xff0c;可以用一个长度为V的向量来表示&#xff0c;其中第i个元素为1&#xff0c;其它为0.例如&#xff1a; 减肥&#xff1a;[1, 0,…