javaSwing连连看游戏

news2024/9/19 10:56:49

一、简介

基于java的连连看游戏设计和实现,基本功能包括:消除模块,重新开始模块,刷新模块,选择难度模块,计时模块。本系统结构如下:

(1)消除模块:
完成连连看游戏消除动作的模块。
(2)重新开始模块:
完成连连看游戏中重新开始新一局游戏功能的模块。
(3)刷新模块:
完成连连看游戏中,将游戏中未消除的图片个数记录并重新随机放置等数量图片的功能模块。
(4)选择难度模块:
完成游戏中切换游戏难度并开始新一局游戏的模块。
(5)计时模块:
完成游戏中倒计时并显示提示信息的模块。
(6)状态显示模块:
完成游戏中对游戏得分、闯关数记录的模块。

二、需求分析

软件需求分析就是通过调查研究和有效的沟通以及建立系统的数据模型、功能模型和行为模型,使用户和开发人员就“系统必须做什么”这个问题达成一致意见,最后生成软件需求规格说明的过程。软件需求分析的过程就是对用户或企业意图不断揭示的过程,需要对系统进行可行性研究之后,对系统目标做出分为详细的描述。

可行性分析

可行性研究的结果是清楚的回答:该系统是否值得开发。
下面将分别从技术、经济、社会、操作四个方面对基于Java的连连看游戏的设计与实现进行可行性分析和研究。

技术可行性

技术可行性分析一般可以理解为项目开发涉及到的技术、环境是否符合开发标
准,能够达到预期效果;它是项目成功运行的一个必不可少的条件;因此,对技术可行性分析需要进行全面化的评估。
本次连连看游戏采用的开发工具是功能强大的Eclipse,它具有十分强大的可扩展功能,只要下载安装所需要的相关插件,就能支持我们用纯Java实现此次的桌面游戏程序。使用Eclipse开发应用程序可按需下载插件,不过分依赖于硬件,不论是升级产品方面还是扩展功能方面都有很好的发挥空间。
本次项目使用Java的GUI开发技术。Java本身可提供类库,完善的类库和AWT包对桌面游戏开发提供了强大完整的技术支持,完全可以满足我们连连看小游戏的开发,在开发过程中,可以创建满足本次开发项目任务的直接的、简明的图形用户界面。
Eclipse在开发Java项目方面应用多而广,是一个成熟可行的开发平台。Java语言也是成熟的开发语言,能够满足此次要求。在开发方面,无论是开发平台,还是开发语言,对于开发人员来说都是熟悉且能易掌握的。在从硬件方面来看,时下的硬件容量不断扩大,可靠性日益渐涨,性价比越来越高,对于本项目开发而言,足够满足需求。
由以上分析可知,本软件在技术上是可行的。

经济可行性

经济可行性是指对项目的成本和收益进行分析,具体内容包括两个部分:新系统所能带来的经济效益和该经济效益是否超过系统开发和系统维护所需要的费用。
对于本项目而言,在系统开发和系统维护方面的开销很小,没有过多的硬件投入,调试方便,开发过程中,Eclipse是开源免费的,本游戏在此开发环境下,不需要太复杂的工具和服务器支持,在完成过程中,也仅需要一台个人电脑以及在完成过程中上网查询所用到的人力资源以及文献资源。
  综上所述,本项目在经济上是可行的。

社会可行性

社会可行性广义上可分为三大部分:道德方面、法律方面、社会方面。接下来将就这几个方面,对此次项目进行分析。
从道德方面来看,本次开发无论从过程中还是最终完成的产品上看均不涉及传播低级黄色内容、社会负能量。本次开发目的主要是借毕业设计巩固所学专业知识,一切皆以个人为单位,不涉及广泛传播及使用,对社会基本不造成任何不良影响。
从法律方面来讲,本次开发过程和最终产品因开发目的不涉及版权、社会安全等法律问题。在开发过程中,参考的所有文献会列明,尊重知识产权,尊重专利版权,不会将产品投入社会使用。
从社会方面来谈,本次开发是对已有成果的一次学习和开发体验,虽不能带来很大的社会价值,但不同程度上实现了开发者个人价值。因不涉及产品推广,所以不涉及产品带来的社会经济效益和社会影响力。
由以上分析可知,本软件具有社会可行性。

操作可行性

操作可行性主要分析系统操作难度问题。本游戏界面以窗口形式给出,可视化强,整体风格简洁大气,各个功能键布局合理使得游戏功能一目了然。整个游戏过程操作简单易上手,完全依靠鼠标点击操作,在简单说明或培训下,操作上基本没有难度。
综上所述,本游戏具有技术可行性、经济可行性、操作可行性和社会可行性值得开发。

连连看游戏需求描述及规则描述

游戏规则是模仿网络上普通的连连看游戏,即解决鼠标两次点击的图片能否消去的问题。当然,前提是点击两张相同的图片,若点击的是同一张图片或者两张不同的图片,则不予以处理。在两张相同图片所能连通的所有路径中,如果存在一条转弯点不多于两个的路径,就可以消去;如果没有,则不予以处理。
开始制作游戏时,主要需要解决的问题有以下几个方面:第一,如何设置整个游戏的界面。第二,如何控制连连看游戏中随机图片的生成且每种图片生成个数必须为偶数。第三,游戏开始后,需要判断鼠标两次点击的图片能否消去,即判断图片是否相同且片之间路径是否满足判断要求等。第四,如何实现游戏计时功能、刷新功能、重新开始新一局游戏功能。第五,相关游戏情况展示。
游戏往往会涉及游戏胜利或失败条件。对于连连看游戏来说,胜利条件是在规定时间内将游戏界面上所有图片全部依照一定规则消除掉。失败条件则相反,指未能或无法在规定时间内将棋盘上面的图片全部消除掉。

系统需求分析

软件需求分为四个层次,分别是:业务需求、用户需求、功能需求和非功能需求。  
业务需求主要反映了组织结构或客户对系统、产品高层次的目标要求,通常在项目定义与范围文档中予以说明;用户需求描述了用户使用产品必须要完成的任务,这在实例或方案脚本中予以说明;功能需求定义了开发人员必须实现的软件功能,使用户利用系统能够完成他们的任务,从而满足业务需求;非功能性的需求描述了系统展现给用户的行为和执行的操作等,它包括产品必须遵从的标准、规范和约束,操作界面的具体细节和构造上的限制。

业务需求

业务需求针对的是项目组或者公司,描述是公司想如何解决用户的问题,如何满足用户的欲望,并将利益最大化。
本项目课题是连连看游戏的设计与实现,在业务需求方面,第一,具备连连看基本游戏功能。选择两个图形,判断是否满足一定条件,条件即两个图形一致且二者之间存在转弯少于3的路径。当判定满足这一条件后,两张图片被消除。第二,具备附加功能:计时功能、重新开始功能、刷新当前界面功能等。

用户需求

本项目面向的用户是游戏玩家,对于用户而言,需求有两个方面,一方面,要求游戏界面整齐美观,长时间使用也应尽可能的减小对游戏的审美疲劳。另一方面,要求游戏体验良好。在运行游戏的过程中,能保证数据安全,游戏能稳定、高速地运行。对于游戏本身,用户往往要求游戏功能相对完善,游戏具备可娱乐性,并且游戏规则易理解,游戏操作既要简单同时也应有难度,在保证游戏操作顺滑、响应快速的情况下,游戏能具有一定的挑战性。
通过用例图能更清晰的分析用户需求,如图3-1连连看游戏的用例图。用户在连连看游戏中,能开始游戏、重新开始游戏、重排列游戏、结束游戏、退出游戏、消除图片、查看得分和闯关数等。
在这里插入图片描述
在这里插入图片描述

功能需求

根据上文游戏规则描述以及需求描述,游戏规则是模仿网络上普通的连连看游戏,主要需求是解决鼠标两次点击的图片能否消去的问题。当然,前提是点击两张相同的图片,若点击的是同一张图片或者两张不同的图片,则不予以处理。在两张相同图片所能连通的所有路径中,如果存在一条转弯点不多于两个的路径,就可以消去;如果没有,则不予以处理。这也是游戏的基本功能,给定任意具有相同图形的两个格子,我们需要寻找这两个格子之间在转弯最少的情况下,经过格子数目最少的路径。如果这个最优路径的转弯数目少于3 ,则这两个格子可以消去。
根据难度的不同该游戏由4、8、12、15种不同的图片组成,游戏开始将会出现64张随机组合的图片,在规则下点击两张相同的图片后,图片将会消失。图片全部消完为游戏成功,将进入下一关。游戏还将设置刷新功能,重新开始功能的按钮,并实现该功能,方便用户进行操作。游戏的主要功能将通过程序中的线程、布局功能、事件监听进行有效实现。
本系统将划分为以下几个模块,如图3-3系统功能模块图。将连连看游戏按照功能划分为:
消除模块:完成连连看游戏消除动作的模块。
重新开始模块:完成连连看游戏中重新开始新一局游戏功能的模块。
刷新模块:完成连连看游戏中,将游戏中未消除的图片个数记录并重新随机放置等数量图片的功能模块。
选择难度模块:完成游戏中切换游戏难度并开始新一局游戏的模块。
计时模块:完成游戏中倒计时并显示提示信息的模块。
状态显示模块:完成游戏中对游戏得分、闯关数记录的模块。
在这里插入图片描述

三、程序截图

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

四、代码


import java.awt.Choice;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LianLianKan extends JFrame {

	private static final long serialVersionUID = 1L;

	public LianLianKan() {
		LianLianKanJPanel llk = new LianLianKanJPanel();
		add(llk);

	}
	class LianLianKanJPanel extends JPanel implements ActionListener,ItemListener {

	private static final long serialVersionUID = 1L;//序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
		private int[][] map = new int[8][8];//8*8的正方形
		private int kind, randomx, randomy, randomx1, randomy1; // 种类,随机x
		private int coordinatex, coordinatey, coordinatex1, coordinatey1; // 坐标X
		private Point lineStart = new Point(0, 0);
		private int clicktimes;
		private int jishushengyu;//计数剩余
		private int Kinds = 4;
		private int score;
		private int guanshu;//关数

		
		loudou ld = new loudou();// 漏斗
		

		JButton BlockButton[][] = new JButton[8][8];//
		Choice difficultChoice = new Choice();
		JButton newgameButton = new JButton("重新开始");
		JButton reLoad = new JButton("刷新");

		ImageIcon ii = new ImageIcon("src/im/bk.jpg");

		ImageIcon aIcon = new ImageIcon("src/im/1.gif");
		ImageIcon bIcon = new ImageIcon("src/im/2.gif");
		ImageIcon cIcon = new ImageIcon("src/im/3.gif");
		ImageIcon dIcon = new ImageIcon("src/im/4.gif");
		ImageIcon eIcon = new ImageIcon("src/im/5.gif");
		ImageIcon fIcon = new ImageIcon("src/im/6.gif");
		ImageIcon gIcon = new ImageIcon("src/im/7.gif");
		ImageIcon hIcon = new ImageIcon("src/im/8.gif");
		ImageIcon iIcon = new ImageIcon("src/im/9.gif");
		ImageIcon jIcon = new ImageIcon("src/im/10.gif");
		ImageIcon kIcon = new ImageIcon("src/im/11.gif");
		ImageIcon lIcon = new ImageIcon("src/im/12.gif");
		ImageIcon mIcon = new ImageIcon("src/im/13.gif");
		ImageIcon nIcon = new ImageIcon("src/im/14.gif");
		ImageIcon oIcon = new ImageIcon("src/im/15.gif");

		public LianLianKanJPanel() {

			this.setLayout(null);

			newMap();
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					BlockButton[i][j] = new JButton();
					add(BlockButton[i][j]);
					BlockButton[i][j].addActionListener(this);//监听器
					BlockButton[i][j].setBounds(30 + j * 40, 30 + i * 40, 31,34);
				//	BlockButton[i][j].setBorderPainted(false);
				//  BlockButton[i][j].setVisible(true);
				}
			}
			difficultChoice.add("简单");
			difficultChoice.add("中等");
			difficultChoice.add("困难");
			difficultChoice.add("变态");

			newgameButton.setBounds(map[0].length * 40 + 80, 40, 100, 20);
			newgameButton.setBackground(Color.white);
			newgameButton.setBorderPainted(false); //去边框
			reLoad.setBounds(map[0].length * 40 + 100, 80, 60, 20);
			reLoad.setBackground(Color.white);
			reLoad.setBorderPainted(false);
			difficultChoice.setBounds(map[0].length * 40 + 100, 120, 60, 20);
			difficultChoice.addItemListener(this);
			newgameButton.addActionListener(this);
			reLoad.addActionListener(this);

			this.add(newgameButton);
			this.add(reLoad);
			this.add(difficultChoice);

			// /-------------------------漏斗
			ld.setBounds(map[0].length * 40 + 100, 200, 70, 150);// 漏斗
			ld.setBackground(Color.black);
			this.add(ld);
	

		}
		class loudou extends JPanel implements Runnable {
			private static final long serialVersionUID = 1L;
			private int dijiguan;
			int remainTimes = 0; // 时间
			int x1 = 0;
			int y1 = 30;
			int x2 = 60;
			int y2 = 150;
			Thread nThread1;//线程
			JLabel overJLabel = new JLabel();
			JDialog dialog = new JDialog();

			public loudou() {
				nThread1 = new Thread(this);				
				nThread1.start();
				this.setLayout(null);
				this.add(overJLabel);
				overJLabel.setBounds(0, 0, 200, 50);
				overJLabel.setForeground(Color.white);
			}

			public void setdijiguan(int x) {
				this.dijiguan = x;
			}

			public void paintComponent(Graphics g) // 画画函数
			{
				super.paintComponent(g);
								
				g.setColor(Color.green);
				for (int i = 0; i < 56; i++) {
					g.drawLine(x1 + i / 2 + 2, y1 + i, x2 - i / 2 - 2, y1 + i);
				}
				
				if (remainTimes < 55) {
					for (int i = 0; i < remainTimes; i++) {
						g.drawLine(x1 + i / 2 + 2, y2 - i - 1, x2 - i / 2 - 2, y2 - i
								- 1);
					}
					g.drawLine((x1 + x2) / 2, (y1 + y2) / 2, (x1 + x2) / 2, y2 - 2);
					g.drawLine((x1 + x2) / 2 + 1, (y1 + y2) / 2 + 1, (x1 + x2) / 2 + 1,y2 - 2);//两条竖线
					g.setColor(getBackground());
					for (int i = 0; i < remainTimes; i++) {
						g.drawLine(x1 + i / 2 + 2, y1 + i, x2 - i / 2 - 2, y1 + i);//覆盖上边的倒三角
					}
				}
				if (remainTimes >= 50 && remainTimes <= 55)
					overJLabel.setText(55-remainTimes +"s");
				
				if (remainTimes == 56) 
					overJLabel.setText("OVER");
			}

			public void setTimes(int x) {
				this.remainTimes = x;
			}

			public int getTimes() {
				return remainTimes;
			}

			public void run() {
				while (dijiguan < 20) {
					if (remainTimes == 0) {
						JOptionPane.showMessageDialog(null, "游戏开始?");
					}
					if (remainTimes == 56) {
						JOptionPane.showMessageDialog(null, "时间到!游戏结束!");
					}
					
					remainTimes++;
					repaint();
					
					try {
						if (dijiguan < 6)
							Thread.sleep(1500 - dijiguan * 100);
						if (dijiguan >= 6 && dijiguan <= 8)
							Thread.sleep(1000 - (dijiguan - 5) * 50);
						if (dijiguan > 8)
							Thread.sleep(850 - (dijiguan - 8) * 20);

					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			
		}



		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			//是父类JPanel里的方法,会把整个面板用背景色重画一遍,起到清屏的作用

			g.drawImage(ii.getImage(), 0, 0, this);
			//绘制两个文本字符串
			g.setColor(Color.white);
			g.drawString("得分: " + score, 430, 165);
			g.drawString("第 " + (guanshu + 1) + " 关", 430, 190);
			
			
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					switch (map[i][j]) {
					case 0:
						
						BlockButton[i][j].setVisible(false);
						break;
					case 1:
						BlockButton[i][j].setIcon(aIcon);
						break;
					case 2:
						BlockButton[i][j].setIcon(bIcon);
						break;
					case 3:
						BlockButton[i][j].setIcon(cIcon);
						break;
					case 4:
						BlockButton[i][j].setIcon(dIcon);
						break;
					case 5:
						BlockButton[i][j].setIcon(eIcon);
						break;
					case 6:
						BlockButton[i][j].setIcon(fIcon);
						break;
					case 7:
						BlockButton[i][j].setIcon(gIcon);
						break;
					case 8:
						BlockButton[i][j].setIcon(hIcon);
						break;
					case 9:
						BlockButton[i][j].setIcon(iIcon);
						break;
					case 10:
						BlockButton[i][j].setIcon(jIcon);
						break;
					case 11:
						BlockButton[i][j].setIcon(kIcon);
						break;
					case 12:
						BlockButton[i][j].setIcon(lIcon);
						break;
					case 13:
						BlockButton[i][j].setIcon(mIcon);
						break;
					case 14:
						BlockButton[i][j].setIcon(nIcon);
						break;
					case 15:
						BlockButton[i][j].setIcon(oIcon);
						break;
					default:
						break;
					}

				}

			}

		}
		//重载
		public void chongzai() {  
			jishushengyu = 0;
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					if (map[i][j] > 0) {
						jishushengyu++;
					}
				}
			}

			int[][] map1 = new int[8][8];
			this.map = map1;
			Random random = new Random();

			for (int i = 0; i < jishushengyu / 2; i++) {
				kind = random.nextInt(Kinds) + 1;//0~3+1  === 1~4
				do {				
					randomx1 = random.nextInt(8);//0-8随机数
					randomy1 = random.nextInt(8);
				} while (map[randomy1][randomx1] > 0);

				map[randomy1][randomx1] = kind;
				
				do {
					randomx = random.nextInt(8);
					randomy = random.nextInt(8);
				} while (map[randomy][randomx] > 0);

				map[randomy][randomx] = kind;
				
			}
			
			repaint();
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					
					BlockButton[i][j].setVisible(true);
				}
			}
			
			
		}

		public void newGame() {

			// JOptionPane.showMessageDialog(null,"你按了开始按钮");
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					BlockButton[i][j].setEnabled(true);
					BlockButton[i][j].setVisible(true);
				}
			}
			int[][] map = new int[8][8];
			this.map = map;
			newMap();
			ld.setTimes(0);
			score = 0;
			guanshu = 0;
			ld.setdijiguan(guanshu);
		}

		public void guoguan() {
			int jishushengyu2 = 0;
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					if (map[i][j] > 0) {
						jishushengyu2++;
					}
				}
			}
			if (jishushengyu2 == 0) {
				for (int i = 0; i < 8; i++) {
					for (int j = 0; j < 8; j++) {
						BlockButton[i][j].setEnabled(true);
						BlockButton[i][j].setVisible(true);
					}
				}
				int[][] map = new int[8][8];
				this.map = map;
				newMap();
				
				ld.setTimes(0);
				guanshu++;
				ld.setdijiguan(guanshu);
				reLoad.setEnabled(true);
			}

		}

		public void newMap() {
			ArrayList<Integer> numbers = new ArrayList<Integer>();//链表
			for (int i = 0; i < Kinds; i++) {
				numbers.add(i + 1);//加到列表尾部
				numbers.add(i + 1);
			}//每一次重新布局的时候,能保证一定有前几种难度中的图片类型
			
			Random random = new Random();
			int temp = 0;
			for (int i = 0; i < 32- Kinds; i++) {
				temp = random.nextInt(Kinds) + 1;//0~kinds-1之间的随机数在加1
				numbers.add(temp);
				numbers.add(temp);

			}
			Collections.shuffle(numbers);//随机打乱原来的顺序
			map = new int[8][8];
			temp = 0;

			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					//JOptionPane.showMessageDialog(null, numbers.get(temp));
					map[i][j] = numbers.get(temp++).intValue();//get方法返回第i个元素,intvalue 返回int类型
					
				}

			}

		}

		public void itemStateChanged(ItemEvent e) {
			// TODO 自动生成的方法存根
			if (e.getSource() == difficultChoice) {
				String selected = difficultChoice.getSelectedItem();
				if (selected == "简单") {
					Kinds = 4;
					newGame();
					repaint();
				} else if (selected == "中等") {
					Kinds = 8;
					newGame();
					repaint();
				} else if (selected == "困难") {
					Kinds = 12;
					newGame();
					repaint();
				} else if (selected == "变态") {
					Kinds = 15;
					newGame();
					repaint();
				}
			}
		}

		public void actionPerformed(ActionEvent e) {
			// TODO 自动生成的方法存根
			
			if (ld.getTimes() >56) {
				for (int i = 0; i < 8; i++) {
					for (int j = 0; j < 8; j++) {
						BlockButton[j][i].setEnabled(false);
					}
				}
			}
			if (e.getSource() == reLoad) {
				chongzai();
				reLoad.setEnabled(false);
			}
			if (e.getSource() == newgameButton) {
				newGame();
				reLoad.setEnabled(true);
			}

			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < 8; j++) {
					if (e.getSource() == BlockButton[j][i]) {
						clicktimes++; // 点击的次数
						lineStart.move(i, j);
						if (clicktimes % 2 == 1) {
							coordinatex1 = i;
							coordinatey1 = j;
							BlockButton[coordinatey1][coordinatex1].setEnabled(false);
							BlockButton[coordinatey][coordinatex].setEnabled(true);

						//	BlockButton[j][i].setEnabled(false);
						}
						if (clicktimes % 2 == 0) {
							
							coordinatex = i;
							coordinatey = j;
							BlockButton[coordinatey][coordinatex].setEnabled(false);
							BlockButton[coordinatey1][coordinatex1].setEnabled(true);
						}
					}

				}
			}

			this.requestFocus();
			clearBlock();

			/*
			 * for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) {
			 * BlockButton[j][i].setEnabled(true); }
			 * 
			 * }
			 */

			repaint();

		}

		// --------------------------------------------------------------------------
		// 判断在一列之内两图片之间是否全部是空白或直接相邻
		private boolean containsAllOrNoneZeroInColumn(int posX1, int posY1,
				int posX2, int posY2) {
			// 直接相连,因而不包含空白
			if (Math.abs(posY1 - posY2) == 0) {
				return true;
			}
			int a = posY1 < posY2 ? posY1 : posY2;
			int b = posY1 < posY2 ? posY2 : posY1;//y值:a小 b大
			for (int j = a + 1; j < b; j++) {
				if (map[posX1][j] != 0) {
					return false;
				}
			}
			return true;
		}

		// 判断在一行之内两图片之间是否全部是空白或直接相邻
		private boolean containsAllOrNoneZeroInRow(int posX1, int posY1,
				int posX2, int posY2) {
			// 直接相连,因而不包含空白
			if (Math.abs(posX1 - posX2) == 0) {
				return true;
			}
			int a = posX1 < posX2 ? posX1 : posX2;
			int b = posX1 < posX2 ? posX2 : posX1;
			for (int i = a + 1; i < b; i++) {
				if (map[i][posY1] != 0) {
					return false;
				}
			}
			return true;
		}

		// 是否可以一直线相连
		private boolean isLinkByOneLine(int posX1, int posY1, int posX2,
				int posY2) {

			if (posX1 != posX2 && posY1 != posY2) {
				return false;
			}
			if (posX1 == posX2) {
				if (containsAllOrNoneZeroInColumn(posX1, posY1, posX2, posY2)) {
					return true;
				}
			}
			if (posY1 == posY2) {
				if (containsAllOrNoneZeroInRow(posX1, posY1, posX2, posY2)) {
					return true;
				}
			}
			return false;
		}

		// 是否可以两直线相连
		private boolean isLinkByTwoLines(int posX1, int posY1, int posX2,
				int posY2) {
			if (posX1 != posX2 && posY1 != posY2) {
				// x1,y1 to x2,y1 to x2,y2
				if (containsAllOrNoneZeroInRow(posX1, posY1, posX2, posY1)
						&& map[posX2][posY1] == 0
						&& containsAllOrNoneZeroInColumn(posX2, posY1, posX2,
								posY2)) {
					return true;
				}
				// x1,y1 to x1,y2 to x2,y2
				if (containsAllOrNoneZeroInColumn(posX1, posY1, posX1, posY2)
						&& map[posX1][posY2] == 0
						&& containsAllOrNoneZeroInRow(posX1, posY2, posX2,
								posY2)) {
					return true;
				}

			}
			return false;
		}

		// 是否可以三直线相连
		private boolean isLinkByThreeLines(int posX1, int posY1, int posX2,
				int posY2) {
			if (isOnSameEdge(posX1, posY1, posX2, posY2)) {
				return true;
			}
			if (isOnThreeLinesLikeArc(posX1, posY1, posX2, posY2)) {
				return true;
			}
			if (isOnThreeLinesLikeZigzag(posX1, posY1, posX2, posY2)) {
				return true;
			}
			return false;
		}

		// 是否可以三直线相连,似U形
		private boolean isOnThreeLinesLikeArc(int posX1, int posY1, int posX2,
				int posY2) {
			if (isOnUpArc(posX1, posY1, posX2, posY2)) {
				return true;
			}
			if (isOnDownArc(posX1, posY1, posX2, posY2)) {
				return true;
			}
			if (isOnLeftArc(posX1, posY1, posX2, posY2)) {
				return true;
			}
			if (isOnRightArc(posX1, posY1, posX2, posY2)) {
				return true;
			}
			return false;
		}

		// ∪
		private boolean isOnUpArc(int posX1, int posY1, int posX2, int posY2) {
			// Y --> 0
			int lessY = posY1 < posY2 ? posY1 : posY2; //找小y
			for (int j = lessY - 1; j >= 0; j--) {
				if (containsAllOrNoneZeroInRow(posX1, j, posX2, j)
						&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, j)
						&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, j)
						&& map[posX1][j] == 0 && map[posX2][j] == 0) {
					return true;
				}
			}

			if (isOnSameEdge(posX1, 0, posX2, 0)
					&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, 0)
					&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, 0)
					&& (map[posX1][0] == 0 && map[posX2][0] == 0
							|| map[posX1][0] == 0
							&& map[posX2][0] == map[posX2][posY2] || map[posX1][0] == map[posX1][posY1]
							&& map[posX2][0] == 0)) {
				return true;
			}

			return false;
		}

		// ∩
		private boolean isOnDownArc(int posX1, int posY1, int posX2, int posY2) {
			int moreY = posY1 < posY2 ? posY2 : posY1;
			for (int j = moreY + 1; j <= 8 - 1; j++) {
				if (containsAllOrNoneZeroInRow(posX1, j, posX2, j)
						&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, j)
						&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, j)
						&& map[posX1][j] == 0 && map[posX2][j] == 0) {
					return true;
				}
			}
			if (isOnSameEdge(posX1, 8 - 1, posX2, 8 - 1)
					&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, 8 - 1)
					&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, 8 - 1)
					&& (map[posX1][8 - 1] == 0 && map[posX2][8 - 1] == 0
							|| map[posX1][8 - 1] == map[posX1][posY1]
							&& map[posX2][8 - 1] == 0 || map[posX1][8 - 1] == 0
							&& map[posX2][8 - 1] == map[posX2][posY2])) {
				return true;
			}
			return false;
		}

		// ﹚
		private boolean isOnLeftArc(int posX1, int posY1, int posX2, int posY2) {
			int lessX = posX1 < posX2 ? posX1 : posX2;
			for (int i = lessX - 1; i >= 0; i--) {
				if (containsAllOrNoneZeroInColumn(i, posY1, i, posY2)
						&& containsAllOrNoneZeroInRow(i, posY1, posX1, posY1)
						&& containsAllOrNoneZeroInRow(i, posY2, posX2, posY2)
						&& map[i][posY1] == 0 && map[i][posY2] == 0) {
					return true;
				}
			}

			if (isOnSameEdge(0, posY1, 0, posY2)
					&& containsAllOrNoneZeroInRow(0, posY1, posX1, posY1)
					&& containsAllOrNoneZeroInRow(0, posY2, posX2, posY2)
					&& (map[0][posY1] == 0 && map[0][posY2] == 0
							|| map[0][posY1] == map[posX1][posY1]
							&& map[0][posY2] == 0 || map[0][posY1] == 0
							&& map[0][posY2] == map[posX2][posY2])) {
				return true;
			}

			return false;
		}

		// (
		private boolean isOnRightArc(int posX1, int posY1, int posX2, int posY2) {
			int moreX = posX1 < posX2 ? posX2 : posX1;
			for (int i = moreX + 1; i <= 8 - 1; i++) {
				if (containsAllOrNoneZeroInColumn(i, posY1, i, posY2)
						&& containsAllOrNoneZeroInRow(i, posY1, posX1, posY1)
						&& containsAllOrNoneZeroInRow(i, posY2, posX2, posY2)
						&& map[i][posY1] == 0 && map[i][posY2] == 0) {
					return true;
				}
			}

			if (isOnSameEdge(8 - 1, posY1, 8 - 1, posY2)
					&& containsAllOrNoneZeroInRow(posX1, posY1, 8 - 1, posY1)
					&& containsAllOrNoneZeroInRow(posX2, posY2, 8 - 1, posY2)
					&& (map[8 - 1][posY1] == 0 && map[8 - 1][posY2] == 0
							|| map[8 - 1][posY1] == map[posX1][posY1]
							&& map[8 - 1][posY2] == 0 || map[8 - 1][posY1] == 0
							&& map[8 - 1][posY2] == map[posX2][posY2])) {
				return true;
			}

			return false;
		}

		// 是否可以三直线相连,似之字形N
		private boolean isOnThreeLinesLikeZigzag(int posX1, int posY1,
				int posX2, int posY2) {
			if (isOnZigzagWith1Row2Cols(posX1, posY1, posX2, posY2)) {
				return true;
			}
			if (isOnZigzagWith2Rows1Col(posX1, posY1, posX2, posY2)) {
				return true;
			}

			return false;
		}

		// 是否可以三直线相连,似之字形, 两行一列 Z
		private boolean isOnZigzagWith2Rows1Col(int posX1, int posY1,
				int posX2, int posY2) {
			int moreX = posX1 < posX2 ? posX2 : posX1;
			int lessX = posX1 < posX2 ? posX1 : posX2;
			for (int i = lessX + 1; i < moreX; i++) {
				if (containsAllOrNoneZeroInColumn(i, posY1, i, posY2)
						&& containsAllOrNoneZeroInRow(i, posY1, posX1, posY1)
						&& containsAllOrNoneZeroInRow(i, posY2, posX2, posY2)
						&& map[i][posY1] == 0 && map[i][posY2] == 0) {
					return true;
				}
			}
			return false;
		}

		// 是否可以三直线相连,似之字形, 一行两列
		private boolean isOnZigzagWith1Row2Cols(int posX1, int posY1,
				int posX2, int posY2) {
			int moreY = posY1 < posY2 ? posY2 : posY1;
			int lessY = posY1 < posY2 ? posY1 : posY2;
			for (int j = lessY + 1; j < moreY; j++) {
				if (containsAllOrNoneZeroInRow(posX1, j, posX2, j)
						&& containsAllOrNoneZeroInColumn(posX1, posY1, posX1, j)
						&& containsAllOrNoneZeroInColumn(posX2, posY2, posX2, j)
						&& map[posX1][j] == 0 && map[posX2][j] == 0) {
					return true;
				}
			}
			return false;
		}

		// 是否处于游戏区域的4条边的同一边上
		private boolean isOnSameEdge(int posX1, int posY1, int posX2, int posY2) {
			if ((posY1 == posY2 && posY2 == 0)
					|| (posY1 == posY2 && posY2 == 8 - 1)
					|| (posX1 == posX2 && posX2 == 0)
					|| (posX1 == posX2 && posX2 == 8 - 1)) {
				return true;
			}

			return false;
		}

		// --------------------------------------------------------------------------
		public boolean ifcanTouch(int posX1, int posY1, int posX2, int posY2) {

			if (isLinkByOneLine(posX1, posY1, posX2, posY2)) {
				return true;
			}
			// 是否可以两直线相连
			if (isLinkByTwoLines(posX1, posY1, posX2, posY2)) {
				return true;
			}
			// 是否可以三直线相连
			if (isLinkByThreeLines(posX1, posY1, posX2, posY2)) {
				return true;
			}

			return false;

		}

		public void clearBlock() {
			if (clicktimes >=2) {
			
				if (map[coordinatey1][coordinatex1] == map[coordinatey][coordinatex]
						&& !((coordinatex1 == coordinatex) && (coordinatey1 == coordinatey))) {
					
					if (ifcanTouch(coordinatey1, coordinatex1, coordinatey,
							coordinatex)) {
						
						if (map[coordinatey1][coordinatex1] > 0)
							score = score + 10;
						
						map[coordinatey1][coordinatex1] = 0;
						map[coordinatey][coordinatex] = 0;
						guoguan();
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		
	String lookAndFeel ="javax.swing.plaf.metal.MetalLookAndFeel";//swing 外观和感觉
		try {
			UIManager.setLookAndFeel(lookAndFeel);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		LianLianKan frame = new LianLianKan();
		frame.setTitle("连连看");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBounds(100, 100, 560, 430);
		frame.setLocation(440, 100);
//		frame.setSize(600, 500);
		frame.setSize(540, 440);
		frame.setVisible(true);

	}

}



五、联系与交流

q:969060742 完整报告、程序资源、代码、ppt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1546763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MATLAB源码-第13期】基于matlab的4ASK的误码率BER和误符号率SER理论和实际对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 "4ASK" 是一种数字调制技术&#xff0c;代表4级振幅移移键控&#xff08;4-Level Amplitude Shift Keying&#xff09;调制。它是一种数字通信中常用的调制方式之一&#xff0c;用于将数字信号转换为模拟信号以便传…

map china not exists. the geojson of the map must be provided.

map china not exists. the geojson of the map must be provided. 场景&#xff1a;引入echarts地图报错map china not exists. the geojson of the map must be provided. 原因&#xff1a; echarts版本过高&#xff0c;ECharts 之前提供下载的矢量地图数据来自第三方&…

小白学视觉 | 图像上的 OpenCV 算术运算

本文来源公众号“小白学视觉”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;图像上的 OpenCV 算术运算 1 OpenCV 简介 图像可以进行算术运算&#xff0c;例如加法、减法和按位运算&#xff08;AND、OR、NOT、XOR&#xff09;。…

模拟器App抓包 - 证书双向验证绕过手段

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog 0x00 Frida 环境配置 1. 本地安装 Frida pip install frida pip install frida-tools2. 模拟器安装 Fr…

【详细讲解yarn的安装和使用】

&#x1f308;个人主页:程序员不想敲代码啊&#x1f308; &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f3c6; &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提…

leetcode 15.三数之和 JAVA 双指针法

题目 思路 双指针法 去重 为啥要去重呢&#xff1f;因为题目中说了要返回不重复的三元组。拿示例1来看&#xff0c;&#xff08;-1&#xff0c;0&#xff0c;1&#xff09;和&#xff08;0&#xff0c;1&#xff0c;-1&#xff09;虽然都等于0&#xff0c;但其实它们里面的数…

Unix环境高级编程-学习-08-自旋锁与屏障

目录 一、多线程相关文章链接 二、自由抒发 1、自旋锁 2、屏障 三、函数介绍 1、pthread_spin_init &#xff08;1&#xff09;声明 &#xff08;2&#xff09;作用 &#xff08;3&#xff09;参数 &#xff08;4&#xff09;返回值 &#xff08;5&#xff09;注意点 …

c语言文件操作(下)

目录 1.文件的随机读写1.1 fseek1.2 ftell1.3 rewind 2. 文件结束的判定2.1 文本文件读取结束的判断2.2 二进制文件读取结束的判断 3. 文件缓冲区 1.文件的随机读写 1.1 fseek 根据⽂件指针的位置和偏移量来定位⽂件指针。 函数原型&#xff1a; int fseek (FILE * stream,…

Python篇之网络编程,实现简单的服务端和客户端的内容传输

本小节内容&#xff1a;实现简单的信息交流 文章目录 一、 Socket介绍二、客户端与服务端三、在python中实现网络通信1. 服务端2. 客户端3. 连接测试 一、 Socket介绍 socket (简称 套接字) 模块是其内置的标准库之一&#xff0c;它实现了BSD sockets API&#xff0c;允许开发…

(分享)一个图片添加水印的小demo的页面,可自定义样式

有时候想给某张图片添加一个自己的水印&#xff0c;但是又懒的下载相应软件&#xff0c;用js canvas制作一个静态页面&#xff0c;对于单张图片添加自定义文字水印&#xff0c;大小 间距&#xff0c;角度可调。 页面如下&#xff1a; 选择图片&#xff0c;设置相应参数&#x…

深度学习模型部署(十二)CUDA编程-绪

CUDA 运行时 API 与 CUDA 驱动 API 速度没有差别&#xff0c;实际中使用运行时 API 较多&#xff0c;运行时 API 是在驱动 API 上的一层封装。​ CUDA 是什么&#xff1f;​ CUDA(Compute Unified Device Architecture) 是 nvidia 推出的一个通用并行技术架构&#xff0c;用它…

【LLM】大模型推理加速 KV-Cache

目录 模型推理过程KV Cache原理KV Cache的存储 模型推理过程 在了解KVCache之前&#xff0c;我们需要知道Transformer类大模型的推理过程。 对于LLM进行一次前向传播也就是生成一个token的过程可以被分解成以下步骤&#xff1a; 文本 T i n p u t T_{input} Tinput​经过Toke…

数据结构与算法分析引论1

1.解决问题的算法有很多&#xff0c;但是在输入不同的情况下&#xff0c;不同算法之间的差异也很大&#xff0c;我们总是追求一个更快、更有效的方法。比如说普通的依次查找和二分查找&#xff0c;两者的差异就很大。我们使用大O表示法来表示算法的速度。依次查找就是O(n)&…

MATLAB 自定义生成平面点云(可指定方向,添加噪声)(48)

MATLAB 自定义生成平面点云(可指定方向,添加噪声)(48) 一、算法介绍二、算法步骤三、算法实现1.代码2.效果一、算法介绍 通过这里的平面生成方法,可以生成模拟平面的点云数据,并可以人为设置平面方向,平面大小,并添加噪声来探索不同类型的平面数据。这种方法可以用于…

UDS诊断中的NRC

我总结了一张表格&#xff1a;详细解释了NRC的分布情况和NRC的触发条件 1&#xff1a;基本概念 NRC 全称Negative Response Code(否定响应代码)&#xff0c;是指示uds诊断中的&#xff0c;指示否定响应的原因 例如&#xff1a;0x22 服务 request 报文 0x618 03 22 F1 34 0…

电脑物理磁盘空间不足?试试这5种清理和优化方法!

随着我们使用电脑的时间越来越长&#xff0c;物理磁盘空间可能会逐渐变得捉襟见肘。当你的电脑提示磁盘空间不足时&#xff0c;不要慌张&#xff0c;这里有五种方法可以帮助你清理和优化电脑&#xff0c;释放宝贵的存储空间。 1. 卸载不常用的程序和游戏 许多用户在安装软件和…

机器学习基础——模型评估与选择(部分)

目录 一、前言&#xff1a;误差与拟合 &#xff08;一&#xff09;经验误差 &#xff08;二&#xff09;过拟合、欠拟合 二、评估方法 &#xff08;一&#xff09;评估总体的思路 &#xff08;二&#xff09;如何划分训练集和测试集 1.留出法 2.k折交叉验证 3.自助法 …

程序员35岁真的就是危机吗?

前言 35岁被认为是程序员职业生涯的分水岭&#xff0c;许多程序员开始担忧自己的职业发展是否会受到年龄的限制。有人担心随着年龄的增长&#xff0c;技术更新换代的速度会使得资深程序员难以跟上&#xff1b;而另一些人则认为&#xff0c;丰富的经验和深厚的技术积累是年轻程…

knife4j/swagger救援第一现场

1、前方来报&#xff0c;测试环境springboot项目无法启动&#xff0c;现场如下&#xff1a; Error starting ApplicationContext. To display the auto-configuration report re-run your application with debug enabled. [ERROR] 2024-03-20 12:54:42,718 --main-- [org.spr…

一键跳过开屏广告,这下舒服了

现在的app开屏广告越来越过分了&#xff0c;不小心摇一摇翻转就点开广告了。 今天分享个强大的自动跳过广告https://github.com/gkd-kit/gkd&#xff0c;李跳跳替代品&#xff0c;下载地址在公众号后台对话框回复 广告 玩转互联网达人 苏生不惑备用号&#xff0c;分享各种黑科…