国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

java實現簡易的五子棋游戲

瀏覽:75日期:2022-08-11 09:14:30

本文實例為大家分享了java實現簡易五子棋游戲的具體代碼,供大家參考,具體內容如下

先上效果圖

java實現簡易的五子棋游戲

一、問題分析

1、五子棋游戲分析:

五子棋作為較為普遍且簡易的娛樂游戲,受到眾多人的熱愛,且五子棋AI也是一個較為容易實現的AI。下面我們先來分析游戲規則。(哈哈,雖然大家都知道,但我還是想寫寫)雙方分別使用黑白兩色棋子,下在棋盤橫線交叉處,先連成五子者勝利。(黑棋禁手啥的規則在我的程序里沒加,就不贅述了)。

2、程序分析:

(1)首先,五子棋開始,我們需要一個棋盤,15*15的棋盤,需要黑白棋子。

(2)其次,我們需要實現棋子順序的改變,就是實現先下黑棋,再下白棋,然后實現一個基本的修正功能,就是通過點擊交叉點周圍的位置,使棋子下到交叉處。

(3)再之后呢,有了棋子棋盤,(其實這個時候已經能進行下棋了,自己判斷勝負,哈哈),但是呢,我們接下來需要加一個判斷輸贏的功能。(4)接下來,我們就來豐富我們的五子棋游戲,加一些功能鍵,例如重新開始,悔棋,認輸,計時啥啥啥的。

(5)最后來一個高級點的,就是實現人機對戰,實現AI下棋。

二、模塊分析

1、棋盤棋子模塊

棋盤嘛就用直線畫就好,橫線15條,豎線15條,棋子也就兩個,可以畫得花哨一點,比如3D棋子,也可以簡單一點就用填充圓就好。博主畫了一個黑色3D棋子,白的沒畫。(這里繼承了我之前的一個畫板,實現直線的重繪,可以去翻一翻我的之前有關畫板的博客)。創建一個二維數組,存放棋子,用1代表黑棋,2代表白棋,0代表沒棋。用count變量來計算到誰下棋了,以及記錄下了第幾顆棋子了。

以下是窗體代碼

public void outUI(){ //設置標題 this.setTitle('五子棋'); this.setSize(1680,1380); this.setLayout(null); JButton btn = new JButton(); JButton btn1 = new JButton(); JButton btn2 = new JButton(); JButton btn3 = new JButton(); JButton btn4 = new JButton(); btn.setBounds(1340, 780, 210, 65); btn1.setBounds(1340,860,210, 65); btn2.setBounds(1340,940,210, 65); btn3.setBounds(320,1200,210, 65); btn4.setBounds(780,1200,210, 65); //獲取一個圖片 ImageIcon square=new ImageIcon(this.getClass().getResource('JButton1.jpg')); ImageIcon square1=new ImageIcon(this.getClass().getResource('JButton.jpg')); ImageIcon square2=new ImageIcon(this.getClass().getResource('JButton2.jpg')); ImageIcon square3=new ImageIcon(this.getClass().getResource('JButton3.jpg')); ImageIcon square4=new ImageIcon(this.getClass().getResource('JButton4.jpg')); //設置圖片的大小 square.setImage(square.getImage().getScaledInstance(210, 65, 0)); square1.setImage(square1.getImage().getScaledInstance(210, 65, 0)); square2.setImage(square2.getImage().getScaledInstance(210, 65, 0)); square3.setImage(square3.getImage().getScaledInstance(210, 65, 0)); square4.setImage(square4.getImage().getScaledInstance(210, 65, 0)); //把圖片放到按鈕上 btn.setIcon(square); btn1.setIcon(square1); btn2.setIcon(square2); btn3.setIcon(square3); btn4.setIcon(square4); btn.setText('開始'); btn1.setText('悔棋'); btn2.setText('認輸'); btn3.setText('人機對戰'); btn4.setText('人人對戰'); this.add(btn); this.add(btn1); this.add(btn2); this.add(btn3); this.add(btn4); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); MyGameListen bn=new MyGameListen(); this.addMouseListener(bn); btn.addActionListener(bn); btn1.addActionListener(bn); btn2.addActionListener(bn); btn3.addActionListener(bn); btn4.addActionListener(bn); Graphics f= this.getGraphics(); AI Ai=new AI(); AI2 Ai2=new AI2(); AIPlus Ai3=new AIPlus(); bn.ai=Ai; bn.ai2=Ai2; bn.ai3=Ai3; bn.f1=f; Ai.f1=f; Ai2.f1=f; Ai3.f1=f; bn.sn=this; Ai.arr2=bn.arr; Ai2.arr2=bn.arr; Ai3.arr=bn.arr; arragain=bn.arr; showtime a=new showtime(); a.count1=bn.count; } int[][] arragain; @Override public void paint(Graphics g) { // TODO Auto-generated method stub super.paint(g); //加背景圖 ImageIcon square5=new ImageIcon(this.getClass().getResource('game.jpeg')); ImageIcon square6=new ImageIcon(this.getClass().getResource('title.jpg')); square5.setImage(square5.getImage().getScaledInstance( 1200,1162,0)); square6.setImage(square6.getImage().getScaledInstance( 366,683,0)); g.drawImage(square5.getImage(),40,60,this); g.drawImage(square6.getImage(),1280,100,366,683,this); for(int i=1;i<=15;i++) { g.drawLine(80, i*80, 1200, i*80); g.drawLine(i*80,80,i*80,1200); } g.drawLine(60,60 , 1220, 60); g.drawLine(60,60 , 60, 1220); g.drawLine(60, 1220, 1220,1220); g.drawLine(1220, 1220, 1220,60); g.fillOval(630, 630, 20, 20); g.fillOval(310, 950, 20, 20); g.fillOval(310, 310, 20, 20); g.fillOval(950, 950, 20, 20); g.fillOval(950, 310, 20, 20); // 繪制棋盤MyGameListen bn1=new MyGameListen(); bn1.f1=g; for(int i=0;i<arragain.length;i++) { for(int j=0;j<arragain.length;j++) { if(arragain[i][j]==1) { Blackchessman(i*80-40,j*80-40,g); } else if(arragain[i][j]==2) { whitechessman(i*80-40,j*80-40,g); } } } } public void Blackchessman(int x,int y,Graphics g) { for(int i=0;i<80;i++) { Color c=new Color(i*3,i*3,i*3); g.setColor(c); g.fillOval(x+i/3, y+i/3, 80-i, 80-i); } } public void whitechessman(int x,int y,Graphics g) { g.setColor(Color.white); g.fillOval(x,y,80,80); }

以下是鼠標監聽器的代碼,這里有部分變量沒有給出,在文章末尾會附上完整代碼

public void mousePressed(MouseEvent e) { x1=e.getX();y1=e.getY(); m=correct(x1); n=correct(y1); if(x1<=1240&&y1<=1240) { if(arr[m/80][n/80]==0) { if(count%2!=0) { x1=e.getX();y1=e.getY(); m=correct(x1); n=correct(y1); Blackchessman(m-40,n-40); arr[m/80][n/80]=1; arr1[m/80][n/80]=count; count++; if( gobangiswin.isWin(arr, m/80, n/80)) { JOptionPane.showMessageDialog(null, '黑棋WIN!!'); } //ai下棋 if(who==2) { ai3.playchess(); arr[ai3.q][ai3.w]=2; arr1[ai3.q][ai3.w]=count; count++; if( gobangiswin.isWin(arr,ai3.q ,ai3.w )) { JOptionPane.showMessageDialog(null, '白棋WIN!!'); } } } else { x1=e.getX();y1=e.getY(); m=correct(x1); n=correct(y1); whitechessman(m-40,n-40); arr[m/80][n/80]=2; arr1[m/80][n/80]=count; count++; if( gobangiswin.isWin(arr, m/80, n/80)) { JOptionPane.showMessageDialog(null, '白棋WIN!!'); } } } else return; } else { return;} }

2、位置修正

這個功能其實有很多種實現的方法,可以根據自己的棋盤位置啥的進行修正。

public int correct(int x) { a=x/80; b=x%80; if(b<=40) { return a*80; } else return (a+1)*80; }

3、輸贏判斷

輸贏判斷的思路,大概是以下思路,通過點擊,下了最后一顆棋子以后,判斷該棋子是否使游戲結束了,就是下完這顆棋子后是否成功構成五子連珠。因為輸贏的判斷你 只需要判斷最后一步即可,因為輸贏的勝負就在最后一步。所以,通過判斷最后一顆棋子的八個方向是否構成五子連珠即可。

以下是判斷輸贏的代碼。

public class GobangIsWin { //判斷輸贏函數 // 橫向 public int left_right(int[][] arr,int x,int y) { int con=1; //向右遍歷 for(int i=x+1;i<arr.length;i++) { if(arr[x][y]==arr[i][y]){ con++; } else break; } //向左遍歷 for(int i=x-1;i>0&&i<arr.length;i--) { if(arr[x][y]==arr[i][y]) { con++; } else break; } return con; } // 縱向 public int high_low(int[][] arr,int x,int y) { int con=1; //向下遍歷 for(int i=y+1;i<arr[0].length;i++) { if(arr[x][y]==arr[x][i]) { con++; } else break; } //向上遍歷 for(int i=y-1;i>0&&i<arr[0].length;i--) { if(arr[x][y]==arr[x][i]) { con++; } else break; } return con; } // 左斜 public int towQudrant_three(int[][] arr,int x,int y) { int con=1; int i=x,j=y; //向右上遍歷 for(int m=i+1,k=j-1;m<arr.length&&k>0&&m<i+5&&k>j-5;k--,m++) { if(x==15||y==1) { break; } else if(arr[x][y]==arr[m][k]) con++; else break; } //向左下遍歷 for(int m=i-1,k=j+1;k<arr.length&&m>0&&k<i+5&&m>j-5;k++,m--) { if(x==1||y==15) { break; } if(arr[x][y]==arr[m][k]) con++; else break; } return con; } // 右斜 public int one_fourwin(int[][] arr,int x,int y) { int con=1; int i=x,j=y; //向左上遍歷 for(int m=i-1,k=j-1;m>0&&k>0&&m>i-5&&k>j-5;k--,m--) { if(x==1||y==1) { break; } if(arr[x][y]==arr[m][k]) con++; else break; } //向右下遍歷 for(int m=i+1,k=j+1;k<arr.length&&m<arr.length&&m<i+5&&k<j+5;k++,m++) { if(x==15||y==15) { break; } if(arr[x][y]==arr[m][k]) con++; else break; } return con; } public boolean isWin(int[][] arr,int x,int y) { if(left_right(arr, x, y)>=5||high_low(arr, x, y)>=5||towQudrant_three(arr, x, y)>=5||one_fourwin(arr, x, y)>=5) { return true; }else { return false; } }}

4、我們再來加一點功能,這里有悔棋,重新開始,認輸的功能。

重新開始:我們清空我們存放棋子的數組即可,然后重新繪制棋盤,將之前的棋盤覆蓋即可。

public void start() { sn.repaint(); for(int i=0;i<arr.length;i++) { for(int j=0;j<arr.length;j++) { arr[i][j]=0; } } count=1; }

悔棋:悔棋的思路:悔棋,我們可以和開始一樣,先把之前的棋盤覆蓋掉,然后去除存放數組里的最后一個棋子即可,然后在新的棋盤上重新放下棋子(除了最后一個棋子)。

public void huiqi() { sn.repaint(); //去除最后一顆棋子 for(int i=0;i<arr1.length;i++) { for(int j=0;j<arr1.length ;j++) { if(arr1[i][j]==count-1) { arr1[i][j]=0; arr[i][j]=0; } if(arr1[i][j]==count-2&&who==2) { arr1[i][j]=0; arr[i][j]=0; } } } //重放棋子 for(int i=0;i<arr.length;i++) { for(int j=0;j<arr.length ;j++) { if(arr[i][j]==1) { Blackchessman(i*80-40,j*80-40); } else if(arr[i][j]==2) { whitechessman(i*80-40,j*80-40); } } } //控制下一顆棋子顏色 if(who==2) { count=count-2; } else if(who==1) { count=count-1; } }

認輸功能:這個很簡單就不說了,判斷一下到誰下點擊了認輸就誰輸就好。

5、最后來一個高級的,實現AI的功能,人機對戰。

這里有很多種實現人工智能的方法:

(1)權值法(2)博弈樹(3)機器學習

博主現在水平有限,只會權值算法,等博主學會后面兩種方法再來加~

權值法:這里用到了權值表,創建一個新的二維數組chessvalue[][]用于存放該點的權值。

HashMap<String,Integer> map = new HashMap<String,Integer>();map.put('1',10);map.put('11',100);map.put('111',1000);map.put('1111',10000);

這里的HashMap類是一種特殊的類,可以通過map.get(),將字符串放進get方法中,通過比較map中的所有字符串,找到與之相對應的權值,并返回這個值,這里指的注意的是,這里返回的數據類型不是int型,而是Integer型,但是不必擔心,這個類型也能實現累加。

接下來是查找棋型,通過查找該位置的八個方向的棋型,并對八個方向的權值進行累加。最后通過找出最大的權值的位置,將棋子下到這個位置就好,這樣就基本實現AI功能了。

保存棋局的方法:通過String類型的拼接功能實現棋局的保存。

注:在寫這部分AI的時候,對于部分棋型沒有考慮到,難度水平大概處于低階至中階,對于部分難以通過遍歷八個方向進行查找的,采用了聯合算法。例如,對于“22022”這樣的棋型,顯然需要通過左右兩邊的棋型綜合考慮,這里采用了聯合算法,遍歷完左右(上下)后進行一次聯合判斷。

AI代碼

public class AIPlus { int arr[][]=null; int weightArray[][]=new int [16][16]; Graphics f1=null; //棋子相連情況的劃分 HashMap<String,Integer> map = new HashMap<String,Integer>();//設置不同落子情況和相應權值的數組 public AIPlus() { //被堵住 map.put('01', 17);//眠1連 map.put('02', 12);//眠1連 map.put('001', 17);//眠1連 map.put('002', 12);//眠1連 map.put('0001', 17);//眠1連 map.put('0002', 12);//眠1連 map.put('0102',17);//眠1連,15 map.put('0201',12);//眠1連,10 map.put('0012',15);//眠1連,15 map.put('0021',10);//眠1連,10 map.put('01002',19);//眠1連,15 map.put('02001',14);//眠1連,10 map.put('00102',17);//眠1連,15 map.put('00201',12);//眠1連,10 map.put('00012',15);//眠1連,15 map.put('00021',10);//眠1連,10 map.put('01000',21);//活1連,15 map.put('02000',16);//活1連,10 map.put('00100',19);//活1連,15 map.put('00200',14);//活1連,10 map.put('00010',17);//活1連,15 map.put('00020',12);//活1連,10 map.put('00001',15);//活1連,15 map.put('00002',10);//活1連,10 //被堵住 map.put('0101',65);//眠2連,40 map.put('0202',60);//眠2連,30 map.put('0110',65);//眠2連,40 map.put('0220',60);//眠2連,30 map.put('011',65);//眠2連,40 map.put('022',60);//眠2連,30 map.put('0011',65);//眠2連,40 map.put('0022',60);//眠2連,30 map.put('01012',65);//眠2連,40 map.put('02021',60);//眠2連,30 map.put('01102',65);//眠2連,40 map.put('02201',60);//眠2連,30 map.put('00112',65);//眠2連,40 map.put('00221',60);//眠2連,30 map.put('01010',75);//活2連,40 map.put('02020',70);//活2連,30 map.put('01100',75);//活2連,40 map.put('02200',70);//活2連,30 map.put('00110',75);//活2連,40 map.put('00220',70);//活2連,30 map.put('00011',75);//活2連,40 map.put('00022',70);//活2連,30 //被堵住 map.put('0111',1500);//眠3連,100 map.put('0222',1400);//眠3連,80 map.put('01112',1500);//眠3連,100 map.put('02221',1400);//眠3連,80 map.put('01101',10000);//活3連,130 map.put('02202',8000);//活3連,110 map.put('01011',10000);//活3連,130 map.put('02022',8000);//活3連,110 map.put('01110', 10000);//活3連 map.put('02220', 8000);//活3連 map.put('01111',300000);//4連,300 map.put('02222',350000);//4連,280 } public void printArray(int[][] arr) { for(int i=1;i<arr.length;i++) { for(int j=1;j<arr.length ;j++) { System.out.print(arr[i][j]+' '); } System.out.println(); } } public Integer unionWeight(Integer a,Integer b ) { //必須要先判斷a,b兩個數值是不是null if((a==null)||(b==null)) return 0; //一一 else if((a>=10)&&(a<=25)&&(b>=10)&&(b<=25)) return 60; //一二、二一 else if(((a>=10)&&(a<=25)&&(b>=60)&&(b<=80))||((a>=60)&&(a<=80)&&(b>=10)&&(b<=25))) return 800; //一三、三一、二二 else if(((a>=10)&&(a<=25)&&(b>=140)&&(b<=1000))||((a>=140)&&(a<=1000)&&(b>=10)&&(b<=25))||((a>=60)&&(a<=80)&&(b>=60)&&(b<=80))) return 300000; //二三、三二 else if(((a>=60)&&(a<=80)&&(b>=140)&&(b<=1000))||((a>=140)&&(a<=1000)&&(b>=60)&&(b<=80))) return 300000; else return 0; } public void getvalue() { for(int i=0;i<arr.length;i++) { for(int j=0;j<arr[i].length;j++) { //首先判斷當前位置是否為空 if(arr[i][j]==0) { //往左延伸 String ConnectType='0'; int jmin=Math.max(0, j-4); for(int positionj=j-1;positionj>=jmin;positionj--) {//依次加上前面的棋子ConnectType=ConnectType+arr[i][positionj]; } //從數組中取出相應的權值,加到權值數組的當前位置中 Integer valueleft=map.get(ConnectType); if(valueleft!=null) weightArray[i][j]+=valueleft; //往右延伸 ConnectType='0'; int jmax=Math.min(14, j+4); for(int positionj=j+1;positionj<=jmax;positionj++) {//依次加上前面的棋子ConnectType=ConnectType+arr[i][positionj]; } //從數組中取出相應的權值,加到權值數組的當前位置中 Integer valueright=map.get(ConnectType); if(valueright!=null) weightArray[i][j]+=valueright; //聯合判斷,判斷行 weightArray[i][j]+=unionWeight(valueleft,valueright); //往上延伸 ConnectType='0'; int imin=Math.max(0, i-4); for(int positioni=i-1;positioni>=imin;positioni--) {//依次加上前面的棋子ConnectType=ConnectType+arr[positioni][j]; } //從數組中取出相應的權值,加到權值數組的當前位置中 Integer valueup=map.get(ConnectType); if(valueup!=null) weightArray[i][j]+=valueup; //往下延伸 ConnectType='0'; int imax=Math.min(14, i+4); for(int positioni=i+1;positioni<=imax;positioni++) {//依次加上前面的棋子ConnectType=ConnectType+arr[positioni][j]; } //從數組中取出相應的權值,加到權值數組的當前位置中 Integer valuedown=map.get(ConnectType); if(valuedown!=null) weightArray[i][j]+=valuedown; //聯合判斷,判斷列 weightArray[i][j]+=unionWeight(valueup,valuedown); //往左上方延伸,i,j,都減去相同的數 ConnectType='0'; for(int position=-1;position>=-4;position--) {if((i+position>=0)&&(i+position<=14)&&(j+position>=0)&&(j+position<=14))ConnectType=ConnectType+arr[i+position][j+position]; } //從數組中取出相應的權值,加到權值數組的當前位置 Integer valueLeftUp=map.get(ConnectType); if(valueLeftUp!=null) weightArray[i][j]+=valueLeftUp; //往右下方延伸,i,j,都加上相同的數 ConnectType='0'; for(int position=1;position<=4;position++) {if((i+position>=0)&&(i+position<=14)&&(j+position>=0)&&(j+position<=14))ConnectType=ConnectType+arr[i+position][j+position]; } //從數組中取出相應的權值,加到權值數組的當前位置 Integer valueRightDown=map.get(ConnectType); if(valueRightDown!=null) weightArray[i][j]+=valueRightDown; //聯合判斷,判斷行 weightArray[i][j]+=unionWeight(valueLeftUp,valueRightDown); //往左下方延伸,i加,j減 ConnectType='0'; for(int position=1;position<=4;position++) {if((i+position>=0)&&(i+position<=14)&&(j-position>=0)&&(j-position<=14))ConnectType=ConnectType+arr[i+position][j-position]; } //從數組中取出相應的權值,加到權值數組的當前位置 Integer valueLeftDown=map.get(ConnectType); if(valueLeftDown!=null) weightArray[i][j]+=valueLeftDown; //往右上方延伸,i減,j加 ConnectType='0'; for(int position=1;position<=4;position++) {if((i-position>=0)&&(i-position<=14)&&(j+position>=0)&&(j+position<=14))ConnectType=ConnectType+arr[i-position][j+position]; } //從數組中取出相應的權值,加到權值數組的當前位置 Integer valueRightUp=map.get(ConnectType); if(valueRightUp!=null) weightArray[i][j]+=valueRightUp; //聯合判斷,判斷行 weightArray[i][j]+=unionWeight(valueLeftDown,valueRightUp); } } } } int q=0,w=0; public void playchess() { getvalue(); //取出最大的權值 int weightmax=0; for(int i=0;i<arr.length;i++) { for(int j=0;j<arr.length;j++) { if(weightmax<weightArray[i][j]) {weightmax=weightArray[i][j];q=i;w=j; } } } whitechessman(q*80-40, w*80-40); for(int i=0;i<weightArray.length;i++) { for(int j=0;j<weightArray.length;j++) { weightArray[i][j]=0; } } } public void whitechessman(int x,int y) { f1.setColor(Color.white); f1.fillOval(x,y,80,80); }}三、總結

本次是第一次做游戲類的項目,仍然存在許多不足,但是很開心最后成功了,然后最后AI部分的權值表以及聯合算法借鑒了其他博主的思路,如有侵權,請聯系我刪除。后期我會再加上博弈樹算法的思想。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 欧美日韩国产在线观看一区二区三区 | 日韩一级欧美一级在线观看 | 女人野外小树林一级毛片 | 毛片在线全部免费观看 | 日本vs欧美一区二区三区 | 久久免费黄色 | 日韩一区二区在线观看 | 92手机看片福利永久国产 | 亚洲特级黄色片 | 午夜欧美日韩在线视频播放 | 日韩伦理一区二区三区 | 狠色狠狠色狠狠狠色综合久久 | 国产91无套剧情在线播放 | 免费a级毛片网站 | 日本亚洲欧美高清专区vr专区 | 亚洲精品在线视频 | 午夜免费成人 | 黄色一级片a | 最近最新中文字幕免费的一页 | 日韩毛片免费在线观看 | 刺激免费视频 | 成人久久网 | 亚洲国产一区在线 | 亚洲系列在线 | 亚洲国产午夜看片 | 久久久国产免费影院 | 深夜在线观看大尺度 | 日本亚洲综合 | 亚洲成人在线视频播放 | 泷泽萝拉亚洲精品中文字幕 | 男人的天堂中文字幕 | 欧美1区二区三区公司 | 好吊色37pao在线观看 | 免费观看欧美精品成人毛片 | 免费在线观看毛片 | 亚洲免费视频在线观看 | 真实国产乱子伦高清 | 久久久久久久国产a∨ | 午夜欧美成人久久久久久 | 国产在线播放一区 | 亚洲一区二区三区不卡在线播放 |