⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 model.java

📁 一个JAVA写的连连看游戏,非常不错,是学习JAVA的好资料,值得下载
💻 JAVA
字号:
/*
 * Created on 2005-3-15
 */
package jcase.lianliankan;

/**
 * @author javacat
 * This is the puzzle model
 */
public class Model {
	// empty character
	public static final char EMPTY = 0;//'-';
	public static final char PLACEHOLDER = '-';
	public static final char[] CHARSETS = new char[]{
			'0','1','2','3','4','5','6','7','8','9',
			'A','B','C','D','E','F','G','H','I','J',
			'K','L','M','N','O','P','Q','R','S','T',
			'U','V','W','X','Y','Z'
	};
	private char[][] matrix;
	private int columns,rows,count;
	private int emptyCount=0;
	private int[] nextPair;
	public int getColumns(){
		return columns;
	}
	public int getRows(){
		return rows;
	}
	/**
	 * 得到指定位置的字符。
	 * @param x
	 * @param y
	 * @return
	 */
	public char getChar(int x, int y){
		try {
			return matrix[x][y];
		} catch (IndexOutOfBoundsException e) {
			e.printStackTrace();
			return EMPTY;
		}
	}
	/**
	 * 根据指定的字符串行创建model。
	 * 这种创建方式用于前期测试或者从文件读入游戏。
	 * 参考随机生成model的方法
	 * @param lines
	 * @return
	 */
	public static Model createModel(String[] lines){
		int h=lines.length;
		int w=lines[0].length();
		char[][] matrix = new char[w][h];
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				matrix[j][i] = lines[i].charAt(j);
				if(matrix[j][i]==PLACEHOLDER){
					matrix[j][i]=EMPTY;
				}
			}
		}
		return new Model(matrix);
	}
	/**
	 * 随机产生model
	 * @param columns--盘面列数,因为第一列和最后一列是空的,所以model的字符数组列数应该是这个值+2.
	 * @param rows --盘面行数,因为第一行和最后一行是空的,所以model的字符数组行数应该是这个值+2.
	 */
	public static Model createRandomModel(int columns,int rows){
		char[][] matrix = new char[columns+2][rows+2];		
		int len=CHARSETS.length;
		int size = columns*rows;
		int half=size/2;
		char[] chars = new char[size];
		
		for(int i=0;i<half;i++){
			chars[i]=CHARSETS[(int)(len*Math.random())];
			chars[half+i]=chars[i];			
		}
		int repeat = (int)(size*Math.random());
		int pos1,pos2;
		char tmp;
		for(int i=0;i<repeat;i++){
			pos1= (int)(size*Math.random());
			pos2=(int)(size*Math.random());
			tmp=chars[pos2];
			chars[pos2]=chars[pos1];
			chars[pos1]=tmp;
		}
		
		for(int i=0;i<rows;i++){
			for(int j=0;j<columns;j++){				
					matrix[j+1][i+1]=chars[i*columns+j];				
			}
		}
		return new Model(matrix);
	}
	public Model(char[][] matrix){
		this.matrix = matrix;
		columns = matrix.length;
		rows = matrix[0].length;
		count = columns*rows;
		countEmpty();
	}
	/**
	 * 试图消除指定位置的两个目标
	 * 如果这两个目标之间有通路,则消除之,并且返回扫描到的x或者y轴坐标,
	 * 否则返回null
	 */
	public int[] defuse(int x1,int y1,int x2,int y2){
		int[] path=getPath(x1,y1,x2,y2);
		if(path!=null){
		matrix[x1][y1]=EMPTY;
		matrix[x2][y2]=EMPTY; //empty two puzzle
		emptyCount+=2;
		}
		return path;
	}
	/**
	 * Check the specified two cells could be linked or not.
	 * If there's a path, return the axis     
	 */
	protected int[] getPath(int x1,int y1, int x2, int y2){
		if(x1==x2 && y1==y2){
			return null;
		}
		if(matrix[x1][y1]!=matrix[x2][y2]){
			return null;
		}
		if(matrix[x1][y1]==EMPTY){
			return null;
		}
		if(matrix[x2][y2]==EMPTY){
			return null;
		}
		int x,y,step;
		//scan horizental
		for(x=0;x<getColumns();x++){
			// (x1,y1) --> (x,y1)
			boolean breaked=false;
			for(step=Math.min(x,x1);step<=Math.max(x,x1);step++){
				if(step==x1) continue; //do not check(x1,y2)
				if(matrix[step][y1]!=EMPTY){
					breaked=true;
					break;
				}
			}
			if(breaked){
				continue;
			}
			// (x,y1) --> (x,y2)
			for(step=Math.min(y1,y2)+1;step<Math.max(y1,y2);step++){
				if(matrix[x][step]!=EMPTY){
					breaked=true;
					break;
				}
			}
			if(breaked){
				continue;
			}
			// (x,y2) --> (x2,y2)
			for(step=Math.min(x,x2);step<=Math.max(x,x2);step++){
				if(step==x2) continue; //do not check (x2,y2)
				if(matrix[step][y2]!=EMPTY){
					breaked=true;
					break;
				}
			}
			if(!breaked){
				//record two point (x,y1),(x,y2)
				int[] rec=new int[]{x,-1};				
				return rec;
			}
		}
		//if horizental scan finished and have not find a path, 
		//then scan vertical
		for(y=0;y<getRows();y++){
			boolean breaked = false;
			// (x1,y1) --> (x1,y)
			for(step=Math.min(y,y1);step<=Math.max(y,y1);step++){
				if(step==y1) continue; //do not check (x1,y1)
				if(matrix[x1][step]!=EMPTY){
					breaked = true;
					break;
				}
			}
			if(breaked){
				continue;
			}
			// (x1,y) --> (x2,y)
			for(step=Math.min(x1,x2)+1;step<Math.max(x1,x2);step++){
				if(matrix[step][y]!=EMPTY){
					breaked=true;
					break;
				}
			}
			if(breaked){
				continue;
			}
			// (x2,y) --> (x2,y2)
			for(step=Math.min(y,y2);step<=Math.max(y,y2);step++){
				if(step==y2) continue ; //do not check (x2,y2)
				if(matrix[x2][step]!=EMPTY){
					breaked = true;
					break;
				}
			}
			
			if(!breaked){
				//record two point (x1,y),(x2,y)
				int[] rec=new int[]{-1,y};			
				return rec;
			}
		}
		return null;
	}
	/**
	 * 检查是否过关(牌都消掉了)
	 */
	public boolean isAllDefused(){
		return (count-countEmpty())==0;
	}
	/**
	 * 检查是否还有可以消除的格子
	 * @return 如果还有可以消除的则返回true,否则返回false
	 */
	public boolean check(){
		return check(0);
	}
	/**
	 * 洗牌
	 */
	public void wash(){
		int cln=columns-2;
		int size = cln*(rows-2);
		int repeat = (int)(size*Math.random());
		int x1,y1,x2,y2,pos1,pos2;
		char tmp;
		for(int i=0;i<repeat;i++){
			pos1= (int)(size*Math.random());
			pos2=(int)(size*Math.random());
			x1=pos1%cln+1;
			y1=pos1/cln+1;
			x2=pos2%cln+1;
			y2=pos2/cln+1;
			tmp=matrix[x2][y2];
			matrix[x2][y2]=matrix[x1][y1];
			matrix[x1][y1]=tmp;
		}
	}
	private boolean check(int index){
		int y=index/columns;
		int x=index%columns;
		for(int i=index+1;i<count;i++){
			if(getPath(x,y,i%columns,i/columns)!=null){
			    //找到一对可以消除的,记录其坐标
				nextPair = new int[4];
				nextPair[0]=x;
				nextPair[1]=y;
				nextPair[2]=i%columns;
				nextPair[3]=i/columns;
				return true;
			}
		}
		index++;
		if(index< (count-1)){
			return check(index);
		}
		nextPair=null;
		return false;
	}
	private int countEmpty(){
		if(emptyCount==0){
			for(int j=0;j<rows;j++){
				for(int i=0;i<columns;i++){
					if(matrix[i][j]==EMPTY)
						emptyCount++;
				}
			}
		}
		return emptyCount;
	}
	/**
	 * 得到下一对可以消除的目标,通常用于提示用户
	 */
	public int[] getNextPair(){
		return nextPair;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -