主要原理,地图为一个二维数组,蛇是一个集合,蛇移动集合插入一个头节点,删除一个尾节点。
首先,Node.java,每个节点是一个坐标。
package com.worm;
public class Node {
private int i;
private int j;
public Node(){};
public Node(int i,int j){
super();
this.i = i;
this.j = j;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
@Override
public String toString(){
return "[" +i+","+j+"]";
}
@Override
public boolean equals(Object obj){
if(obj == null)
return false;
if(this == obj)
return true;
if(obj instanceof Node){
Node o = (Node)obj;
return this.i == o.i&&this.j == o.j;
}
return false;
}
@Override
public int hashCode(){
return(i<<16)|j;//
}
}
接下来,Worm.java
package com.worm;
import java.util.LinkedList;
public class Worm {
private int rows = 10;
private int cols = 32;
private LinkedList<Node> nodes = new LinkedList<Node>();
private int dir;
public static final int UP = -10;
public static final int DOWN = 10;
public static final int LEFT = -1;
public static final int RIGHT = 1;
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));
dir = RIGHT;
}
public Worm(LinkedList<Node> nodes){//也可以自定义蛇的形状
this.nodes.clear();
this.nodes.addAll(nodes);
}
public void step(){
Node head = nodes.getFirst();
int i = head.getI() + dir/10;
int j = head.getJ() + dir%10;
if(i==0||i==rows||j==0||j==cols){
throw new RuntimeException("碰到边界,游戏结束");
}
head = new Node(i,j);
nodes.addFirst(head);
nodes.removeLast();
}
public void step(int dir){
if(this.dir + dir == 0){
throw new RuntimeException("不能掉头行驶");
}
this.dir = dir;
step();
}
public boolean contains (int i,int j){
return nodes.contains(new Node(i,j));
}
@Override
public String toString(){
return nodes.toString();
}
}
接下来,WormPanel.java,将蛇和背景画在控制台上
package com.worm;
public class WormPanel {
private int rows = 10;
private int cols = 32;
public void print(Worm worm){
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{
System.out.print(" ");
}
}
System.out.println();
}
}
}
最后,测试类,WormDemo.java
package com.worm;
import java.util.Scanner;
public class WormDemo {
public static void main(String[] args) {
final WormPanel panel = new WormPanel();
final Worm worm = new Worm();
Scanner s = new Scanner(System.in);
while(true){
panel.print(worm);
System.out.println(worm);
String dir = s.nextLine();
if(dir.equalsIgnoreCase("w")){
worm.step(Worm.UP);
}else if(dir.equalsIgnoreCase("s")){
worm.step(Worm.DOWN);
}else if(dir.equalsIgnoreCase("a")){
worm.step(Worm.LEFT);
}else if(dir.equalsIgnoreCase("d")){
worm.step(Worm.RIGHT);
}else if(dir.equalsIgnoreCase("q")){
System.out.println("Bye!!");
break;
}else{
worm.step();
}
}
}
}
一直按w键运行结果:
--------------------------------
| |
| |
| # |
| # |
| ### |
| # |
| # |
| |
--------------------------------
[[3,9], [4,9], [5,9], [5,10], [5,11], [6,11], [7,11]]
w
--------------------------------
| |
| # |
| # |
| # |
| ### |
| # |
| |
| |
--------------------------------
[[2,9], [3,9], [4,9], [5,9], [5,10], [5,11], [6,11]]
w
--------------------------------
| # |
| # |
| # |
| # |
| ### |
| |
| |
| |
--------------------------------
[[1,9], [2,9], [3,9], [4,9], [5,9], [5,10], [5,11]]
w
Exception in thread "main" java.lang.RuntimeException: 碰到边界,游戏结束
at com.worm.Worm.step(Worm.java:40)
at com.worm.Worm.step(Worm.java:52)
at com.worm.WormDemo.main(WormDemo.java:18)
蛇自动前进和键盘控制一起进行有待改进。
添加食物,食物为一个set集合,在地图中食物用“.”显示,当蛇移动后,如果食物集合中包含蛇的头节点,蛇集合加上头节点,食物集合减去头节点,蛇集合不减去尾节点。
在WormPanel.java中添加食物
private Set<Node> foods = new HashSet<Node>();
public void initFoods(){
foods.add(new Node(2,9));
}
public WormPanel(){
initFoods();
}
public Set<Node> getFoods() {
return foods;
}
地图中画出食物:
else if(foods.contains(new Node(i,j))){
System.out.print(".");
}
在Worm.java中添加:
private Set<Node> foods = new WormPanel().getFoods();
蛇移动的时候做出判断:
if(foods.contains(head)){
foods.remove(head);
return;
}
运行结果:
--------------------------------
| |
| . |
| # |
| # |
| ### |
| # |
| # |
| |
--------------------------------
[[3,9], [4,9], [5,9], [5,10], [5,11], [6,11], [7,11]]
w
--------------------------------
| |
| # |
| # |
| # |
| ### |
| # |
| # |
| |
--------------------------------
[[2,9], [3,9], [4,9], [5,9], [5,10], [5,11], [6,11], [7,11]]
w
--------------------------------
| # |
| # |
| # |
| # |
| ### |
| # |
| |
| |
--------------------------------
[[1,9], [2,9], [3,9], [4,9], [5,9], [5,10], [5,11], [6,11]]