java實現(xiàn)九宮格拼圖游戲
本文實例為大家分享了java實現(xiàn)九宮格拼圖游戲的具體代碼,供大家參考,具體內(nèi)容如下
設計步驟:
先將框架構思出來,首先將拼圖游戲的雛形實現(xiàn),即一個界面,九個按鈕,按鈕上的圖片顯示出自己想要的圖片。
(1)其次構思移動版塊的問題,想到按鈕直接互換是極為麻煩的一件事,所以采用更換按鈕上的圖片。按鈕類上有兩個屬性,a[9]表示按鈕的位置,b[9]表示按鈕上圖片的編號, 空白快圖片編號為8標記,點擊按鈕之后,點擊事件得到點擊的塊數(shù)在哪(1-9),if -else判斷相鄰是否為標記的空白快。方法簡單但是代碼量長。
(2)在完成了上述游戲的靈魂——移動算法之后。接下來便是加入一個判斷是否勝利的算法了。在上一段中我們提到有兩個按鈕屬性 a,b來記錄信息,在未打亂之前,ab對應,值相等。那么我們在每一次的鼠標點擊拼圖按鈕之后進行一次判斷,是否每一個a[i]都對應著自身b[i]值,如果是的話就給出勝利信號。
(3)完成了結(jié)束條件后,我們再設計一個開始游戲,打亂拼圖的算法。一開始先考慮了隨機置入圖片的方法,但是在八數(shù)碼問題中,隨機置入的話會存在奇偶性,有一半的幾率是沒有解法的。如果采用此法,我不得不再寫一個判斷隨機打亂之后是否有解的算法。這樣會非常麻煩,并且與我之前寫的版塊內(nèi)容不兼容。由于我們寫好了移動算法,所以我們隨機移動可移動的版塊若干次,次數(shù)足夠多的情況下便可以做到打亂拼圖的效果,并且保證此法必然有解。
(4)在第三步完成之后,新增了一個點擊鎖click,初始化為零。當且僅當有效移動之后click自增1。在結(jié)束條件中新增一個點擊鎖是否大于零的判斷條件,這樣我們就可以避免在游戲未開始時隨機點擊一個方塊就給出勝利。
(5)添加還原圖片功能。在每一次完成游戲之后,或者感覺太難想從頭來過,按照人們的思維,總想點擊一鍵還原。還原的算法有智能的搜索算法,有廣度,深度,a+等,輸入人工智能中的八數(shù)碼問題,還有最簡單的直接“重置”,我采用代碼量少的重置,留下八數(shù)碼當成提示功能。思想是先將按鈕顯示的圖片重置,再還原按鈕的兩個屬性。
(6)在上述功能實現(xiàn)之后,此設計初具備一個拼圖游戲的功能了。在興趣之下想做提示功能,本意想做出根據(jù)當前局面。搜索出最佳的步驟并提示,但是對廣度搜索的學習不夠,只能算出最短步驟次數(shù),還不會將最短路徑回溯顯示出來。所以只能做出簡單的提示,搜索的過程顯示在eclipse控制臺。
以上便是本程序的設計步驟,源代碼于下,可直接運行,圖片位置需要自己設置。
package 拼圖; import java.awt.BorderLayout; import java.awt.Component; import java.awt.GridLayout; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; import javax.imageio.ImageIO; import javax.swing.*; class Palace{ //算出最短步數(shù) String start;//初始字符串 String end;//目標字符串 int result=-1;//最終結(jié)果 public int Palacea(String shuju){ this.start = shuju; end = "12345678."; HashMap<String, Integer> memery = new HashMap<>(100000);//用于保存之前狀態(tài),key代表狀態(tài)字符串,value代表到key狀態(tài)所用的最小步數(shù) Queue<String> process = new LinkedList<String>();//bfs用到的隊列 memery.put(start,0);//放入初始字符串 process.offer(start);//放入初始字符串 while(result==-1){//當沒有搜索到結(jié)果是繼續(xù)搜索 String cur = process.poll(); char[] a=cur.toCharArray(); int count=0; for(int b=0;b<a.length;b++) { count++; System.out.print(a[b]+" "); if(count%3==0)System.out.println(); } System.out.println("++++++++++++++"); int tmp = 0; while(cur.charAt(tmp)!='.'){ tmp++; } int[] d = {-3,3,-1,1};//方向數(shù)組,分別表示上下左右 for(int i=0;i<4;i++){ int p = tmp+d[i]; int chengji = tmp*p; if(p>-1&&p<9&&chengji!=6&&chengji!=30){ //2-->3,3-->2,5-->6,6-->5跨行了,要去掉 String change = cur; char c = cur.charAt(p); change = cur.replace('.', '*');//交換String中的兩個字符,借助中間字符‘*' change = change.replace(c,'.'); change = change.replace('*',c); if(change.equals(end)){//找到了目標狀態(tài) result = memery.get(cur)+1; } if(!memery.containsKey(change)){//如果之前沒有這種狀態(tài) memery.put(change,memery.get(cur)+1); process.add(change);//存入隊列 } } } } System.out.println(result); return result; } } class tu extends JButton { int ID; int nowID; int IMAGEWIDTH; int IMAGEHEIGHT; int nowx; int nowy; Icon icon; public tu(Icon icon) { this.setIcon(icon); } public tu(Icon icon, int id, int imagewidth, int height,int nowx,int nowy,int nowid)//構造函數(shù)初始化,傳入兩個參數(shù),一個是圖像的圖標,一個是該按鈕的數(shù)組ID { this.setIcon(icon); this.ID = id; this.nowID = nowid; this.IMAGEWIDTH = imagewidth; this.IMAGEHEIGHT = height; this.setSize(IMAGEWIDTH, IMAGEHEIGHT); this.nowx=nowx; this.nowy=nowy; this.icon=icon; } public Icon geticon() { return icon; } public int getID() { return ID; } public int getnowID() { return nowID; } public int getx() { return this.getBounds().x; } public int gety() { return this.getBounds().y; } public int getnowx() { return nowx; } public int getnowy() { return nowy; } } class pintus extends JFrame implements MouseListener, ActionListener { private JButton strat,strat1,strat2,yuan,restart,save,readsave,tishi; //按鈕 private JLabel raw; //按鈕 private tu tu[]=new tu[9]; //標簽 private tu tuz[]=new tu[9]; JLabel tishikuan; //標簽 private int ID; ImageIcon icon1=null; int jishu=0; JPanel j1=new JPanel();//新建中間容器 JPanel j2=new JPanel(); JPanel j3=new JPanel(); public pintus() { BufferedImage tutu=null; ImageIcon icon = null; BufferedImage bufnew=null; int w=0; int h=0; int m = 0; //jframe設置基本屬性 setTitle("05林-拼圖游戲"); 添加布局 j1.setLayout(new GridLayout(3, 3)); //設置中間流式布局 //j2.setLayout(new GridLayout(1, 4)); //設置中間流式布局 ///圖片切割并存入 try { tutu = ImageIO.read(new File("C:\\Users\\czldd\\eclipse-workspace\\拼圖\\src\\拼圖\\原.png")); w=tutu.getWidth()/3; h=tutu.getHeight()/3; setSize(tutu.getWidth(),tutu.getHeight()+175); // //jframe設置大小屬性 //System.out.println(w+" "+h); } catch (IOException e) { System.out.println("錯誤"); e.printStackTrace(); } for(int i = 0; i < 3 ;i++) { for(int j = 0; j < 3; j++) { m=j*3+i; bufnew = tutu.getSubimage(w*i, h*j, w, h); icon = new ImageIcon(bufnew); tu [m]=new tu(icon,m,w,h,i,j,m); tu [m].setLocation(w*j, h*i); tuz [m]=new tu(icon,m,w,h,i,j,m); tuz [m].setLocation(w*j, h*i); if(m==8) { icon=new ImageIcon("C:\\Users\\czldd\\eclipse-workspace\\拼圖\\src\\拼圖\\白.png"); tu[m]=new tu(icon,m,w,h,i,j,m); tuz[m]=new tu(icon,m,w,h,i,j,m); } } } j2.add(strat=new JButton("簡單")); j2.add(strat1=new JButton("中等")); j2.add(strat2=new JButton("復雜")); j2.add(yuan=new JButton("還原")); j2.add(tishi=new JButton("提示")); //j2.add(restart=new JButton("重置")); //j2.add(save=new JButton("保存進度")); //j2.add(readsave=new JButton("讀取進度")); icon=new ImageIcon("C:\\Users\\czldd\\eclipse-workspace\\拼圖\\src\\拼圖\\小.png"); j2.add(raw=new JLabel(icon)); strat.addActionListener(this); strat1.addActionListener(this); strat2.addActionListener(this); yuan.addActionListener(this); tishi.addActionListener(this); j3.add(tishikuan=new JLabel("系統(tǒng)提示:請選擇游戲模式")); icon1=(ImageIcon) tu[8].geticon(); zairu(); // setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); setResizable(false); } /設置按鈕 public void zairu() { for(int a=0;a<9;a++) //輸入圖片 { j1.add(tu[a]); tu [a].addMouseListener(this); //設置鼠標事件 } add(j1,BorderLayout.CENTER); add(j2,BorderLayout.PAGE_START); add(j3,BorderLayout.PAGE_END); } public void qingkong() { removeAll(); } public void moves(tu t) { int a=t.getnowID(); icon1=new ImageIcon("C:\\Users\\czldd\\eclipse-workspace\\拼圖\\src\\拼圖\\白.png"); if(a==0) { if(tu[a+1].getID()==8) { tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+1].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a+3].getID()==8) { tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+3].icon=t.icon;t.icon=icon1;jishu++;} } if(a==1) { if(tu[a+1].getID()==8) { tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+1].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a+3].getID()==8) { tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-1].getID()==8) { tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==2) { if(tu[a+3].getID()==8) { tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-1].getID()==8) { tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==3) { if(tu[a+3].getID()==8) { tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-3].getID()==8) { tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-3].icon=t.icon;t.icon=icon1; jishu++;} if(tu[a+1].getID()==8) { tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==4) { if(tu[a+3].getID()==8) { tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-3].getID()==8) { tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-3].icon=t.icon;t.icon=icon1; jishu++;} if(tu[a+1].getID()==8) { tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+1].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-1].getID()==8) { tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==5) { if(tu[a+3].getID()==8) { tu[a+3].setIcon(t.geticon()); tu[a+3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-3].getID()==8) { tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a-1].getID()==8) { tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==6) { if(tu[a-3].getID()==8) { tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a+1].getID()==8) { tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==7) { if(tu[a-3].getID()==8) { tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-3].icon=t.icon;t.icon=icon1;jishu++;} if(tu[a+1].getID()==8) { tu[a+1].setIcon(t.geticon()); tu[a+1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a+1].icon=t.icon;t.icon=icon1; jishu++;} if(tu[a-1].getID()==8) { tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} } if(a==8) { if(tu[a-3].getID()==8) { tu[a-3].setIcon(t.geticon()); tu[a-3].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-3].icon=t.icon;t.icon=icon1;jishu++; } if(tu[a-1].getID()==8) { tu[a-1].setIcon(t.geticon()); tu[a-1].ID=t.getID(); t.setIcon(icon1);t.ID=8; tu[a-1].icon=t.icon;t.icon=icon1;jishu++;} } } /圖片移動事件 public void mouseClicked(MouseEvent e){ //設置執(zhí)行事件 tu t =(tu) e.getSource(); System.out.println("原本的位置:"+t.getID()+" 點擊的位置:"+t.getnowID()); int a=t.getnowID(); moves(t); String s="系統(tǒng)提示:游戲繼續(xù)"+",點擊的塊數(shù)目標位置為"+t.getID(); tishikuan.setText(s); if(win()&&jishu!=0) {jishu=0;JOptionPane.showConfirmDialog(null, "你贏了! " ,"拼圖",JOptionPane.CANCEL_OPTION); } } private boolean win() { int sum=0; for(int s=0;s<9;s++) { if(tu[s].ID==tu[s].nowID) sum++; } if(sum==9) { tishikuan.setText("系統(tǒng)提示:你贏了"); return true;} else { return false; } } public void actionPerformed(ActionEvent e) { //設置執(zhí)行事件} if(e.getSource()==strat) { luan(); String s="系統(tǒng)提示:游戲開始,簡單模式"; tishikuan.setText(s); for(int a=0;a<9;a++) { if(tu[a].ID==8) {System.out.println(0);continue;} System.out.println(tu[a].ID+1);} } if(e.getSource()==strat1) { luan1(); String s="系統(tǒng)提示:游戲開始,中等模式"; tishikuan.setText(s); for(int a=0;a<9;a++) { if(tu[a].ID==8) {System.out.println(0);continue;} System.out.println(tu[a].ID+1);} } if(e.getSource()==strat2) { luan2(); String s="系統(tǒng)提示:游戲開始,復雜模式"; tishikuan.setText(s); for(int a=0;a<9;a++) { if(tu[a].ID==8) {System.out.print(".");continue;} System.out.print(tu[a].ID+1);} } if(e.getSource()==yuan) { String s="系統(tǒng)提示:已經(jīng)還原,請重新選擇游戲模式"; tishikuan.setText(s); try { huanyuan(); } catch (IOException e1) { // TODO 自動生成的 catch 塊 e1.printStackTrace(); } } if(e.getSource()==tishi) { if(jishu==0) { String s="系統(tǒng)提示:系統(tǒng)利用廣度搜索算出解法,需要0步"; tishikuan.setText(s); } else { String d = "" ; for(int a=0;a<9;a++) { if(tu[a].ID==8) {d = d+".";continue;} d = d+Integer.toString(tu[a].ID+1); } System.out.println(d); Palace palace = new Palace(); String s="系統(tǒng)提示:系統(tǒng)利用廣度搜索算出解法,需要"+palace.Palacea(d)+"步"; tishikuan.setText(s); } } } private void huanyuan() throws IOException { jishu=0; for(int a=0;a<9;a++) { //顯示圖 tu[tu[a].ID].setIcon(tu[a].geticon()); } for(int i = 0; i < 9 ;i++) { //還原圖 tu[i].icon=tuz[i].icon; } for(int i = 0; i < 9 ;i++) { //還原標記點 tu[i].ID=tu[i].nowID=i; } } //打亂順序!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! private void luan() { for(int a=0;a<20;a++) { int b=(int) (Math.random()*9); moves(tu[b]); } } private void luan1() { for(int a=0;a<100;a++) { int b=(int) (Math.random()*9); moves(tu[b]); } } private void luan2() { for(int a=0;a<10000;a++) { int b=(int) (Math.random()*9); moves(tu[b]); } } /// public void setIcon(String file, JButton iconButton) { ImageIcon icon = new ImageIcon(file); Image temp = icon.getImage().getScaledInstance(iconButton.getWidth(), iconButton.getHeight(), icon.getImage().SCALE_DEFAULT); icon = new ImageIcon(temp); iconButton.setIcon(icon); } @Override public void mouseEntered(MouseEvent e) { // TODO 自動生成的方法存根 } @Override public void mouseExited(MouseEvent e) { // TODO 自動生成的方法存根 } @Override public void mousePressed(MouseEvent e) { // TODO 自動生成的方法存根 } @Override public void mouseReleased(MouseEvent e) { // TODO 自動生成的方法存根 } / public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch(Exception e) {} SwingUtilities.invokeLater(new Runnable() { public void run() { new pintus(); } }); } }
運行:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
解決spring boot 1.5.4 配置多數(shù)據(jù)源的問題
下面小編就為大家?guī)硪黄鉀Qspring boot 1.5.4 配置多數(shù)據(jù)源的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06java利用注解實現(xiàn)簡單的excel數(shù)據(jù)讀取
這篇文章主要為大家詳細介紹了java利用注解實現(xiàn)簡單的excel數(shù)據(jù)讀取,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06使用dom4j解析xml文件,并轉(zhuǎn)出json格式問題
這篇文章主要介紹了使用dom4j解析xml文件,并轉(zhuǎn)出json格式問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09Java用Arrays.fill()初始化二維數(shù)組的實現(xiàn)
這篇文章主要介紹了Java用Arrays.fill()初始化二維數(shù)組的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01SpringMVC @RequestBody屬性名大寫字母注入失敗的解決
這篇文章主要介紹了SpringMVC @RequestBody屬性名大寫字母注入失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04mybatis QueryWrapper的條件構造之a(chǎn)pply、last、select解析
這篇文章主要介紹了mybatis QueryWrapper的條件構造之a(chǎn)pply、last、select,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03