实验序号:实验三
实验名称:基于 A*搜索算法迷宫游戏开发
实验要求
1) 迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫;

2)要求查找并理解迷宫生成的算法,并尝试用两种不同的算法来生成随机的迷宫。

3)要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘
方向键控制,并在行走路径上留下痕迹;系统走迷宫路径要求基于 A*算法实现,输
出走迷宫的最优路径并显示。设计交互友好的游戏图形界面。

4) 选做:① 基于 A*算法的八数码问题

日志
1.完成的部分:目前已完成符合要求的1.0版本
2.代码如下:

package experiment3;import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Stack;
import javax.swing.JOptionPane;class Yard extends Frame{private static final long serialVersionUID = 1L;public static final int BLOCK = 19;public static final int BLOCK_SIZE = 30;public static final int Xpadding = 30 ;public static final int Ypadding = 50 ;public static int X=0;public static int Y=0;public static boolean drawPath = false;private Lattice[][] maze;Image offScreenImage = null;public void launch() {this.setLocation(500,100);this.setSize(Xpadding*2+BLOCK * BLOCK_SIZE,Ypadding*2+BLOCK * BLOCK_SIZE);this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});this.setVisible(true);this.setTitle("迷宫测试");maze = new Lattice[BLOCK][BLOCK];for (int i = 0; i <= BLOCK - 1; i++) {for (int j = 0; j <= BLOCK - 1; j++) {maze[i][j] = new Lattice(i, j);}}createMaze();this.setFocusable(true);setKeyListener();}@Overridepublic void paint(Graphics g) {g.setColor(Color.PINK);g.fillRect(30,50,BLOCK * BLOCK_SIZE,BLOCK * BLOCK_SIZE);g.setColor(Color.black);//画出横线竖线for(int i=1; i<BLOCK+2; i++) {g.drawLine(30 , 20+BLOCK_SIZE * i, 30+BLOCK * BLOCK_SIZE, 20+BLOCK_SIZE * i);}for(int i=1; i<BLOCK+2; i++) {g.drawLine(BLOCK_SIZE * i, 50 , BLOCK_SIZE * i, 50+BLOCK * BLOCK_SIZE);}for (int i = BLOCK - 1; i >= 0; i--) {for (int j = BLOCK - 1; j >= 0; j--) {Lattice f = maze[i][j].getFather();if (f != null) {int fx = f.getX(), fy = f.getY();Clear(i, j, fx, fy, g);}}}g.setColor(Color.PINK);g.drawLine(Xpadding, Ypadding + 1, Xpadding, Ypadding + BLOCK_SIZE - 1);g.drawLine(Xpadding+BLOCK*BLOCK_SIZE, Ypadding+BLOCK*BLOCK_SIZE - 1, Xpadding+BLOCK*BLOCK_SIZE, Ypadding+BLOCK*BLOCK_SIZE - BLOCK_SIZE + 1);g.setColor(Color.RED);g.fillOval(getCenterX(Y) - BLOCK_SIZE / 3, getCenterY(X) - BLOCK_SIZE / 3,BLOCK_SIZE / 2, BLOCK_SIZE / 2);if (drawPath == true) {drawPath(g);//new Solve(g);}}public int getCenterX(int x) {return Xpadding + x * BLOCK_SIZE + BLOCK_SIZE / 2;}public int getCenterY(int y) {return Ypadding + y * BLOCK_SIZE + BLOCK_SIZE / 2;}public int getCenterX(Lattice p) {return Xpadding + p.getY() * BLOCK_SIZE + BLOCK_SIZE / 2;}public int getCenterY(Lattice p) {return Ypadding + p.getX() * BLOCK_SIZE + BLOCK_SIZE / 2;}private boolean Out(int x, int y) {return (x > BLOCK - 1 || y > BLOCK - 1 || x < 0 || y < 0) ? true : false;}public void update(Graphics g) {if(offScreenImage == null) {offScreenImage = this.createImage(60+BLOCK*BLOCK_SIZE,80+BLOCK*BLOCK_SIZE);}Graphics gOff = offScreenImage.getGraphics();paint(gOff);g.drawImage(offScreenImage, 0, 0, null);}public boolean Stop(int x,int y) {if (!Out(X, Y) && (maze[x][y].getFather() == maze[X][Y]|| maze[X][Y].getFather() == maze[x][y])){return true;}else {return false;}}private void checkWin() {if (X == BLOCK - 1 && Y == BLOCK - 1) {JOptionPane.showMessageDialog(null, "游戏结束", "你走出了迷宫。",JOptionPane.PLAIN_MESSAGE);}}class Lattice{private int x = 0;private int y = 0;private boolean check = false;private Lattice father = null;public Lattice(int x, int y) {this.x = x;this.y = y;}public void setCheck(boolean c){check = c;}public void setFather(Lattice f) {father = f;}public Lattice getFather() {return father;}public boolean getcheck(){return check;}public int getX(){return x;}public int getY(){return y;}}private void Clear(int i, int j, int fx, int fy, Graphics g) {int sx = Xpadding + ((j > fy ? j : fy) * BLOCK_SIZE),sy = Ypadding + ((i > fx ? i : fx) * BLOCK_SIZE),dx = (i == fx ? sx : sx + BLOCK_SIZE),dy = (i == fx ? sy + BLOCK_SIZE : sy);if (sx != dx) {sx++;dx--;} else {sy++;dy--;}g.setColor(Color.PINK);g.drawLine(sx, sy, dx, dy);}private void createMaze() {Random random = new Random();int rx = 0;//Math.abs(random.nextInt()) % BLOCK;int ry = 0;//Math.abs(random.nextInt()) % BLOCK;Stack<Lattice> s = new Stack<Lattice>();Lattice p = maze[rx][ry];Lattice e[] = null;s.push(p);while (!s.isEmpty()) {p = s.pop();p.setCheck(true);e = Ergodic(p);int ran = Math.abs(random.nextInt()) % 4;for (int a = 0; a <= 3; a++) {ran++;ran %= 4;if (e[ran] == null || e[ran].getcheck() == true) {continue;}s.push(e[ran]);e[ran].setFather(p);}}     }private Lattice[] Ergodic(Lattice p) {final int[] adds = {-1, 0, 1, 0, -1};// 顺序为上右下左if (Out(p.getX(), p.getY())) {return null;}Lattice[] ps = new Lattice[4];// 顺序为上右下左int xt;int yt;for (int i = 0; i <= 3; i++) {xt = p.getX() + adds[i];yt = p.getY() + adds[i + 1];if (Out(xt, yt)) {continue;}ps[i] = maze[xt][yt];}return ps;}synchronized private void move(int c) {int tx = X, ty = Y;switch (c) {case KeyEvent.VK_LEFT :ty--;break;case KeyEvent.VK_RIGHT :ty++;break;case KeyEvent.VK_UP :tx--;break;case KeyEvent.VK_DOWN :tx++;break;case KeyEvent.VK_SPACE :if (drawPath == true) {drawPath = false;} else {drawPath = true;}break;default :}if (Stop(tx,ty)) {X = tx;Y = ty;}}//**键盘监听private void setKeyListener() {this.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {int c = e.getKeyCode();move(c);repaint();checkWin();}});}class Solve{int startx = X, starty = Y;int endx = BLOCK - 1 , endy = BLOCK - 1;List<Position> open;Solve(Graphics g) {Position start = new Position(startx, starty, null);Position end = null;open.add(start);while(true) {Position chosed = open.remove(0);if(chosed.x == endx && chosed.y == endy) {end = chosed;break;}if(Stop(chosed.x-1, chosed.y)) {addToOpenList(new Position(chosed.x-1, chosed.y, chosed));}if(Stop(chosed.x+1, chosed.y)) {addToOpenList(new Position(chosed.x+1, chosed.y, chosed));}if(Stop(chosed.x, chosed.y-1)) {addToOpenList(new Position(chosed.x, chosed.y-1, chosed));}if(Stop(chosed.x, chosed.y+1)) {addToOpenList(new Position(chosed.x, chosed.y+1, chosed));}}Position tmp = end;while(tmp != null) {g.drawLine(getCenterX(tmp.x), getCenterY(tmp.y), getCenterX(tmp.lastPosition.x),getCenterY(tmp.lastPosition.x));tmp = tmp.lastPosition;}}class Position {int x;int y;Position lastPosition;int pastDistance = 0;int predictDistance;Position(int x, int y, Position lastPosition) {this.x = x;this.y = y;this.lastPosition = lastPosition;if(lastPosition != null) {pastDistance = lastPosition.pastDistance + 1;}predictDistance = BLOCK*2 - 2 - this.x - this.y;}int distance(){return pastDistance + predictDistance;}}void addToOpenList(Position q) {Iterator<Position> itr = open.iterator();int index = -1;while(itr.hasNext()) {Position tmp = itr.next();index++;if(q.distance() <= tmp.distance()) {open.add(index, q);return;}}open.add(q);}}private void drawPath(Graphics g) {Color PATH_COLOR = Color.BLUE, BOTH_PATH_COLOR = Color.PINK;g.setColor(PATH_COLOR);Lattice p = maze[BLOCK - 1][BLOCK - 1];while (p.getFather() != null) {p = p.getFather();}p = maze[BLOCK - 1][BLOCK - 1];while (p.getFather() != null) {g.setColor(BOTH_PATH_COLOR);g.drawLine(getCenterX(p), getCenterY(p), getCenterX(p.getFather()),getCenterY(p.getFather()));p = p.getFather();}g.setColor(PATH_COLOR);p = maze[BLOCK - 1][BLOCK - 1];while (p.getFather() != null) {g.drawLine(getCenterX(p), getCenterY(p), getCenterX(p.getFather()),getCenterY(p.getFather()));p = p.getFather();}}
}
public class Maze1 {public static void main(String[] args) {new Yard().launch();}
}

3实例如下


学习的资料

《Java程序设计教程》机械工业出版社 程科 潘磊主编 ISBN 978-7-111-50902-8

20201227

计算机软件实习每日学习打卡(6)20201227相关推荐

  1. 10.24 每日学习打卡

    包装类wrapper 针对8种基本类型相应的引用类型 装箱操作为各包装类的valueof方法(默认调用) 包装类和String类型的转换 包装类->String 新建str对象 toString ...

  2. 每日辣评:微信禁朋友圈学习打卡、明星生图、支付宝、小红书

    文/王易见 知名科技KOL,四川创业者联盟发起人 QQ:543415188,微信:543415188 ,约稿.公关.营销传播.欢迎合作! [微信禁朋友圈"学习打卡",我是这么看的] ...

  3. 艾为数字ic面试题_每日学习:数字后端面试100问(2019全新版)

    关注并标星大同学吧 每天1次,打卡学习 积累1个新知识,增1分职场底气 作者称谓:Tao涛 个人介绍:摸爬滚打多年的数字后端工程师 微信公众号:数字后端IC芯片设计 半导体知识分享第29期 技能升级, ...

  4. bin文件如何编辑_每日学习:Linux文件与目录管理常用命令解析

    关注并标星大同学吧 每天1次,打卡学习 积累1个新知识,增1分职场底气 作者称谓:Jack xu 个人介绍:不断学习的数字后端工程师 微信公众号:志芯 半导体知识分享第25期 技能升级,从这里开始 1 ...

  5. java时序图工具_每日学习:静态时序分析入门面面观

    关注并标星大同学吧 每天1次,打卡学习 积累1个新知识,增1分职场底气 作者称谓:Jack xu 个人介绍:不断学习的数字后端工程师 微信公众号:志芯 半导体知识分享第41期 技能升级,从这里开始 本 ...

  6. 前端捕捉轨迹_基于JavaScript实现每日签到打卡轨迹功能

    本文实例为大家分享了js实现每日签到打卡轨迹功能的具体代码,供大家参考,具体内容如下 1. 核心文件 calendar.js var calUtil = { //当前日历显示的年份 showYear: ...

  7. 基于微信小程序的每日签到打卡

    社会的发展和科学技术的进步,互联网技术越来越受欢迎.手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用.手机具有便利性,速度快,效率高,成本低等优点. 因此,构建符合自己要求的操作系统是非常 ...

  8. html5 签到系统功能,项目实战之基于JavaScript实现每日签到打卡轨迹功能

    今天扣丁学堂HTML5培训老师给大家介绍一下关于js实现每日签到打卡轨迹功能的具体代码,希望对同学们学习HTML5开发有所帮助,下面我们一起来看一下吧. 1.核心文件calendar.js var c ...

  9. 计算机软件实习日志(三)基于 A*搜索算法迷宫游戏开发

    文章目录 界面展示 前言 一.实验要求? 二.实验准备 三.设计思路 1.A*算法的理解 算法描述 简化搜索区域 简化地图 概述算法步骤 进一步解释 具体寻路过程 F值计算方式: 2.开发思路 使用Q ...

  10. 计算机软件实习(一)简单计算机

    计算机软件实习(一)简单计算机 实验内容: (1) 学习图形界面的设计,利用 MFC 应用程序(Java swing 或 QT 框架,或 C#)创 建基于对话框的应用程序,添加按钮.编辑框等控件: ( ...

最新文章

  1. java io流读写文件换行_java基础io流——OutputStream和InputStream的故事(温故知新)...
  2. PIC单片机精通_异步串口通讯实例与细节
  3. ECMAScript6 新特性——“字符串的扩展”
  4. C语言数组中找到第一个重复元素的算法(附完整源码)
  5. 用计算机画函数图象,信息技术应用 用计算机画函数图象优秀公开课教案
  6. ROS入门(一) 文件结构篇
  7. tcp压测工具_掌门全链路灰度压测实战
  8. 室温金刚石共聚焦平台
  9. python中除法运算_python除法运算
  10. Linux中Sort命令详解
  11. matlab 把连续函数离散,连续传递函数离散化
  12. JAVA WEB开发技术作业 HTML国家奖学金申请审批表
  13. Swift 读标准库源码笔记 -- Integers(基本数据类型篇)
  14. IJCAI‘22 推荐系统论文梳理
  15. AIDE手机编程初级教程(零基础向) 1.2 初识界面编程
  16. Onenet麒麟迷你板开发过程【附程序】
  17. 抑郁症最新研究进展(2021年11月)
  18. 计算机专业有哪些【含金量超高竞赛】?
  19. mysql 复制 1032_mysql slave复制1032错误解决方法
  20. xilinx ip video

热门文章

  1. 【论文阅读】Advances and challenges in conversational recommender systems: A survey
  2. 数据库基本操作和练习
  3. 【Redis 系列】redis 学习十五,redis sds数据结构和底层设计原理
  4. 的欧美HTML游戏,国外十大HTML5、JavaScript 3D游戏引擎和框架
  5. 2003服务器安全策略
  6. illegal TFTP operation
  7. #L190616楼市穿越与未来锚点
  8. python随机漫步_Python实现随机漫步功能
  9. WinServer服务器IP访问白名单设置
  10. Python爬取下载网易云音乐