研一下学期,java基础学习的整理,每一步都要走的踏实,输入同样要有输出,总结更加重要。
这是一个简单的贪吃蛇展示,主要分为4个类
1.Node类:节点坐标定义
2.Worm类:蛇身的节点是一个集合,实现头部插入,尾部删除。
3.WormPanel类:贪吃蛇的面板,包含框框、蛇
4.WornDemo:测试类
Node类:
package com.snack;
public class Node {
private int i;
private int j;
public Node(){
}
public Node(int i,int j){
this.i=i;
this.j=j;
}
public int getI(){
return i;
}
public int getJ(){
return j;
}
public void setI(int i){
this.i=i;
}
public void setJ(int j){
this.j=j;
}
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 other=(Node) obj;
return this.i==other.i&&this.j==other.j;
}
return false;
}
public int hashCode(){
return i*10000+j;
}
}
Worm类:
package com.snack;
import java.util.LinkedList;
import javax.management.RuntimeErrorException;
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<>();//插入速度快 可以头尾插入
private int dir;//方向变量
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 void step(){
//取出当前头节点
Node head =nodes.getFirst();//get(0)
//计算新的头结点
int i=head.getI()+dir/10;
int j=head.getJ()+dir%10;
head=new Node(i,j);
nodes.addFirst(head);//nodes.add(0,head);
nodes.removeLast();//nodes.remove(nodes.size()-1)
}
/*
* 换方向走一步
* dir 新方向
*/
public void step(int dir){
if(this.dir+dir==0){
throw new RuntimeException( "不能往方向走啊");
}
this.dir=dir;
step();
}
public boolean contains(int i,int j){
// Node node=new Node(i,j);
return nodes.contains(new Node(i,j));
}
public String toString(){
return nodes.toString();
}
}
WormPanel类:
package com.snack;
public class WormPanel {
private Worm worm;
private int rows;
private int cols;
public WormPanel(int rows,int cols){
this.rows=rows;
this.cols=cols;
worm = new 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 {
System.out.print(" ");
}
}
System.out.println();
}
}
/*
* 获取面板上的蛇
* return蛇对象
*/
public Worm getWorm(){
return worm;
}
}
主测试类:
package com.snack;
import java.util.Scanner;
public class WormDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
WormPanel pane=new WormPanel(15,45);
Scanner console = new Scanner(System.in);
Worm worm=pane.getWorm();//获取面板上的蛇
for(;;){
pane.print();
System.out.println("请输入方向");
String cmd=console.nextLine();
if(cmd.equalsIgnoreCase("U")){
worm.step(worm.UP);
}else if(cmd.equalsIgnoreCase("D")){
worm.step(worm.Down);
}else if(cmd.equalsIgnoreCase("L")){
worm.step(worm.Left);
}else if(cmd.equalsIgnoreCase("R")){
worm.step(worm.Right);
}else if(cmd.equalsIgnoreCase("q")){
System.out.println("See you~");
break;
}
else{
worm.step();
}
}
}
}
代码总结:
Node类:定义了 i,j 横纵坐标 用于输出面板用的 该类中还定义toString方法,用于输出节点的坐标。重写了equals方法 可以自动重写equals方法和hashcode方法的 虽然现在还不太理解为什么要重写hashcode方法
if (obj instanceof Node)
// {
// Node other=(Node) obj;
// return this.i==other.i&&this.j==other.j;
}
A instanceof B :A 是不是B类型的对象 或者A对象能不能转成B类型
通常来判断子类对象是可以转换成父类对象。
Worm类:
定义了上下左右四个常量,这个细细探究一下 是非常巧妙的。尤其是代码中的
int i=head.getI()+dir/10;
int j=head.getJ()+dir%10;
UP: i-1 (i是行)
DOMN: i+1
LEFT: j-1
RIGHT: j+1
就是10 -10 1 -1 这样四个参数 加上/10和%10 取整取余的操作 可以巧妙的实现想要ij变化的效果 还是要动脑子的
step() 是向当前方向走一步 step 有参的是换方向走一步 其实后者只要把当前的方向改一下就好了 this.dir=dir; 定义了不 能反向走 用了一个new RuntimeException() 用来抛出一个异常。
利用LinkedList的特性 实现在头部插入一个点 并把结尾的节点杀出 addFirst和removeLast 合适
该类中还定义了contains方法 用来判断面板中是否包含蛇身的节点 是的话就打印 这样就能很轻松的把蛇给打印出来
Wormpanel类中没有什么好说的 就是打印面板和蛇 利用contains方法。
WormDemo类:
主函数入口,for(;;)是指 没有循环初始条件 满足什么的。。