计算机软件实习项目三

学习目标:

基于A*搜索算法迷宫游戏开发

学习内容:

  1. 迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫;
  2. 要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系统走迷宫路径要求基于A*算法实现,输出走迷宫的最优路径并显示。
  3. 设计交互友好的游戏图形界面。

学习产出:

package maze;
import java.awt.;
import java.awt.event.
;
import java.util.;
import javax.swing.
;

class Lattice{
static final int INTREE=1;
static final int NOTINTREE=0;
private int x=-1;
private int y=-1;
private int flag=NOTINTREE;
private Lattice father=null;

public Lattice(int xx, int yy){
x=xx;
y=yy;
}

public int getX(){
return x;
}

public int getY(){
return y;
}

public int getFlag(){
return flag;
}

public Lattice getFather(){
return father;
}

public void setFather(Lattice f){
father=f;
}

public void setFlag(int f){
flag=f;
}

public String toString(){
return new String("("+x+","+y+")");
}
}

public class Maze extends JPanel{
private int NUM,width,padding;// width 每个格子的宽度和高度
private Lattice[][]maze;
private int ballX,ballY;
private boolean drawPath=false;

Maze(int m,int wi,int p){
NUM=m;
width=wi;
padding=p;
maze=new Lattice[NUM][NUM];
for(int i=0;i<=NUM-1;i++)
for(int j=0;j<=NUM-1;j++)
maze[i][j]=new Lattice(i, j);
createMaze();
setKeyListener();
this.setFocusable(true);
}

private void init(){
for(int i=0;i<=NUM-1;i++)
for(int j=0;j<=NUM-1;j++){
maze[i][j].setFather(null);
maze[i][j].setFlag(Lattice.NOTINTREE);
}
ballX=0;
ballY=0;
drawPath=false;
createMaze();
setKeyListener();
this.setFocusable(true);
repaint();
}

public int getCenterX(int x){
return padding+x*width+width/2;
}

public int getCenterY(int y){
return padding+y*width+width/2;
}

public int getCenterX(Lattice p){
return padding+p.getY()*width+width/2;
}
public int getCenterY(Lattice p){
return padding+p.getX()*width+width/2;
}

private void checkIsWin(){
if(ballXNUM-1&&ballYNUM-1){
JOptionPane.showMessageDialog(null,“You are win!”,“你走出了迷宫”,JOptionPane.PLAIN_MESSAGE);
init();
}
}

private synchronized void move(int c){ //同步方法
int tx=ballX,ty=ballY;
switch©{
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(!isOutOfBorder(tx,ty)
&& (maze[tx][ty].getFather()==maze[ballX][ballY]
||maze[ballX][ballY].getFather()==maze[tx][ty])){
ballX=tx;
ballY=ty;
}
}

private void setKeyListener(){
this.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
int c=e.getKeyCode();
move©;
repaint();
checkIsWin();
}
});
}

private boolean isOutOfBorder(Lattice p){
return isOutOfBorder(p.getX(), p.getY());
}

private boolean isOutOfBorder(int x,int y){
return (x>NUM-1||y>NUM-1||x<0||y<0)?true:false;
}

private Lattice[] getNeis(Lattice p){
final int[] adds={-1,0,1,0,-1};//顺序为上右下左
if(isOutOfBorder§){
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(isOutOfBorder(xt,yt))
continue;
ps[i] = maze[xt][yt];
}
return ps;
}

private void createMaze(){ //深度优先算法建立迷宫
Random random=new Random();
int rx=Math.abs(random.nextInt())%NUM;
int ry=Math.abs(random.nextInt())%NUM;
Stack s=new Stack();
Lattice p=maze[rx][ry];
Lattice neis[]=null;
s.push§;
while(!s.isEmpty()){
p=s.pop();
p.setFlag(Lattice.INTREE);
neis=getNeis§;
int ran=Math.abs(random.nextInt())%4;
for(int a=0;a<=3;a++){
ran++;
ran%=4;
if(neis[ran]==null||neis[ran].getFlag()==Lattice.INTREE)
continue;
s.push(neis[ran]);
neis[ran].setFather§;
}
}
}

private void changeFather(Lattice p,Lattice f){
if(p.getFather()==null){
p.setFather(f);
return;
} else{
changeFather(p.getFather(),p);
}
}

private void clearFence(int i,int j,int fx,int fy,Graphics g){
int sx=padding+((j>fy?j:fy)*width),
sy=padding+((i>fx?i:fx)*width),
dx=(ifx?sx:sx+width),
dy=(i
fx?sy+width:sy);
if(sx!=dx){
sx++;
dx–;
} else{
sy++;
dy–;
}
g.drawLine(sx,sy,dx,dy);
}

protected void paintComponent(Graphics g){
super.paintComponent(g);
for(int i=0;i<=NUM;i++){
g.drawLine(padding+iwidth,padding,padding+iwidth,padding+NUMwidth);
}
for(int j=0;j<=NUM;j++){
g.drawLine(padding,padding+j
width,padding+NUMwidth,padding+jwidth);
}
g.setColor(this.getBackground());
for(int i=NUM-1;i>=0;i–){
for(int j=NUM-1;j>=0;j–){
Lattice f=maze[i][j].getFather();
if(f!=null){
int fx=f.getX(),fy=f.getY();
clearFence(i,j,fx,fy,g);
}
}
}
g.drawLine(padding,padding+1,padding,padding+width-1);
int last=padding+NUM*width;
g.drawLine(last,last-1,last,last-width+1);
g.setColor(Color.RED);
g.fillOval(getCenterX(ballY)-width/3,getCenterY(ballX)-width/3,width/2,width/2);
if(drawPath == true)
drawPath(g);
}

private void drawPath(Graphics g){
Color PATH_COLOR=Color.ORANGE,BOTH_PATH_COLOR=Color.PINK;
if(drawPath==true)
g.setColor(PATH_COLOR);
else
g.setColor(this.getBackground());
Lattice p=maze[NUM-1][NUM-1];
while(p.getFather()!=null){
p.setFlag(2);
p=p.getFather();
}
g.fillOval(getCenterX§-width/3,getCenterY§-width/3,width/2,width/2);
p=maze[0][0];
while(p.getFather()!=null){
if(p.getFlag()==2){
p.setFlag(3);
g.setColor(BOTH_PATH_COLOR);
}
g.drawLine(getCenterX§,getCenterY§,getCenterX(p.getFather()),
getCenterY(p.getFather()));
p=p.getFather();
}
g.setColor(PATH_COLOR);
p=maze[NUM-1][NUM-1];
while(p.getFather()!=null){
if(p.getFlag()==3)
break;
g.drawLine(getCenterX§,getCenterY§,getCenterX(p.getFather()),
getCenterY(p.getFather()));
p=p.getFather();
}
}

public static void main(String[] args){
final int n=30,width=600,padding=20,LX=200,LY=100;
JPanel p=new Maze(n,(width-padding-padding)/n,padding);
JFrame frame=new JFrame(“MAZE(按空格键显示或隐藏路径)”);
frame.getContentPane().add§;
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width+padding,width+padding+padding);
frame.setLocation(LX, LY);
frame.setVisible(true);
}
}

使用了深度优先算法生成迷宫并生成路径,并未使用A*算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值