控制台实现的java消消乐小游戏
发表于:2017-11-24 23:13:20 分类:JAVA 阅读:499次
原本以为很简单,写进来才发现细节很繁复。
初始化游戏不能出现可以不操作而直接消除的棋子。
最后想到的解决方案是生成的同时向前向上匹配,
如果能消除就重新生成,不能就下一格。
移动格子后查找可以消除的格子。
起初想的关注点就是移动后的两个格子,一调试发现每推进一格,都需要关注它的垂直的两个方向。这一块代码很吓人,写了n层while循环……
消除后空格上移。
这块又有一个细节,当空格上面的格子掉落后,
需要重新匹配地图中可以消除的格子,消除完又是一波掉落。所以这块需要设置一个无限次数循环,结束条件为不再有新的可消除格子产生。
消除停止后,再次填充为空的格子。
这点简单,把初始化的代码再拉过来跑一跑就ok。
想到但懒得实现的一个小细节——判断死局。
当前地图没有可通过移动消除的格子为死局,需要重新初始化游戏。关键点在判定上,想到的方案是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,控制台,消消乐