java自学Web前端之路程序员

综合练习——简易俄罗斯方块

2017-11-20  本文已影响33人  孙浩j

需求分析:类1.图形类(父类图形和子类的具体图形)2.屏幕类

*3.打印图形
*(1)打印的图形包括正在移动的图形和被存的图形

*4.判断正在移动的图形和被存的图形坐标是否冲和
*/

点类

public class Spot {
    private int row;   //定义行坐标
    private int col;   //定义列坐标
    
    public Spot(int row, int col) {
        super();
        this.row = row;
        this.col = col;
    }
    
    public Spot() {
        super();
    }

    public int getRow() {
        return row;
    }
    public void setRow(int row) {
        this.row = row;
    }
    public int getCol() {
        return col;
    }
    public void setCol(int col) {
        this.col = col;
    }
    //图形的移动功能是根据点移动的
    public void left(){
        col=col-1;
    }
    public void right(){
        col=col+1;
    }
    public void bottom(){
        row=row+1;
    }           
}

public abstract class Graph {
  private Spot[]sp=new Spot[4];  //建立一个用于构成图形的数组
    public Graph(){
        
    }
    public Spot[] getSp() {   
        return sp;
    }
    public void setSp(Spot[] sp) {
        this.sp = sp;
    }
    public void leftG(){   //图形左移,将数组里每一个点左边都进行改变
        for(int i=0;i<sp.length;i++){
            sp[i].setCol(sp[i].getCol()-1);
        }
        
    }
    public void rightG(){   //图形右移
        for(int i=0;i<sp.length;i++){
            sp[i].setCol(sp[i].getCol()+1);
        }   
    }
    public void bottomG(){   //图形下移
        for(int i=0;i<sp.length;i++){
            sp[i].setRow(sp[i].getRow()+1);
        }
        
    }
    
    
    public void topG(){   //图形上移
        for(int i=0;i<sp.length;i++){
            sp[i].setRow(sp[i].getRow()-1);
        }
        
    }
    public boolean judgeLeft(){  //判断左侧是否越界,越界为true
        for(int i=0;i<sp.length;i++){
            if(sp[i].getCol()<1){
                return true;
            }
        }
        return false; 
        
    }
    public boolean judgeRight(){  //判断右侧是否越界,越界为true
        for(int i=0;i<sp.length;i++){
            if(sp[i].getCol()>12){
                return true;
            }
        }
        return false; 
        
    }
    public boolean judgeBottom(){  //判断下侧是否越界,越界为true
        for(int i=0;i<sp.length;i++){
            if(sp[i].getRow()>15){
                return true;
            }
        }
        return false; 
        
    }
    public abstract void rotate();//y-q+p, p-x+q
        //定义一个抽象的旋转的方法,由子类决定怎么旋转
    
}

具体图形类T型(该类继承了抽象类图形,自动具备了非抽象方法)

public class T extends Graph { 

    public T(int row,int col){   //子类调用父类方法要使用super.方法
        super.getSp()[0]=new Spot(row,col-1);  //通过确定中心点坐标找到其它点和其关系,确定了图形形状
        super.getSp()[1]=new Spot(row,col);
        super.getSp()[2]=new Spot(row,col+1);
        super.getSp()[3]=new Spot(row+1,col);
    }
    
    public void rotate() {//y-q+p, p-x+q
        Spot[] sp=new Spot[4]; 
  //建一个新数组用于接收旋转后的图形,用原数组,旋转后坐标和原坐标有影响
        for(int i=0;i<super.getSp().length;i++){
            sp[i]=new Spot(super.getSp()[i].getCol()
                    -super.getSp()[1].getCol()
                    +super.getSp()[1].getRow(),
                    super.getSp()[1].getRow()
                    -super.getSp()[i].getRow()
                    +super.getSp()[1].getCol());

        }
        super.setSp(sp);    //把这个旋转后的坐标位置传给图形
        
    }
    public void rotate1() {//y-q+p, p-x+q   //逆时针旋转
        Spot[] sp=new Spot[4];
        for(int i=0;i<super.getSp().length;i++){
            sp[i]=new Spot(-super.getSp()[i].getCol()
                    +super.getSp()[1].getCol()
                    +super.getSp()[1].getRow(),
                    -super.getSp()[1].getRow()
                    +super.getSp()[i].getRow()
                    +super.getSp()[1].getCol());

        }
        super.setSp(sp);    
    }
}

屏幕类

public class Screen {
    private String[][] s=new String[15][12];//保存当前图形
    private String[][] s1=new String[15][12]; //用于存已有图形
    public Screen(){
        for(int i=0;i<s1.length;i++){
            for(int j=0;j<s1[i].length;j++){
                s1[i][j]="*";
            }
        }
    }
    
    public void setS(Graph g){
        //把图形存到屏幕中图形坐标的位置里。
        for(int i=0;i<s.length;i++){   //屏幕的行
            for(int j=0;j<s[i].length;j++){        //屏幕的列
                boolean b=false;
                for(int k=0;k<g.getSp().length;k++){   //
                    if((g.getSp()[k].getRow()==(i+1)&&
                            g.getSp()[k].getCol()==(j+1))){
                        b=true;
                    }
                }
                if(b){
                    s[i][j]="~";
                 
                }else{
                    s[i][j]="*";  //在不满足的地方存星,是为了防止图形位置改变时,原有位置还存在
                
                }   
            }
            }       
        }
    public void setS1(){ //   用于存不再受控制移动的图形
      for(int i=0;i<s.length;i++){
          for(int j=0;j<s[i].length;j++){
              if(s[i][j]=="~"){
                  s1[i][j]=s[i][j];
              }
          }
      }
    }
        
    
    public void print(){     //打印出的屏幕是不受控制的图形+正在受控制移动的图形
        for(int i=0;i<s.length;i++){
            for(int j=0;j<s[i].length;j++){
                if(s1[i][j]=="~"){
                System.out.print(s1[i][j]);
            }else{
                System.out.print(s[i][j]);
            
            }
            }
            System.out.println();
        }
        
    }
    public String[][] getS() {
        return s;
    }
    public boolean have(){  //判断正在移动的图形和已经被存起来的图形是否重合
        for(int i=0;i<s.length;i++){
            for(int j=0;j<s[i].length;j++){
                if(s[i][j]==s1[i][j]&&s[i][j]=="~"){ //在相同的且等于~就是图形重合
                    return true;
                }
            }
        }
        return false;
        
    }
    public boolean full(){//判断最后一行是不是满的
        boolean a=true;
        for(int i=0;i<s1[14].length;i++){
            if(s1[14][i]=="*"){
                a=false;
                break;
                
            }else{
                a=true;
            }
        }
        return a;
    }

    public void delete(){  //删除最后一行
            for(int i=s1.length-1;i>0;i--){
                for(int j=0;j<s1[i].length;j++){
                    s1[i][j]=s1[i-1][j];
                    
                }       
        }
    }
  
}


测试类

import java.util.*;
public class Demo1 {
    public static void main(String[]args) throws InterruptedException{  
        Scanner in=new Scanner(System.in);
        Screen s=new Screen();
        while(true){
            T t=new T(3,3); 
        s.setS(t);  
        //s.print();
        out:while(true){  //不断移动

        System.out.println("1表示左移,2表示右移,3表示下移,4表示旋转");
        int a=in.nextInt(); 
        if(a==1){
            if(!t.judgeLeft()){  //如何没到达左侧边界,图形左移。
                t.leftG(); 
                s.setS(t);}   //存到屏幕对象的正在移动图形的数组里
            if(t.judgeLeft()){
                t.rightG();  //但是左移后不一定到没到边界,这时要判断一下,到了边界之外右移回来
                s.setS(t);
            }        
                s.print(); //打印屏幕
            
        }else if(a==2){     //如何没到达右侧边界,图形左移被存到屏幕对象的正在移动图形的数组里
            if(!t.judgeRight()){
                t.rightG();
                s.setS(t);}
            if(t.judgeRight()){
                t.leftG();  
                s.setS(t);
            }
                s.print();//打印屏幕
    
        }else if(a==3){
            if(!t.judgeBottom()&&!s.have()){   //没到底边界,并且没跟已有图形重合,下移
                t.bottomG();
                s.setS(t);}
            if(t.judgeBottom()||s.have()){   //如果下移后出了底边界,就上上移一下
                t.topG();                       //并且把上移后的图形存到 到达地步的屏幕数组里
                s.setS(t);
                s.setS1();
                while(true){
                    if(s.full()){ //如果最后一行满了
                        s.delete();   //消除最后一行
                    }else{              
                s.print();   //打印出屏幕
                break out;   //这时不断移动的循环接收,重新进入一个图形开始移动
                    }
                }
            }
                
                s.print();    
                

        }else if(a==4){     
            if(!t.judgeBottom()&&!t.judgeLeft()&&!t.judgeRight())//没到边界进行顺时针旋转
            {
            t.rotate();
            s.setS(t);
            }
            if(t.judgeBottom()||t.judgeLeft()||t.judgeRight()){   //旋转后出了边界进行逆时针旋转
                t.rotate1();
                s.setS(t);
            }
            s.print();      打印屏幕
        }
        }
}
}
}


上一篇下一篇

猜你喜欢

热点阅读