栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java学习日志3.23】连连看Java控制台小游戏,可直接运行

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java学习日志3.23】连连看Java控制台小游戏,可直接运行

连连看小游戏很考验逻辑算法基本功,这里我写了个控制台的简易版本,注释都有,逻辑思想可供大家参考

思路:

1 获得一个连连看的初始棋盘

2 棋盘保存的是一个二维数组

3 设置图形的种类数(例:level=5)

4 往二维数组里随机插入1到5,并要求为偶数个

5 判断消除条件(边界消除,直线消除,一折消除,两折消除

import java.util.Random;
import java.util.Scanner;

public class linklinkLook {

	int rows;
	int cols;
	int level = 5;// 图像的种类数
	int [] [] checkboard; // 棋盘
	
	public void init() {
		//让用户输入行数和列数(行列至少有一个为偶数)
		Scanner sc = new Scanner(System.in);
		do {
			System.out.println("请输入棋盘行数和列数");
			rows = sc.nextInt();
			cols = sc.nextInt();
		} while(rows * cols % 2 != 0);
		
		// 初始化棋盘
		checkboard = new int[rows][cols];
		
		// 生成棋盘,将指定范围的数字随机生成后放到棋盘中。要求随机乱序,要求数字是成对的
		Random rd = new Random();
		int num = 0;
		if (rows % 2 == 0) {
			// 说明行数为偶数
			for(int i = 0; i < rows; i += 2) {
				for (int j = 0; j < cols; j ++) {
					num = rd.nextInt(level) + 1; // [0, 5) + 1 后为[1, 6)转化成int就是[1, 5]
					checkboard[i][j] = num;
					checkboard[i + 1][j] = num;
				}
			}
			return;
		}
		
		// 如果行不是偶数,那么列肯定是偶数
		for (int i = 0; i < rows; ++ i) {
			for (int j = 0; j < cols; ++ j) {
				num = rd.nextInt(level) + 1;
				checkboard[i][j] = num;
				checkboard[i][ ++ j] = num;
			}
			return;
		}
	}
	
	public void shuffle() {
		int x1, x2, y1, y2, temp;
		for(int i = 0; i < rows * cols * level; ++ i) {
			x1 = (int)(Math.random()*rows);
			x2 = (int)(Math.random()*rows);
			y1 = (int)(Math.random()*cols);
			y2 = (int)(Math.random()*cols);
			temp = checkboard[x1][y1];
			checkboard[x1][y1] = checkboard[x2][y2];
			checkboard[x2][y2] = temp;
		}
	}
	
	
	public void show() {
		System.out.print("    ");
		for (int i = 1; i <= cols; ++ i) {
			System.out.print("*" + i + "* ");
		}
		System.out.println("n");
		for (int i = 0; i < rows; ++ i) {
			for (int j = 0; j < cols; ++ j) {
				if (j == 0) {// 说明是第一列
					System.out.print("*" + (i + 1) + "*  ");
				}
				if(checkboard[i][j] == 0) {// 说明这个位置已经消除
					System.out.print("    ");
				}else {
					System.out.print(checkboard[i][j] + "   ");
				}
			}
			System.out.print("*" + (i + 1) + "*nn");
		}
		System.out.print("    ");
		for (int i = 1; i <= cols; ++ i) {
			System.out.print("*" + i + "* ");
		}
		System.out.println("n");
	}
	
	
	public void startGame() {
		int x1, y1, x2, y2;
		Scanner sc = new Scanner(System.in);
		do {
			System.out.println("请输入要消除的两个点的坐标(0 0 0 0):");
			x1 = sc.nextInt() - 1;
			y1 = sc.nextInt() - 1;
			x2 = sc.nextInt() - 1;
			y2 = sc.nextInt() - 1;
			// 消除规则,初始校验 :两个位置的值是否相等,检查是否越界,是否是同一个点
			if(x1 < 0 || x1 >= rows || x2 < 0 || x2 >= rows || y1 < 0 || y1 >= cols || y2 < 0 || y2 >= cols) {
				System.out.println("越界。。。");
				continue;
			}
			if(x1 == x2 && y1 == y2) {
				System.out.println("同一个点不能消除。。。");
				continue;
			}
			if(checkboard[x1][y1] != checkboard[x2][y2]) {
				System.out.println("图形不同不能消除。。。");
				continue;
			}
			// 是否能边界消除、直线消除、一折消除、两折消除
			if(checkBound(x1, y1, x2, y2) || checkonLine(x1, y1, x2, y2) || checkoneTurn(x1, y1, x2, y2)
					|| checkTwoTurn(x1, y1, x2, y2)) {
				checkboard[x1][y1] = 0;
				checkboard[x2][y2] = 0;
				show(); //刷新棋盘
				continue;
			}
		}while(!checkGameOver());
		
		
	}
	private boolean checkBound(int x1, int y1, int x2, int y2) {
		if(x1 == x2 && (x1 == 0 || x1 == rows - 1)) {
			return true;
		}
		if(y1 == y2 && (y1 == 0 || y1 == cols - 1)) {
			return true;
		}
		return false;
	}
	private boolean checkonLine(int x1, int y1, int x2, int y2) {
		if(x1 == x2) { // 同行
			int min = y1 > y2 ? y2 : y1;
			int max = y1 > y2 ? y1 : y2;
			
			for (int i = min + 1; i < max; ++ i) {
				if (checkboard[x1][i] != 0) {
					return false;
				}
			}
			return true;
		}
		if(y1 == y2) { // 同列
			int min = x1 > x2 ? x2 : x1;
			int max = x1 > x2 ? x1 : x2;
			
			for (int i = min + 1; i < max; ++ i) {
				if (checkboard[i][y1] != 0) {
					return false;
				}
			}
			return true;
		}
		return false;
	}
	private boolean checkoneTurn(int x1, int y1, int x2, int y2) {
		// 一折消除
		if(checkboard[x1][y2] == 0 && checkonLine(x1,y1,x1,y2)&&checkonLine(x2,y2,x1,y2)) {
			// 与x1,y1同行,与x2,y2同列
			return  true;
		}if(checkboard[x2][y1]==0 && checkonLine(x1,y2,x2,y1)&&checkonLine(x2,y2,x2,y1)) {
			return true;
		}
		return false;
	}
	private boolean checkTwoTurn(int x1, int y1, int x2, int y2) {
		boolean flag1 = true;
		boolean flag2 = true;
		// 两个折点在同一列平移判断
		for(int i = 1; i < cols + 1; ++ i) {
			if(i==y1|i==y2) {
				++ i;
			}
			if(checkonLine(x1,y1,x1,i)&&checkonLine(x2,y2,x2,i)&&checkonLine(x1,i,x2,i)) {
				// 说明能消,直接返回true
				return true;
			}
			flag1 = false;// 折点在同一列能消失败了 
		}
		// 两个折点在同一行平移判断
				for(int i = 1; i < rows + 1; ++ i) {
					if(i==x1|i==x2) {
						++ i;
					}
					if(checkonLine(x1,y1,y1,i)&&checkonLine(x2,y2,y2,i)&&checkonLine(y1,i,y2,i)) {
						// 说明能消,直接返回true
						return true;
					}
					flag2 = false;// 折点在同一行能消失败了 
				}
		return flag1||flag2;
	}
	
	public boolean checkGameOver(){
		for(int [] arr: checkboard) {
			for(int num : arr) {
				if(num != 0) {
					return false;
				}
			}
		}
		System.out.println("恭喜通关!!!");
		return true;
	}
	public static void main(String[] args) {
		linklinkLook lll = new linklinkLook();
		lll.init();
		lll.shuffle();
		lll.show();
		lll.startGame();
	}

}

 

 值得注意的一点,以上设计并没有包括死局的判断,感兴趣的小伙伴可以自行拓展 需要用到链表结构,字典结构,结合泛型来实现(有向邻接表思想)

死局例如:

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778104.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号