实现贪吃蛇游戏的思路:
class Node(i,j) //表示坐标
class Worm(List<Node> nodes) // 行数:10行//用LinkedList存储蛇的坐标点。当前进是用addFirst(Node node)方法添加一个一个坐标点(可以通过getFirst()得到上一个坐标-1得出);然后再删除尾节点。如果碰到食物则不删除尾节点。
// 列数:32列
step()//往前走一步
step(int dir)//根据方向往前走一步
class WormPanel //画板
---HashSet存储食物 //当随机获得食物坐标点的位置时判断它的坐标点是否与蛇身的坐标点重复(如果重复则继续获取随机数,知道不重复位置)。
内部类--Worm(LinkedList)
i j
j UP -1 0
01234567890123456789012345678901 DOWN 1 0
i 0-------------------------------- LEFT 0-1
1| O | RIGHT 0 1
2| ^ | 2,9
3| <-#-> |3,8 3,9 3,10
4| # | 4,9
5| ### | 5,9 5,10 5,11
6| # O O | 6,11
7| # | 7,11
8| | nodes.remove(nodes.size()-1)
9--------------------------------
import java.util.Scanner; class WormDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); WormPanel wormPanel = new WormPanel(); WormPanel.Worm worm =wormPanel.getWorm(); while(true) { wormPanel.print(); String dir = sc.nextLine();//u、d、l、r代表上下左右方向 if("u".equalsIgnoreCase(dir)) worm.step(WormPanel.Worm.UP); else if("d".equalsIgnoreCase(dir)) worm.step(WormPanel.Worm.DOWN); else if("l".equalsIgnoreCase(dir)) worm.step(WormPanel.Worm.LEFT); else if("r".equalsIgnoreCase(dir)) worm.step(WormPanel.Worm.RIGHT); else if("q".equalsIgnoreCase(dir)) { System.out.println("bye ^_^"); break; } else worm.step(); } }
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>
<pre name="code" class="java">package snakeGame; import java.util.*; class WormPanel { //蛇 private Worm worm; //行数 private int rows = 10; //列数 private int cols = 32; //食物 private HashSet<Node> foods = new HashSet<Node>(); public WormPanel(){ worm = new Worm(); initFoods(6); } public Worm getWorm() { return this.worm; } //打印功能 public void print() { for(int i=0;i<rows;i++) { for(int j=0;j<cols;j++) { if(i==0 ||i==rows-1) System.out.print("-"); else if(j==0 ||j==cols-1) System.out.print("|"); else if(worm.contains(i,j)) System.out.print("#"); else if(foods.contains(new Node(i,j))) System.out.print("0"); else System.out.print(" "); } System.out.println(); } } //随机生成食物 public void initFoods(int num) { Random random = new Random(); while(true) { int i = random.nextInt(rows-2)+1; int j = random.nextInt(cols-2)+1; //先判断是否是构成蛇的坐标 if(worm.contains(i,j)) { continue; } foods.add(new Node(i,j));//不会添加重复坐标 if(foods.size()==num) break; } } public class Worm { public static final int UP = -10; public static final int DOWN = 10; public static final int LEFT = -1; public static final int RIGHT = 1; private LinkedList<Node> nodes = new LinkedList<Node>(); private int direction; public Worm() { nodes.add(new Node(3,9)); nodes.add(new Node(4,9)); nodes.add(new Node(5,9)); nodes.add(new Node(5,10)); nodes.add(new Node(5,11)); nodes.add(new Node(6,11)); nodes.add(new Node(7,11)); this.direction = RIGHT; } public void step() { //得到第一个#号对应的坐标 Node head = nodes.getFirst(); //计算新的节点的坐标 int i = head.getI()+direction/10; int j = head.getJ()+direction%10; head = new Node(i,j); //在蛇的头部加入一个节点 nodes.addFirst(head); //判断是否遇到一个食物 if(foods.remove(head)) { return; } //删除尾部节点 nodes.removeLast(); } public void step(int direction) { if(this.direction+direction==0) throw new RuntimeException("不允许掉头"); this.direction = direction; step(); } //判断是否包含某个坐标的方法 public boolean contains(int i,int j) { return nodes.contains(new Node(i,j)); } } }
package snakeGame; class Node { private int i; private int j; public Node(){} public Node(int i,int j) { this.i = i; this.j = j; } public void setI(int i) { this.i = i; } public void setJ(int j) { this.j = j; } public int getI() { return this.i; } public int getJ() { return this.j; } public String toString() { return i+","+j; } public int hashCode() { return (i<<16)|j; } public boolean equals(Object obj) { if(obj==null) return false; if(this==obj) return true; if(obj instanceof Node) { Node node = (Node)obj; return this.i==node.i && this.j==node.j; } return false; } }
注释:
public void step() { //得到第一个#号对应的坐标 Node head = nodes.getFirst(); //计算新的节点的坐标 int i = head.getI()+direction/10; int j = head.getJ()+direction%10; head = new Node(i,j); //在蛇的头部加入一个节点 nodes.addFirst(head); //判断是否遇到一个食物 if(foods.remove(head)) { return; } //删除尾部节点 nodes.removeLast(); }
//随机生成食物 public void initFoods(int num) { Random random = new Random(); while(true) { int i = random.nextInt(rows-2)+1; int j = random.nextInt(cols-2)+1; //先判断是否是构成蛇的坐标 if(worm.contains(i,j)) { continue; } foods.add(new Node(i,j));//不会添加重复坐标 if(foods.size()==num) break; } }
以上两段代码中的foods.remove()方法需要重写hashCode()和equals()方法。比较的是他们的坐标值。将他们相同的坐标删除。