连连看小游戏控制台版

      看到师兄在玩连连看的游戏,于是乎突然想写一个自己的连连看游戏。我写的这个没有界面,只是一个控制台演示版,当然在这个基础上,用SWING或者Android的GridView扩充界面我想应该很容易吧。不再啰嗦赘述。

     连连看游戏关键还是算法问题,任何两个棋子之多经过两个直角的折角连通就可以消去。能消去的两个棋子分以下三种情况:

     1 可以用一条直线直接相连

     2  经过一个折角相连

     3  经过两个折角相连

     在设计可以考虑,采用递归的思想,3-->2,2--->1 ,我的程序仅仅使用了3--->2而对于2,我没用递归。下面分享我的代码,欢迎拍砖。

import java.awt.Point;
import java.util.Random;
import java.util.Scanner;


public class Test {
	private int row_len;//行数(开始和结束行值为辅助作用)
	private int colunm_len;//列数(开始和结束列值为辅助作用)
	private int a[][];//存储整个棋盘值
	private static final int NUMBER_SIZE=10;//图片的数目
	public static void main(String[] args) {
		Test t=new Test();
		Point p1 =new Point();
		Point p2 =new Point();
		t.showQiPan();
		while(true){
			t.getPoint(p1,p2);
			t.docheck(p1, p2);
			if(p1.x==0)
				break;
		}
	}
	/*
	 * 得到输入点的坐标
	 */
	private void getPoint(Point p1, Point p2) {
		Scanner scanner=new Scanner(System.in);
		System.out.println("输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)");
		p1.x=scanner.nextInt();
		p1.y=scanner.nextInt();
		p2.x=scanner.nextInt();
		p2.y=scanner.nextInt();	
	}
	/*
	 * 初始化并显示棋盘
	 */
	public void showQiPan(){
		init();
		show_array();
	}
	/*
	 * 初始化
	 */
	public void init(){
		Scanner scanner=new Scanner(System.in);
		System.out.println("难度系数控制:");
		System.out.println("行数:");
		row_len=scanner.nextInt();
		System.out.println("列数");
		colunm_len=scanner.nextInt();
		if(colunm_len%2!=0){
			System.err.println("请保证输入的列号为偶数");
			System.exit(0);
		}
		a=new int[row_len][colunm_len];
		for(int j=0;j<colunm_len;j++){
			a[0][j]=0;
			a[row_len-1][j]=0;
		}
		for(int j=0;j<row_len;j++){
			a[j][0]=0;
			a[j][colunm_len-1]=0;
		}
		for(int i=1;i<row_len-1;i++)
			for(int j=1;j<colunm_len-1;j=j+2){
				int value=0;
				while(value==0){
					Random r=new Random();
					value=r.nextInt(NUMBER_SIZE);
				}				
				a[i][j]=value;
				a[i][j+1]=value;
			}
		/*
		 * 随机调换a[][]中的值
		 */
		for(int i=1;i<(row_len-2)*(colunm_len-2);i++){
				int index_x1=0;
				int index_y1=0;
				int index_x2=0;
				int index_y2=0;				
				Random r=new Random();
				while(index_x1==0){
					index_x1=r.nextInt(row_len-1);
				}	
				while(index_x2==0){
					index_x2=r.nextInt(row_len-1);
				}
				while(index_y1==0){
					index_y1=r.nextInt(colunm_len-1);
				}
				while(index_y2==0){
					index_y2=r.nextInt(colunm_len-1);
				}
				int tmp=a[index_x1][index_y1];
				a[index_x1][index_y1]=a[index_x2][index_y2];
				a[index_x2][index_y2]=tmp;
		}
	}
	/*
	 * 显示数组值
	 */
	public void show_array(){
		System.out.print("    ");
		for(int i=1;i<colunm_len-1;i++)
			System.out.print("*"+i+"*");
		System.out.print("\n");
		for(int i=0;i<row_len;i++){
			if(i!=0&&i!=row_len-1)
				System.out.print(i);
			else System.out.print(" ");
			for(int j=0;j<colunm_len;j++){
				System.out.print(" "+a[i][j]+" ");
			}				
			System.out.print("\n");
		}
	}
	/*
	 * 验证两点是否可以取消
	 */
	public void docheck(Point p1,Point p2){
		Point p3=new Point(-1,-1);
		if(a[p1.x][p1.y]==a[p2.x][p2.y]){
			if(isSameLine(p1, p2)||isSingleBrokenLine(p1, p2)||isDoubleBreakLine(p1, p2, p3)){
				a[p1.x][p1.y]=0;
				a[p2.x][p2.y]=0;
			}
			show_array();
		}else System.out.println("输入两点值不同,请重新选择");
		
	}
	/*
	 * 是否直接可以连通
	 */
	public boolean isSameLine(Point p1,Point p2){
		int i;
		if(p1.x==p2.x){
			int min_y=Math.min(p1.y, p2.y);
			int max_y=Math.max(p1.y, p2.y);
			for(i=min_y+1;i<max_y;i++)
				if(a[p1.x][i]!=0)
					return false;	
			if(i==max_y)
				return true;
		}else if(p1.y==p2.y){
			int min_x=Math.min(p1.x, p2.x);
			int max_x=Math.max(p1.x, p2.x);
			for(i=min_x+1;i<max_x;i++)
				if(a[i][p1.y]!=0)
					return false;	
			if(i==max_x)
				return true;
		}			
		return false;
	}
	/*
	 * 是否一个折线可以连通
	 */
	public boolean isSingleBrokenLine(Point p1,Point p2){
		
		int min_y=Math.min(p1.y, p2.y);
		int max_y=Math.max(p1.y, p2.y);
		int min_x=Math.min(p1.x, p2.x);
		int max_x=Math.max(p1.x, p2.x);
		
		Point tmp=new Point();
		tmp.x=min_x;
		tmp.y=min_y;
		if(p1.equals(tmp)||p2.equals(tmp)){
			
			boolean flag=true;
			if(a[min_x][max_y]!=0&&a[max_x][min_y]!=0)
				return false;
			else if(a[min_x][max_y]==0){
			   for(int i=min_y+1;i<max_y;i++){
				   if(a[min_x][i]!=0){
					   flag=false;
					   break;
				   }
				if(flag)
					for(int j=min_x+1;j<max_x;j++){
						if(a[j][max_y]!=0){
							flag=false;
							break;
						}							
					}
			   }
			   if(flag){
				  /* for(int j=min_x+1;j<max_x;j++){
						System.out.print(a[j][max_y]);
				   }	
				   System.out.println("\n");
				   for(int i=min_y+1;i<max_y;i++){
					   System.out.print(a[min_x][i]);
				   }
				   System.out.println("\n");*/
				   return true;
			   }
				  
			}
			else if(a[max_x][min_y]==0){
				 flag=true;
				 for(int i=min_y+1;i<max_y;i++){
					   if(a[max_x][i]!=0){
						   flag=false;
						   break;
					   }
					if(flag)
						for(int j=min_x+1;j<max_x;j++){
							if(a[j][min_y]!=0){
								flag=false;
								break;
							}							
						}
				   }
				   if(flag){
					  /* for(int j=min_x+1;j<max_x;j++){
							System.out.print(a[j][min_y]);
					   }	
					   System.out.println("\n");
					   for(int i=min_y+1;i<max_y;i++){
						   System.out.print(a[max_x][i]);
					   }
					   System.out.println("\n");*/
					   return true;
				   }
			}
		}else if(p1.x!=p2.x&&p1.y!=p2.y){
			
			boolean flag=true;
			if(a[min_x][min_y]!=0&&a[max_x][max_y]!=0)
				return false;
			else if(a[min_x][min_y]==0){
			   for(int i=min_y+1;i<max_y;i++){
				   if(a[min_x][i]!=0){
					   flag=false;
					   break;
				   }
				if(flag)
					for(int j=min_x+1;j<max_x;j++){
						if(a[j][min_y]!=0){
							flag=false;
							break;
						}							
					}
			   }
			   if(flag)
				   return true;
			}
			
			else if(a[max_x][max_y]==0){
				 flag=true;
				 for(int i=min_y+1;i<max_y;i++){
					   if(a[max_x][i]!=0){
						   flag=false;
						   break;
					   }
					if(flag)
						for(int j=min_x+1;j<max_x;j++){
							if(a[j][max_y]!=0){
								flag=false;
								break;
							}							
						}
				   }
				   if(flag)
					   return true;
			}	
		}	
		return false;
	}
	
	public boolean isDoubleBreakLine(Point p1,Point p2,Point p3){
		boolean flag=false;
		if(p1.y==p2.y){
			if(p1.x<p2.x) 
				flag=horizonVerify(p1,p2,p3);
			else
				flag=horizonVerify(p2,p1,p3);
		}else if(p1.x==p2.x){
			if(p1.y<p2.y) 
				flag=verticalVerify(p1,p2,p3);
			else
				flag=verticalVerify(p2,p1,p3);
		}else {
			if(p1.x<p2.x) 
				flag=horizonVerify(p1,p2,p3);
			else
				flag=horizonVerify(p2,p1,p3);
			if(!flag){
				if(p1.y<p2.y) 
					flag=verticalVerify(p1,p2,p3);
				else
					flag=verticalVerify(p2,p1,p3);
			}else 
				return true;		
		}
		return flag;
	}
	/*
	 * 水平判定 
	 */
	private boolean horizonVerify(Point p1,Point p2,Point p3){
		for(int i=0;i<colunm_len;i++){
			if(i!=p1.y&&a[p1.x][i]==0){
				Point p=new Point(p1.x,i);
				if(isSingleBrokenLine(p, p1)&&isSingleBrokenLine(p, p2)){
					p3.x=p1.x;
					p3.y=i;
					return true;
				}
			}
		}
		return false;
	}	
		
	/*
	 * 垂直判定
	 */
	private boolean verticalVerify(Point p1,Point p2,Point p3){
		for(int i=0;i<row_len;i++){
			if(i!=p1.x&&a[i][p1.y]==0){
				Point p=new Point(i,p1.y);
				if(isSingleBrokenLine(p, p1)&&isSingleBrokenLine(p, p2)){
					p3.x=p1.x;
					p3.y=i;
					return true;
				}
			}
		}
		return false;
	}
}
难度系数控制:
行数:
5
列数
6
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  5  5  6  9  0 
2 0  1  6  1  4  0 
3 0  9  4  5  5  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
1 1 1 2
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  6  9  0 
2 0  1  6  1  4  0 
3 0  9  4  5  5  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
2 2 1 3
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  0  9  0 
2 0  1  0  1  4  0 
3 0  9  4  5  5  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
2 1 2 3
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  0  9  0 
2 0  0  0  0  4  0 
3 0  9  4  5  5  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
3 1 1 4
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  0  0  0 
2 0  0  0  0  4  0 
3 0  0  4  5  5  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
3 2 2 4
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  0  0  0 
2 0  0  0  0  0  0 
3 0  0  0  5  5  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
3 3 3 4
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  0  0  0 
2 0  0  0  0  0  0 
3 0  0  0  0  0  0 
  0  0  0  0  0  0 
输入选择的两个点的坐标值(以空格隔开,以0 0 0 0 结束)
0 0 0 0
    *1**2**3**4*
  0  0  0  0  0  0 
1 0  0  0  0  0  0 
2 0  0  0  0  0  0 
3 0  0  0  0  0  0 
  0  0  0  0  0  0 

  结果中第一行是行号,第一列是列号,输入是坐标值,如果输入点的坐标值相同并且满足上面的三个情况之一,既可以消去,

   并将值改为0.

   当然程序也有不足之处,当出现死局时,应当重新将剩余的棋子摆盘。你还可以加上提示功能,对棋盘中非零的坐标点进行遍    历。当棋盘值全为零时,既可以获胜。如果向更加完善,加一个计时器来倒计时也可以增加趣味性。


 

你可能感兴趣的:(控制台)