java实现推箱子小游戏

本文实例为大家分享了java实现推箱子游戏的具体代码,供大家参考,具体内容如下

运行示例:

图形界面由swing组件构成

生成地图的算法如下

创建地图算法(produceMap):先将二维数组全置为1,代表初始状态全为墙。先随机产生两个不重合的点,一个作为人的起点,另一个作为箱子的起点。从起点开始,随机朝四个方向走一定的步数,若走到的点不是空地,即对应数组元素不为0,则将该点设为空地,即数组元素设为0。将地图分为左上、左下、右上和右下四个区域,并设置四个变量记录四个区域已开辟空地的数量。每开辟一块空地,代表该空地所在区域的变量加1。走完规定的步数后,在四个区域中找到开辟空地数量最小的区域,在该区域内随机产生一个点,以该点作为起点循环执行上述操作,直到开辟的空地的总数大于地图总面积的一半,创建完成。

解决地图算法(solveMap):创建一个状态类,将箱子的一个位置和在搜索这个箱子的过程中人的一个位置以及箱子走到这个位置的步数表示为一个状态。建立一个优先队列,队列元素为状态类的对象,步数小的状态的优先级高。从起点开始按照上下左右的顺序进行广度优先搜索。建立一个HashMap,键为状态类,值为布尔类,用来保存每个状态的是否被走过,再建立一个HashMap,键为点类,值也为点类,保存箱子的每一个位置的前一个位置,用于最后输出路径。使用优先队列可以使推动箱子次数多的状态推迟出队,从而保证箱子每个能推动的方向都被访问到并推动,若直接使用队列,则无法使每种情况都走到。而当地图较大的时候,采用HashMap存储访问信息可以节省较大的空间。优先队列每次执行出队操作的时候记录出队状态的步数,当当前出队状态的步数和上一个出队状态的步数不同的时候,将保存状态访问信息的HashMap清空。另设置一个HashMap键为点类,值为整型类,保存每个点箱子访问过几次,若超过四次,则不访问该点。由优先队列的性质可知,出队的状态的步数是队列中步数最小的状态,即当当前出队的状态的步数和前一个不同的时候,箱子前一步的状态已全部出队。这时箱子之前的访问状态已经不再需要,及时清空保存访问状态的HashMap可以节省很大的内存空间。当广搜搜到箱子在终点位置的状态,则搜索结束。若结束状态的步数小于规定的最小步数,则返回解决失败,否则返回解决成功。若未搜到箱子在终点位置的状态并且队列已空,则返回解决失败。

记录路径算法(recordPath):根据在解决地图的过程中建立的记录箱子每个位置前一个位置的一个HashMap,从终点开始,一步步找回起点,并将在这过程中找到的点按顺序入栈,然后再将栈中的点逐个出栈并记录在一个点的数组中,以实现路径的正序输出。

Main_Class.java

public class Main_Class {
 public static void main(String args[]) {
 PTB_Frame frame=new PTB_Frame("Push The Box");
 frame.setBounds(0,0,1200,1200);
 }
}

PTB_Frame.java

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
@SuppressWarnings("serial")

public class PTB_Frame extends JFrame {
 private Font font = new Font("宋体", Font.PLAIN, 23);
 private Map_Manager map_manager=new Map_Manager();
 private ConsolePanel console = new ConsolePanel(map_manager);
 private JButton creat_map=new JButton("创建地图");
 private MapPanel map=new MapPanel(map_manager);
 PTB_Frame(String title) {
 init();
 this.setTitle(title);
 this.setVisible(true);
 this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 }

 void init() {
 this.setLayout(null);
 console.setBounds(0, 0, 1200,250);
 console.add(creat_map);
 this.add(console);
 map.setBounds(80, 250, 1200, 800);
 this.add(map);
 creat_map.setFont(font);
 creat_map.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 console.creatMap();
 map.setMap(map_manager.getHeight(), map_manager.getWidth(), map_manager.getStepOfMap(), map_manager.getMap());
 map.creatMap();
 }
 });
 }
}

ConsolePanel.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

@SuppressWarnings("serial")
public class ConsolePanel extends JPanel {
 Font font = new Font("宋体", Font.PLAIN, 23);
 JTextField t_height = new JTextField(3);
 JTextField t_width = new JTextField(3);
 JTextField t_diff = new JTextField(5);
 JButton get_path = new JButton("查看最短路径");
 JTextArea show_path = new JTextArea(5, 40);
 int height, width;
 double diff;
 Map_Manager map_manager;

 ConsolePanel(Map_Manager map_manager) {
 this.map_manager = map_manager;
 UIManager.put("Label.font", font);
 this.add(new JLabel("地图高度:"));
 t_height.setFont(font);
 this.add(t_height);
 this.add(new JLabel("(3~100的整数)"));
 this.add(new JLabel("地图宽度:"));
 t_width.setFont(font);
 this.add(t_width);
 this.add(new JLabel("(3~100的整数)"));
 this.add(new JLabel("地图难度:"));
 t_diff.setFont(font);
 this.add(t_diff);
 this.add(new JLabel("(1.0~10.0之间的小数)"));
 this.add(new JLabel("注:地图高度和宽度以及难度越大,生成地图时间越长"));
 get_path.setFont(font);
 this.add(get_path);
 show_path.setFont(font);
 show_path.setLineWrap(true);// 自动换行
 show_path.setWrapStyleWord(true);// 换行不断字
 JPanel show_path_panel = new JPanel();
 show_path_panel.add(new JScrollPane(show_path));//滚动窗口
 this.add(show_path_panel);
 get_path.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 Map_Manager.Point path[] = map_manager.getPath();
 if (path != null) {
  show_path.setText(null);
  for (int i = 0; i<map_manager.getStepOfMap(); ++i)
  show_path.append(path[i] + " ");
 }
 }
 });
 }

 public void creatMap() {
 try {
 height = Integer.valueOf(t_height.getText());
 width = Integer.valueOf(t_width.getText());
 diff = Double.valueOf(t_diff.getText());
 if (height < 3 || height > 100 || width < 3 || width > 100 || diff < 1 || diff > 10)
 throw new NumberFormatException();
 map_manager.setMap(height, width, diff);
 map_manager.creatMap();
 show_path.setText(null);
 } catch (NumberFormatException ex) {
 JOptionPane.showMessageDialog(getRootPane(), "参数格式不正确");
 }
 }
}

MapPanel.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

@SuppressWarnings("serial")
public class MapPanel extends JPanel {
 private Font font = new Font("宋体", Font.PLAIN, 23);
 private JPanel map_area;
 JPanel control_bar = new JPanel();
 private JButton drawback, restart,start;
 private JLabel l_min_step, l_left_step, l_passed_step;
 private JLabel show_cur_point;
 private JLabel show_cur_box;
 private Point person = new Point();
 private Point start_of_person = new Point();
 private Point start_of_box = new Point();
 private Point end = new Point();
 private Point box = new Point();
 private int width, height;
 private int map[][] = new int[100][100];
 private int di[][] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
 private int min_step, passed_step = 0;
 private Stack<Operation> operation_recorder = new Stack<Operation>();
 private JButton block[][] = new JButton[100][100];
 private Map_Manager map_manager;

 private class Point implements Cloneable {
 int x, y;

 public boolean equals(Object obj) {
 if (!(obj instanceof Point))
 return false;
 Point point = (Point) obj;
 return this.x == point.x && this.y == point.y;
 }

 public Object clone() {
 Point newPoint = null;
 try {
 newPoint = (Point) super.clone();
 } catch (CloneNotSupportedException e) {
 e.printStackTrace();
 }
 return newPoint;
 }

 public String toString() {
 return "(" + (this.x + 1) + "," + (this.y + 1) + ")";
 }
 }

 public void setMap(int height, int width, int min_step, int map[][]) {
 this.height = height;
 this.width = width;
 this.min_step = min_step;
 this.map = map;
 }
 private class PtbKeyAdapter extends KeyAdapter {
 public void keyPressed(KeyEvent e) {
 int keycode = e.getKeyCode();
 if (keycode == KeyEvent.VK_UP) {
 pointMove(0);
 } else if (keycode == KeyEvent.VK_DOWN) {
 pointMove(1);
 } else if (keycode == KeyEvent.VK_LEFT) {
 pointMove(2);
 } else if (keycode == KeyEvent.VK_RIGHT) {
 pointMove(3);
 }
 }
 }

 private class Operation {
 int stuff;// 1代表箱子,0代表人
 int dir;// 0代表上,1代表下,2代表左,3代表右

 Operation(int stuff, int dir) {
 this.stuff = stuff;
 this.dir = dir;
 }
 }

 private boolean accessible(Point point) {// point可走则返回true
 if (point.x < 0 || point.x >= height || point.y < 0 || point.y >= width)// 越界
 return false;
 if (map[point.x][point.y] == 1)// 走到墙上
 return false;
 return true;
 }

 private void pointMove(int dir) {
 if(passed_step>=min_step)
 return;
 // 先判断能否进行交换,若能,则交换两按钮颜色值
 Point cur_point = new Point();
 cur_point.x = person.x + di[dir][0];
 cur_point.y = person.y + di[dir][1];
 if (!accessible(cur_point))// 当前点不可走
 return;
 if (cur_point.equals(box)) {
 // 当人前进方向上前一个点是箱子
 Point next_box = new Point();
 next_box.x = box.x + di[dir][0];
 next_box.y = box.y + di[dir][1];
 if (!accessible(next_box))// 箱子无法推动
 return;
 // 如果箱子能前进,则人也前进,不能则人不能前进
 go(box, dir);
 ++this.passed_step;
 updateStep();
 operation_recorder.push(new Operation(1, dir));
 }
 go(person, dir);
 show_cur_point.setText(" "+person.toString()+" ");
 operation_recorder.push(new Operation(0, dir));
 if (box.equals(end))
 JOptionPane.showMessageDialog(this.getRootPane(), "WINNER WINNER CHICKEN DINNER!");
 else if(this.passed_step==this.min_step)
 JOptionPane.showMessageDialog(this.getRootPane(), "江河犹在,命数已尽,悲哉!");
 }

 private void go(Point point, int dir) {// 实现前进部分的代码
 Color color = block[point.x][point.y].getBackground();
 if (point.equals(end))
 block[point.x][point.y].setBackground(Color.GREEN);
 else
 block[point.x][point.y].setBackground(Color.WHITE);
 point.x += di[dir][0];
 point.y += di[dir][1];
 block[point.x][point.y].setBackground(color);
 }

 private void updateStep() {
 l_passed_step.setText(Integer.toString(passed_step));
 l_left_step.setText(Integer.toString(min_step - passed_step));
 show_cur_box.setText(" "+box.toString()+" ");
 }

 public void paintMap() {
 map_area = new JPanel(new GridLayout(this.height, this.width));
 for (int i = 0; i < this.height; i++)
 for (int j = 0; j < this.width; j++) {
 block[i][j] = new JButton();
 if (map[i][j] == 0)// 数组中0为路
  block[i][j].setBackground(Color.WHITE);
 else if (map[i][j] == 1)// 数组中1为墙
  block[i][j].setBackground(Color.BLACK);
 else if (map[i][j] == 2)// 数组中2为箱子位置
 {
  block[i][j].setBackground(Color.BLUE);
  start_of_box.x = i;
  start_of_box.y = j;
 } else if (map[i][j] == 3)// 数组中3为终点
 {
  block[i][j].setBackground(Color.GREEN);
  end.x = i;
  end.y = j;
 } else if (map[i][j] == 4) {// 数组中4为人的位置
  block[i][j].setBackground(Color.RED);
  start_of_person.x = i;
  start_of_person.y = j;
 }
 map_area.add(block[i][j]);
 }
 person = (Point) start_of_person.clone();
 box = (Point) start_of_box.clone();
 l_min_step.setText(Integer.toString(min_step));
 show_cur_point.setText(" "+person.toString()+" ");
 passed_step=0;
 updateStep();
 int map_height=750,map_width=750;
 if(this.height>this.width)
 map_width=(750/this.height)*this.width;
 else if(this.width>this.height)
 map_height=(750/this.width)*this.height;
 map_area.setBounds(0, 0, map_width, map_height);
 this.add(map_area);
 }

 public MapPanel(Map_Manager map_manager) {
 this.map_manager = map_manager;
 init();
 }

 private void init() {
 this.setLayout(null);
 map_manager.setMap(20, 20, 7.0);
 map_manager.creatMap();
 this.height = map_manager.getHeight();
 this.width = map_manager.getWidth();
 this.min_step = map_manager.getStepOfMap();
 this.map = map_manager.getMap();
 UIManager.put("Label.font", font);
 drawback = new JButton("后退一步");
 restart = new JButton("重新开始");
 start=new JButton("开始");
 control_bar.add(new JLabel("当前箱子的位置"));
 show_cur_box=new JLabel();
 control_bar.add(show_cur_box);
 control_bar.add(new JLabel("当前人的位置"));
 show_cur_point=new JLabel();
 control_bar.add(show_cur_point);
 control_bar.add(new JLabel("最短步数:"));
 l_min_step = new JLabel();
 l_min_step.setFont(font);
 control_bar.add(l_min_step);
 control_bar.add(new JLabel("已走步数:"));
 l_passed_step = new JLabel();
 l_passed_step.setFont(font);
 control_bar.add(l_passed_step);
 control_bar.add(new JLabel("剩余步数:"));
 l_left_step = new JLabel();
 l_left_step.setFont(font);
 control_bar.add(l_left_step);
 control_bar.add(new JLabel("注:这里的步数是"));
 control_bar.add(new JLabel("箱子移动的步数"));
 control_bar.add(new JLabel("红色代表人"));
 control_bar.add(new JLabel("蓝色代表箱子"));
 control_bar.add(new JLabel("绿色代表终点"));
 restart.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 block[person.x][person.y].setBackground(Color.WHITE);
 person = (Point) start_of_person.clone();
 block[box.x][box.y].setBackground(Color.WHITE);
 box = (Point) start_of_box.clone();
 block[person.x][person.y].setBackground(Color.RED);
 block[box.x][box.y].setBackground(Color.BLUE);
 block[end.x][end.y].setBackground(Color.GREEN);
 passed_step = 0;
 show_cur_point.setText(" "+person.toString()+" ");
 updateStep();
 }
 });
 drawback.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 if (operation_recorder.empty())
  return;
 Operation cur_op = operation_recorder.peek();
 operation_recorder.pop();
 int dir;
 switch (cur_op.dir) {// 得到相反方向
 case 0:
  dir = 1;
  break;
 case 1:
  dir = 0;
  break;
 case 2:
  dir = 3;
  break;
 default:
  dir = 2;
 }
 // 推箱子的时候,箱子先走,人再走
 // 不推箱子的时候直接就是人走,所以栈顶元素始终是人的操作
 go(person, dir);// 人相反方向走一步
 show_cur_point.setText(" "+person.toString()+" ");
 if (!operation_recorder.empty()&&operation_recorder.peek().stuff == 1) {
  // 下一个是箱子,即人从该位置推动的箱子
  go(box, dir);// 箱子相反方向走一步
  operation_recorder.pop();
  --passed_step;
  updateStep();
 }
 }
 });
 PtbKeyAdapter ptbkeyadapter=new PtbKeyAdapter();
 start.addKeyListener(ptbkeyadapter);
 restart.addKeyListener(ptbkeyadapter);
 drawback.addKeyListener(ptbkeyadapter);
 start.setFont(font);
 restart.setFont(font);
 drawback.setFont(font);
 control_bar.add(start);
 control_bar.add(restart);
 control_bar.add(drawback);
 control_bar.setBounds(850, 100, 200, 600);
 this.paintMap();
 this.add(control_bar);
 }

 public void creatMap() {
 this.setLayout(null);
 this.map_area.removeAll();
 this.map_area.setVisible(false);
 paintMap();
 this.revalidate();
 this.map_area.setVisible(true);
 }
}

Map_Manager.java

import java.util.*;

public class Map_Manager {
 private PTB_Map ptb_map = new PTB_Map();
 private int di[][] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
 private double search_limit;
 private int area[] = new int[4];
 private Map<Status, Boolean> visit_of_status = new HashMap<Status, Boolean>();
 private Map<Point, Integer> visit_of_box = new HashMap<Point, Integer>();
 private PriorityQueue<Status> q = new PriorityQueue<Status>(new Comparator<Status>() {
 public int compare(Status s1, Status s2) {
 return s1.step - s2.step;
 }
 });

 private class PTB_Map {
 private int width;
 private int height;
 private int step_of_map;
 private int accessible_point;
 private Point end_p = new Point();
 private Status start = new Status();
 private int matrix[][] = new int[100][100];
 private Map<Point, Point> path_map = new HashMap<Point, Point>();
 private Point[] path = new Point[1000];
 private double ratio_of_space;
 private double ratio_of_step;
 }

 public class Point implements Cloneable {
 int x, y;

 public boolean equals(Object obj) {
 if (!(obj instanceof Point))
 return false;
 Point point = (Point) obj;
 return this.x == point.x && this.y == point.y;
 }

 public int hashCode() {
 return this.x * ptb_map.width + this.y;
 }

 public Object clone() {
 Point newPoint = null;
 try {
 newPoint = (Point) super.clone();
 } catch (CloneNotSupportedException e) {
 e.printStackTrace();
 }
 return newPoint;
 }

 public String toString() {
 return "(" + (this.x + 1) + "," + (this.y + 1) + ")";
 }
 }

 private class Status implements Cloneable {
 Point box = new Point();
 Point person = new Point();
 int step;

 public int hashCode() {
 return this.box.hashCode() * this.person.hashCode() + this.step;
 }

 public boolean equals(Object obj) {
 if (!(obj instanceof Status))
 return false;
 Status status = (Status) obj;
 return this.box.equals(status.box) && this.person.equals(status.person) && this.step == status.step;
 }

 public Object clone() {
 Status newStatus = null;
 try {
 newStatus = (Status) super.clone();
 newStatus.box = (Point) box.clone();
 newStatus.person = (Point) person.clone();
 } catch (CloneNotSupportedException e) {
 e.printStackTrace();
 }
 return newStatus;
 }
 }

 public void setMap(int height, int width, double degree_of_difficulty) {
 this.ptb_map.height = height;
 this.ptb_map.width = width;
 this.ptb_map.ratio_of_space = 0.5;
 double ratio = 1;
 if (height + width < 20)
 ratio = 0.05 * (height + width);
 this.ptb_map.ratio_of_step = 0.5 + degree_of_difficulty * 0.05 * ratio;
 this.search_limit = (this.ptb_map.height * this.ptb_map.width) / 10;
 }

 public int getHeight() {
 return ptb_map.height;
 }

 public int getWidth() {
 return ptb_map.width;
 }

 public int getStepOfMap() {
 return ptb_map.step_of_map;
 }

 private boolean accessible(Point point) {// point可走则返回true
 if (point.x < 0 || point.x >= ptb_map.height || point.y < 0 || point.y >= ptb_map.width)// 越界
 return false;
 if (ptb_map.matrix[point.x][point.y] == 1)// 走到墙上
 return false;
 return true;
 }

 private void creatSpace(Point point) {
 Random random = new Random();
 int l = 0;
 while (l <= search_limit) {
 int dir = random.nextInt(4);
 if (point.x + di[dir][0] < 0 || point.x + di[dir][0] >= ptb_map.height || point.y + di[dir][1] < 0
  || point.y + di[dir][1] >= ptb_map.width)
 continue;// 若往该方向走一步越界,则换个方向
 point.x += di[dir][0];
 point.y += di[dir][1];
 if (this.ptb_map.matrix[point.x][point.y] != 0) {
 if (point.y < ptb_map.width / 2) {
  if (point.x < ptb_map.height / 2)
  ++area[0];// 该点在左上方
  else
  ++area[1];// 该点在左下方
 } else {
  if (point.x < ptb_map.height / 2)
  ++area[2];// 该点在右上方
  else
  ++area[3];// 该点在右下方
 }
 this.ptb_map.matrix[point.x][point.y] = 0;
 ++this.ptb_map.accessible_point;
 }
 ++l;
 }
 }

 private boolean produceMap() {// 返回值为地图是否创建成功
 Random random = new Random();
 // 重置地图的矩阵
 for (int i = 0; i < ptb_map.height; ++i)
 for (int j = 0; j < ptb_map.width; ++j)
 ptb_map.matrix[i][j] = 1;
 do// 随机设置人和箱子的初始位置
 {
 ptb_map.start.box.x = random.nextInt(ptb_map.height);
 ptb_map.start.box.y = random.nextInt(ptb_map.width);
 ptb_map.start.person.x = random.nextInt(ptb_map.height);
 ptb_map.start.person.y = random.nextInt(ptb_map.width);
 } while (ptb_map.start.box.equals(ptb_map.start.person));
 ptb_map.accessible_point = 0;
 ptb_map.matrix[ptb_map.start.person.x][ptb_map.start.person.x] = 0;
 // 设置一定的墙
 ptb_map.accessible_point = 0;
 Point start = (Point) ptb_map.start.person.clone();// 最开始走的位置为人的初始位置
 area[0] = area[1] = area[2] = area[3] = 0;
 creatSpace(start);
 while (ptb_map.accessible_point < (ptb_map.height * ptb_map.width) * ptb_map.ratio_of_space) {
 int min = 10000, min_area = 0;
 for (int i = 0; i < 4; ++i)
 if (area[i] < min) {
  min = area[i];
  min_area = i;
 }
 switch (min_area) {
 case 0:// 左上
 start.x = random.nextInt(ptb_map.height / 2);
 start.y = random.nextInt(ptb_map.width / 2);
 break;
 case 1:// 左下
 start.x = random.nextInt(ptb_map.height / 2) + ptb_map.height / 2;
 start.y = random.nextInt(ptb_map.width / 2);
 break;
 case 2:// 右上
 start.x = random.nextInt(ptb_map.height / 2);
 start.y = random.nextInt(ptb_map.width / 2) + ptb_map.width / 2;
 break;
 case 3:// 右下
 start.x = random.nextInt(ptb_map.height / 2) + ptb_map.height / 2;
 start.y = random.nextInt(ptb_map.width / 2) + ptb_map.width / 2;
 break;
 }
 creatSpace(start);
 }
 ptb_map.end_p = (Point) start.clone();
 ptb_map.matrix[ptb_map.start.person.x][ptb_map.start.person.y] = 4;
 ptb_map.matrix[ptb_map.start.box.x][ptb_map.start.box.y] = 2;
 ptb_map.matrix[ptb_map.end_p.x][ptb_map.end_p.y] = 3;
 return true;
 }

 private boolean solveMap() {// 返回值为当前地图是否有路径
 q.clear();
 visit_of_box.clear();
 ptb_map.path_map.clear();
 ptb_map.step_of_map = 0;
 ptb_map.start.step = 0;
 int pre_step = -1;
 q.add(ptb_map.start);
 visit_of_status.put(ptb_map.start, true);
 while (!q.isEmpty()) {
 Status pre_Status = (Status) q.peek().clone();
 if (pre_Status.step != pre_step) {
 visit_of_status.clear();
 pre_step = pre_Status.step;
 }
 for (int i = 0; i < 4; ++i) {
 Status cur_Status = (Status) pre_Status.clone();
 cur_Status.person.x += di[i][0];
 cur_Status.person.y += di[i][1];
 if (!accessible(cur_Status.person))// 该点不可走
  continue;
 if (visit_of_status.containsKey(cur_Status))// 该点已经走过
  continue;
 // 保存当前点的前一个,用于输出路径
 if (cur_Status.person.equals(cur_Status.box))// 走到箱子上
 {
  Point next_box = new Point();// 当前人会把箱子推到的位置
  next_box.x = cur_Status.box.x + di[i][0];
  next_box.y = cur_Status.box.y + di[i][1];
  if (!accessible(next_box))// 该点不可走
  continue;
  if (ptb_map.path_map.containsKey(next_box))
  continue;
  if (visit_of_box.containsKey(next_box)) {
  if (visit_of_box.get(next_box) > 4)// 当前位置箱子已走过四次
  continue;
  }
  // 箱子可以走到该点,则箱子走一步
  ptb_map.path_map.put(next_box, cur_Status.box);
  cur_Status.box = next_box;
  ++cur_Status.step;
  if (!visit_of_box.containsKey(cur_Status.box))
  visit_of_box.put(cur_Status.box, 1);
  else {
  int t = visit_of_box.get(cur_Status.box);
  ++t;
  visit_of_box.put(cur_Status.box, t);
  }
  if (cur_Status.box.equals(ptb_map.end_p))// 箱子走到终点
  {
  ptb_map.step_of_map = cur_Status.step;
  q.clear();
  if (ptb_map.step_of_map < (ptb_map.height + ptb_map.width) * ptb_map.ratio_of_step)
  return false;
  else
  return true;
  }
 }
 q.add(cur_Status);
 visit_of_status.put(cur_Status, true);
 }
 pre_Status = null;
 q.poll();
 }
 return false;
 }

 public void recordPath() {// 记录路径
 Stack<Point> output_path = new Stack<Point>();// 用于输出路径
 Point cur_point = (Point) ptb_map.end_p.clone();// 从终点开始
 int step = -1;
 while (step != ptb_map.step_of_map) {
 ++step;
 output_path.push(cur_point);
 cur_point = ptb_map.path_map.get(cur_point);
 if (cur_point == null)
 break;
 }
 int i = 0;
 while (!output_path.empty())// 将路径保存在点数组里
 {
 ptb_map.path[i] = output_path.peek();
 output_path.pop();
 ++i;
 }
 }

 public void creatMap() {
 int i = 0;
 do {
 while (!produceMap())
 ;
 ++i;
 } while (!solveMap());
 recordPath();
 printMap();//
 System.out.println(i);//
 }

 public int[][] getMap() {
 return ptb_map.matrix;
 }

 public Point getStartBoxPoint() {
 return ptb_map.start.box;
 }

 public Point getStartPersonPoint() {
 return ptb_map.start.person;
 }

 public Point getEndPoint() {
 return ptb_map.end_p;
 }

 private void printMap() {
 for (int i = 0; i < ptb_map.height; ++i) {
 System.out.print(ptb_map.matrix[i][0]);
 for (int j = 1; j < ptb_map.width; ++j)
 System.out.print(" " + ptb_map.matrix[i][j]);
 System.out.println();
 }
 }

 public Point[] getPath() {
 return ptb_map.path;
 }
}

更多精彩游戏,请参考专题《java经典小游戏》

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

javascript经典小游戏汇总

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java实现推箱子游戏

    本文实例为大家分享了Java实现推箱子游戏的具体代码,供大家参考,具体内容如下 package Test1; //用于调用Test2包 import Test2.*; import java.awt.*; import javax.swing.*; public class APP extends JFrame{ public static void main(String[] args) { // TODO Auto-generated method stub APP a = new APP(

  • java实现推箱子小游戏

    本文实例为大家分享了java实现推箱子游戏的具体代码,供大家参考,具体内容如下 运行示例: 图形界面由swing组件构成 生成地图的算法如下 创建地图算法(produceMap):先将二维数组全置为1,代表初始状态全为墙.先随机产生两个不重合的点,一个作为人的起点,另一个作为箱子的起点.从起点开始,随机朝四个方向走一定的步数,若走到的点不是空地,即对应数组元素不为0,则将该点设为空地,即数组元素设为0.将地图分为左上.左下.右上和右下四个区域,并设置四个变量记录四个区域已开辟空地的数量.每开辟一

  • java二维数组实现推箱子小游戏

    本文实例为大家分享了java实现推箱子小游戏的具体代码,供大家参考,具体内容如下 二维数组 二维数组:类似于二维表格(有很多层,每一层有多个房间的楼房) 数组声明: 数据类型[][]数据名 = new 数据类型[行数][列数]; 获取二维数组的长度:数组名.lengt 得到的是行数 数组名[行下标].length 得到的是列数 推箱子小游戏 import java.util.Random; import java.util.Scanner; /* * 推箱子的小游戏 */ public clas

  • js推箱子小游戏步骤代码解析

    推箱子小游戏大家肯定都玩过,之所以写这篇文章,是觉得这个小游戏足够简单好理解 demo: 步骤解析: 本文代码已经放在了github上面了,里面也进行了很详细的代码注释,可以copy下来,在本地运行一下看看. 1. 渲染地图 html结构: html结构十分简单,只要弄一堆div,来放置地图的class就可以了,我这里初始化了12*9个div,地图里最多九行高度. 这些div都是同样大小,地图渲染出来区别的只是颜色的不同. 地图函数: var box=$('.box div'); //地图使用的

  • C++实现推箱子小游戏源码

    本文实例为大家分享了C++实现推箱子小游戏的具体代码,供大家参考,具体内容如下 功能尚为完善. // ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include<windows.h> #define KEY_DOWN(vk_code) GetAsyncKeyState(vk_code) & 0x8000 ? 1 : 0 using

  • DEVC++实现推箱子小游戏

    推箱子小游戏(基于DEVC++),供大家参考,具体内容如下 #include<iostream> #include<stdio.h> #include<conio.h> #include <windows.h> using namespace std; void Game_Menu(HANDLE hout); void Game_description(HANDLE hout); void gotoxy(HANDLE hout, int x, int y);

  • C语言代码实现推箱子小游戏

    本文实例为大家分享了C语言实现推箱子小游戏的具体代码,供大家参考,具体内容如下 本次游戏是个推箱子第一关最简单的小游戏 有详细注释,下面是做出来的游戏界面 游戏操作说明和功能说明: 1.按wasd控制小人的上下左右移动. 2.按 r 重新开始游戏 3.游戏开始有操作介绍 4.游戏结束有胜利提示 游戏原理分析 1.游戏开始时的星星个数 = 箱子在星星上的个数时 , 游戏胜利. 2.按 r 键重新开始游戏, 我们需要定义一个量 map_1[8][8] 来保存游戏初始时的界面, 操作时我们将其赋值给

  • C++实现推箱子小游戏

    本文实例为大家分享了C++实现推箱子小游戏的具体代码,供大家参考,具体内容如下 游戏效果 简单易懂的推箱子闯关小游戏. 游戏代码 #include <bits/stdc++.h> #include <windows.h> #include <conio.h> using namespace std; #define VERSION "2.2" #define M 55 int n, m, wall[M][M], hole[M][M], box[M][

  • C/C++编写推箱子小游戏

    本文实例为大家分享了C/C++编写推箱子小游戏的具体代码,供大家参考,具体内容如下 我们用' #'来代表墙,'O'来代表箱子,' * '代表终点,'@'代表箱子已经到达终点,'S来表示人'. 注意:W,A,S,D为方向键,而且要在英文格式下 运行示例: 以下为完整代码: /* 推箱子(示例二) */ #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <conio.h> i

  • C/C++实现推箱子小游戏

    本文实例为大家分享了C/C++实现推箱子小游戏的具体代码,供大家参考,具体内容如下 效果演示 实现功能 如上图所示.按键控制小猪的运动,推箱子到达目的地. 如何实现 1.首先思考要保存箱子,小猪等信息,添加多个map可以用到三维数组. 2.定义小猪,箱子,墙,空地等信息在三维数组里的数值. 空地             0       墙               1  目的地           2     箱子             3  猪               4  2+4=6

  • 用C++实现推箱子小游戏

    前言 推箱子小游戏相信是很多人的同年记忆了,今天用c++语言来尝试下,用的是vs编译器. 代码还有很多可以优化的地方,为了更直观了解函数的形参和实参,所以地图没有用全局变量声明了,其实用全局变量声明会简洁很多. 头文件和main函数分享在最下面了. 提示:以下是本篇文章正文内容,下面案例可供参考 一.初始化游戏数据 void GameInit(int(*&pMap)[10][10], int index)//两张地图数据 { // static:返回静态全局区变量 static int loca

随机推荐