控制台实现的java消消乐小游戏-查看文章

控制台实现的java消消乐小游戏

发表于:2017-11-24 23:13:20 分类:JAVA 阅读:499次

image

原本以为很简单,写进来才发现细节很繁复。

  1. 初始化游戏不能出现可以不操作而直接消除的棋子。

    最后想到的解决方案是生成的同时向前向上匹配,

    如果能消除就重新生成,不能就下一格。

  2. 移动格子后查找可以消除的格子。

    起初想的关注点就是移动后的两个格子,一调试发现每推进一格,都需要关注它的垂直的两个方向。这一块代码很吓人,写了n层while循环……

  3. 消除后空格上移。

    这块又有一个细节,当空格上面的格子掉落后,

    需要重新匹配地图中可以消除的格子,消除完又是一波掉落。所以这块需要设置一个无限次数循环,结束条件为不再有新的可消除格子产生。

  4. 消除停止后,再次填充为空的格子。

    这点简单,把初始化的代码再拉过来跑一跑就ok。

  5. 想到但懒得实现的一个小细节——判断死局。

    当前地图没有可通过移动消除的格子为死局,需要重新初始化游戏。关键点在判定上,想到的方案是for循环遍历所有格子。以每个格子为关注点,分别向上向下向左向右移位(代码中有交换方法,略加改造),如果能交换成功,直接返回活局。如果遍历完成还没有交换成功,返回残局。然后初始游戏。这个功能下次想写安卓时再实现吧,目前调试发现死局并不容易出现。

bug应该不少,但是关键代码好了,这个小游戏暂告一段落。

补充一下:代码编写调试全部在手机的aide软件中完成。耗时一天。下面上代码。

import java.util.*;
public class XiaoLeGame
{
   static String COLORS="红,绿,蓝,黄,黑,白";
   static int MAX=10;
   static String[][] game;
   static boolean gameStart;
   static int count;
   static HashSet boxSet=new HashSet<String>();
   static void init(){
      Random ran=new Random();
      game=new String[MAX][MAX];
      for(int x=0;x<MAX;x++){
         for(int y=0;y<MAX;y++){
            String [] ss=COLORS.split(",");
            String color=ss[ran.nextInt(ss.length)];
            while(canDis(x,y,color)){
               color=ss[ran.nextInt(ss.length)];
            }
            game[x][y]=color;
         }
      }
   }
   static boolean canDis(int xin,int yin,String color){
      if(xin<0||yin<0|xin>=MAX||yin>=MAX){
         return false;
      }
      HashSet set=null;
      int num=1;
      if(gameStart){
         set=new HashSet<String>();
         set.add(xin+","+yin);
      }
      //横向向左
      int x=xin-1;
      int y=yin;
      while(x>=0&&game[x][y]!=null&&game[x][y].equals(color)){
         num++;
         if(gameStart){
            set.add(x+","+y);
         }
         //左移每格后,纵向向下匹配
         y--;
         while(y>=0&&x>=0&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            y--;
         }
         //重置纵坐标,向上匹配
         y=yin+1;
         while(y<MAX&&x>=0&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            y++;
         }
         y=yin;
         x--;
      }
      x=xin+1;
      while(x<MAX&&game[x][y]!=null&&game[x][y].equals(color)){
         num++;
         if(gameStart){
            set.add(x+","+y);
         }
         y--;
         while(y>=0&&x<MAX&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            y--;
         }
         y=yin+1;
         while(y<MAX&&x<MAX&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            y++;
         }
         y=yin;
         x++;
      }
      x=xin;
      y=yin-1;
      while(y>=0&&game[x][y]!=null&&game[x][y].equals(color)){
         num++;
         if(gameStart){
            set.add(x+","+y);
         }
         x--;
         while(x>=0&&y>=0&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            x--;
         }
         x=xin+1;
         while(x<MAX&&y>=0&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            x++;
         }
         x=xin;
         y--;
      }
      y=yin+1;
      while(y<MAX&&game[x][y]!=null&&game[x][y].equals(color)){
         num++;
         if(gameStart){
            set.add(x+","+y);
         }
         x--;
         while(x>=0&&y<MAX&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            x--;
         }
         x=xin+1;
         while(x<MAX&&y<MAX&&game[x][y]!=null&&game[x][y].equals(color)){
            num++;
            if(gameStart){
               set.add(x+","+y);
            }
            x++;
         }
         x=xin;
         y++;
      }
      if(gameStart&&num>=3){
         boxSet.addAll(set);
      }
      return num>=3;
   }
   static void printGame(){
      System.out.println(" 零一二三四五六七八九");
      for(int i=0;i<MAX;i++){
         System.out.print(i);
         for(int j=0;j<MAX;j++){
            System.out.print(game[i][j]==null?"※":game[i][j]);
         }
         System.out.println();
      }
      /*while(!scanAll()){
         gameStart=false;
         init();
         gameStart=true;
      }
      System.out.println("打印ok");*/
   }
   //交换方法
   static void exchange(String boxs){
      String[] boxab=boxs.split("#");
      String[] boxas=boxab[0].split(",");
      String[] boxbs=boxab[1].split(",");
      int ax=Integer.parseInt(boxas[0]);
      int ay=Integer.parseInt(boxas[1]);
      int bx=Integer.parseInt(boxbs[0]);
      int by=Integer.parseInt(boxbs[1]);
      //交换
      String temp=game[bx][by];
      game[bx][by]=game[ax][ay];
      game[ax][ay]=temp;
      
      boolean suc=false;
      if(canDis(ax,ay,game[ax][ay])){
         suc=true;
      }
      if(canDis(bx,by,game[bx][by])){
         suc=true;
      }
      if(!suc){
         System.out.println("无效交换!");
         temp=game[bx][by];
         game[bx][by]=game[ax][ay];
         game[ax][ay]=temp;
      }else{
         int tep=0;
         //调用消除方法
         while(boxSet.size()>=3){
            dis();
            if(tep==0){
               System.out.println("交换成功,本回合得分:"+boxSet.size()+" 总分:"+count);
            }else{
               System.out.println("连击"+tep+"次,得分:"+boxSet.size()+" 总分:"+count);
             }
            boxSet.clear();
            moveDown();
            autoDisScan();
            tep++;
         }
         fullBox();
      }
   }
   //消除方法
   static void dis(){
      count=count+boxSet.size();
      Iterator it=boxSet.iterator();
      while(it.hasNext()){
         String b=(String) it.next();
         String[] point=b.split(",");
         int x=Integer.parseInt(point[0]);
         int y=Integer.parseInt(point[1]);
         
         //System.out.println("要消除的x="+x+" y="+y);
         game[x][y]=null;
      }
      printGame();
      System.out.println("消除完成!");
   }
   //有空就向下移动
   static void moveDown(){
      for(int i=0;i<MAX;i++){
         for(int j=0;j<MAX;j++){
            //如果为null,所有上方格子下移一格,将最上方置为null
            if(game[i][j]==null){
               for(int n=i;n>0;n--){
                  game[n][j]=game[n-1][j];
               }
               game[0][j]=null;
            }
         }
      }
      printGame();
      System.out.println("下移完成!");
   }
   //扫描当前棋局是不是没有可以交换的棋子,有返回true,没有返回false。未完成
   /*static boolean scanAll(){
      for(int i=0;i<MAX;i++){
         for(int j=0;j<MAX;j++){
            System.out.println(i+" "+j);
            if(canDis(game[i][j])){
               System.out.println("可消除"+i+" "+j);
               return true;
            }
         }
      }
      return false;
   }*/
   static void autoDisScan(){
      for(int i=0;i<MAX;i++){
         for(int j=0;j<MAX;j++){
            canDis(i,j,game[i][j]);
         }
      }
      //System.out.println("set长度"+boxSet.size());
   }
   static void fullBox(){
      gameStart=false;
      Random ran=new Random();
      for(int i=0;i<MAX;i++){
         for(int j=0;j<MAX;j++){
            if(game[i][j]==null){
            String [] ss=COLORS.split(",");
            String color=ss[ran.nextInt(ss.length)];

            while(canDis(i,j,color)){
               color=ss[ran.nextInt(ss.length)];

            }
            game[i][j]=color;
            }
         }
      }
      gameStart=true;
      printGame();
      System.out.println("填充完成!");
   }
   public static void main(String[] args){
      init();
      printGame();
      gameStart=true;
      Scanner scan=new Scanner(System.in);
      while(true){
      System.out.println("输入交换的格子坐标:(如1,1#1,2) 当前总分:"+count);
      String ss=scan.next();
      exchange(ss);
      }
      
   }
}


关键词:java,控制台,消消乐


验证码: