java小程序——《连连看(简易版)》

最近做了一个不是图形界面的连连看小游戏,如果后期加上图片之类的估计会更美观些,将代码分享出来。。


感觉比较难的是关于那个三线连消除的部分,想的有些费力,不过想通了就好了,其中还会有一些需要考虑行遍历还是列遍历,怎么遍历之类的问题,主要还是要屡清楚思路,不然会被绕进去的。


一线连:

                 其实一线连是最简单易实现的,但又确实2,3连的基础。

                 一线连要考虑的是(1)行相等还是列相等(2)遍历的其实条件和结束条件,也即是求着同行(或同列)的最大值,最小值。(3)for循环遍历是否为零即可,这一点有可以分成两种方法:一,可以判断数组每个元素是否都为0,。二,或者判断两点间的和是否为零。


二线连:


                  有了一线连的基础,二线连就相对简单易想了,既是两个一线连,再加过渡点为零即可。

三线连:


               最最头痛的三线连,不过想想也还不算难,既是以p1点为标准,对其行遍历寻找出一点(1)该点为零(2)与p1点一连线为真,与p2二连线也为真;

               行遍历要从0,到a[].length,这一点上我被坑了下,如果不是完全遍历,是会漏掉很多情况的。之后列遍历也一样~


还有一点事关于棋盘生成的,棋盘生成是数组两两赋值,然后再打乱,在这里,打乱的时候我采取的办法是,随机生成4个数,作为两个数的下表,在交换这两个数,循环的次数大一点就可以达到目的了。

             其他的地方都还比较一般,写出来比较顺利。而且大部分也都写了注释。

package com.nh;
import java.util.Scanner;
import java.util.Random;
import com.nh.Point;
public class chess{
	public static void main(String[] agrs ){
		Scanner sc=new Scanner(System.in);
		System.out.println("请选择行数(row):");
		int row=sc.nextInt();
		int col;
		do{
			System.out.println("请选择行数(col)(请填写偶数哟!~):");//确保输出的棋盘是偶数,可以完全消除;
			col=sc.nextInt();
		}while(col%2!=0);
	
		System.out.println("请选择难度指数:");
		int degree=sc.nextInt();
		
		//生成棋盘
		int[][] chess=new int[row][col];

		//给棋盘中的位置赋值;
		assign(chess,degree);
		
		//打乱棋盘中两两相邻是一样的数的状态;
		Randomchess(chess);		//乱序棋盘已生成
		System.out.println("游戏开始");

		//输出已生成的棋盘;
		printArray(chess);
		
		//定义两个点:方便之后的判断工作
		Point p1=new Point();
		Point p2=new Point();

		boolean isGameOver=false;

		//循环输入两个数,并且执行判断;
		do{
			System.out.println("请输入要消除的两数字的行号和列号(格式为:x1  y1  x2  y2)");
			
			p1.x=sc.nextInt();
			p1.y=sc.nextInt();
			p2.x=sc.nextInt();
			p2.y=sc.nextInt();
			//1.先用isEliminate对输入的点是否可以消除进行判断;

			int num=isEliminate(chess,p1,p2);
			switch( num ){
				case 1:
					System.out.println("两点的位置不可已相同!");break;
				case 2:
					System.out.println("您输入的两点的值不等,请重新输入!");break;
				case 3:
					//2.判断的输入的点符合条件后对数组进行赋值为零的操作;
					chess[p1.x][p1.y]=0;
					chess[p2.x][p2.y]=0;
					//3.进行游戏结束的判断
					isGameOver=checkGame(chess);break;
				case 4:
					System.out.println("对不起输入有误!请重新尝试!");break;
			}
			printArray(chess);
		}while(!isGameOver);//注意:如果用do  while结构while中的内容是不成立的条件。并且若表示条件并列不成立要用&&
		System.out.println("恭喜通过!");
	}
	//对棋盘赋值;但并不打乱
	public static void assign(int[][] a,int degree){
		Random r=new Random();		
		int row=a.length;
		int col=a[0].length;
		
		for(int i=0;i<row;i++){
			//对边框赋值为零
			if(i==0||i==row-1){
				for(int j=0;j<col;j++){
					a[i][j]=0;
				}
			}else{
				for(int j=0;j<col;){
					//对边框赋值为零
					if(j==0||j==col-1){
						a[i][j]=0;
						j++;
					}else{
						//对其他值随机赋值
						a[i][j]=r.nextInt(degree)+1;
						if(a[i][j]==0){
							a[i][j]+=1;
						}
						a[i][j+1]=a[i][j];
						j+=2;
					}
				}
			}
		}
	}
	//对已经生成的棋盘打乱顺序
	public static void Randomchess(int[][] a){
		Random r=new Random();	
		int row=a.length;
		int col=a[0].length;
		for(int i=0;i<row*col*10;i++){
			int x1=r.nextInt(  row-2  )+1;
			int y1=r.nextInt(  col-2  )+1;
			int x2=r.nextInt(  row-2  )+1;
			int y2=r.nextInt(  col-2  )+1;

			int temp=a[x1][y1];
			a[x1][y1]=a[x2][y2];
			a[x2][y2]=temp;
		}
	}

	public static void printArray(int[][] a){
		int row=a.length;
		int col=a[0].length;
		showColsNum(col);
		for(int i=0;i<row;i++){
			//如果是第零行和最末行就输出边框:
			if(i==0||i==row-1){
				//输出行号
				System.out.print(" \t");
				for(int j=0;j<col;j++){
					System.out.print("#\t");
				}
				System.out.println("\t ");
			}else{
			//其他的就照常输出
				//输出行号
				System.out.print(i+"\t");
				for(int j=0;j<col;j++){
					//但正常输出元素之前,列号为0和col-1的也应输出的是边框;
					if(j==0||j==col-1){
						System.out.print("#\t");
					}else{
						//对内部已经消除的元素清空输出:
						if(a[i][j]==0){
							System.out.print("\t");
						}else{
							System.out.print(a[i][j]+"\t");
						}
					}
				}
				System.out.println("\t"+i);
			}
			
		}
		showColsNum(col);
	}
	//显示列号:
	public static void showColsNum(int col){
		System.out.print(" \t \t");
		for( int i=1;i<col-1;i++){
			
				System.out.print("*"+i+"*\t");
			
		}
		System.out.println();
	}
	public static int isEliminate(int[][] a,Point p1,Point p2){
		//1。判断两点不是统一个点:
		if( p1.equals( p2 ) ){
			return 1;
		}
		//2.两点的值是否相同:
		if( a[p1.x][p1.y]!=a[p2.x][p2.y] ){
			return 2;
		}
		//3.判断两点之间的连线情况:
		if( doOneLine(a,p1,p2)  ||  doTwoLine(a,p1,p2)  ||  doThreeLine(a,p1,p2) )	{
			return 3;
		}
		return 4;
	}

	public static boolean doOneLine(int[][] a,Point p1,Point p2){
		//定义最大值,最小值
		int max;
		int min;
		//判断是循环列还是循环行
		if(p1.x==p2.x){
			max=Max(p1.y,p2.y);
			min=Min(p1.y,p2.y);
			return RunRowCheck(a,p1.x,max,min);
			
		}
		if( p1.y==p2.y ){
			max=Max(p1.x,p2.x);
			min=Min(p1.x,p2.x);
			return RunColCheck(a,p1.y,max,min);
		}
		return false;
	}
	//循环行判断是否连线处都是零;
	public static boolean RunRowCheck(int[][] a,int x,int max,int min){
		int sum=0;
		for(int i=min+1;i<max;i++){
			sum=sum+a[i][x];
		}
		if(sum==0){
			return true;
		}
		return false;
	}
	//循环列判断是否连线处都是零;
	public static boolean RunColCheck(int[][] a,int x,int max,int min){
		int sum=0;
		for(int i=min+1;i<max;i++){
			
			sum=sum+a[x][i];
		}
		if(sum==0){
			return true;
		}
		return false;
	}
	//判断最大值
	public static int Max(int x,int y){
		if(x>y){
			return x;
		}else{
			return y;
		}
	}
	//判断最小值
	public static int Min(int x,int y){
		if(x>y){
			return y;
		}else{
			return x;
		}
	}
	//2连线
	public static boolean doTwoLine(int[][] a,Point p1,Point p2){
		Point p3=new Point();
		int max;
		int min;
		int num=1;
		//判断是循环列还是循环行
		
		//两种情况:1.p3.x=p1.x;p3.y=p2.y
		//	  2。p3.x=p2.x;p3.y=p1.y		


		//1:p3.x=p1.x;p3.y=p2.y
		p3.x=p1.x;
		p3.y=p2.y; 
		if(a[p3.x][p3.y]==0){
			//先判断p3与p1(列相同):
			max=Max(p1.y,p3.y);
			min=Min(p1.y,p3.y);
			if(RunColCheck(a,p1.x,max,min)){
				//继续判断p2和p3(行相同)
				max=Max(p3.x,p2.x);
				min=Min(p3.x,p2.x);
				if(RunRowCheck(a,p3.y,max,min)){
					return true;
				}
			}
		}
		p3.y=p1.y;
		p3.x=p2.x; 
		if( a[p3.x][p3.y]==0 ){
			
			//先判断p3与p1(行相同):
			max=Max(p1.x,p3.x);
			min=Min(p1.x,p3.x);
			if(RunRowCheck(a,p1.y,max,min)){
				//继续判断p2和p3(列相同)
				max=Max(p3.y,p2.y);
				min=Min(p3.y,p2.y);
				return RunColCheck(a,p3.x,max,min);
			}
			return false;
		}
		return false;
	}
			//3连线
	public static boolean doThreeLine(int[][] a,Point p1,Point p2){
		Point p3=new Point();
		Point p4=new Point();
			
		// 边框消除:
		if(   (p1.x==p2.x&&p1.x==1)   ||   (p1.y==p2.y&&p1.y==1)   ){
				return true;
		}else{
			//内部消除
			//行遍历:
			for(int i=0;i<a.length;i++){
					p3.y=p1.y;
					p3.x=i;
					if(a[p3.x][p3.y]==0){
						if(  doOneLine(a,p1,p3)  ){
							if(  doTwoLine(a,p3,p2)  ){
								return true;
							}
						}
					}
				}
			//列遍历
			for(int j=0;j<a[0].length;j++){
				p3.x=p1.x;
				p3.y=j;
				if(a[p3.x][p3.y]==0){
					if(doOneLine(a,p1,p3)){
						if(  doTwoLine(a,p3,p2)  ){
							 return true;
							}
						}
					}
				}
			return false;
		}	
		
	}
	public static void Swap(Point p1,Point p2){
		Point temp=new Point();
			temp=p1;
			p1=p2;
			p2=temp;
	}
	public static boolean checkGame(int[][] a){
		int sum=0;
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[0].length;j++){
			//1.按照垂直方向:
				sum=sum+a[i][j];
			}
		}
		if(sum==0){
			return true;
		}else{
			return false;
		}
	}
}

下面是定义的一个Point类:

package com.nh;
public class Point{
	public int x;
	public int y;
	public boolean equals(Point p1){
		if(this.x==p1.x&&this.y==p1.y){
			return true;
		}else{
			return false;
		}
		
	}
}


  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值