国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java五子棋項目

coordinate35 / 3133人閱讀

摘要:由于二維數組中代表黑棋,代表白棋,,的數字集合即可代表棋盤上的棋子情況,可以對整個棋盤數組進行遍歷,得到每一個可以下的位置的八個方向的棋子情況。

java基本入門之后,迎來第一個挑戰——五子棋設計

寒假的時候,靠著看java手冊,實現了雙人對戰并判斷輸贏的功能。但是一直卡在了人機對戰上面。

之后隨著學習的深入,終于實現。

以下詳細的敘述一下整體的設計過程:

首先是五子棋窗口界面的設計,畫窗體,加按鈕,這些都比較基礎,主要是要重寫重繪的方法,否則每次改變窗體都會使其變化。

package wuziqi;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class FiveChessUI extends JPanel implements Config {
    /**
     *五子棋界面
     */
    private static final long serialVersionUID = 1L;
    private static int[][] chesses=new int[ROWS][COLUMNS];
    
    public static void main(String[] args) {
        FiveChessUI fcUI = new FiveChessUI();
        fcUI.initUI();
    }
    public void initUI () {
        JFrame jf = new JFrame();
        jf.setTitle("五子棋v0.5 by xzw");
        jf.setSize(700,650);
        jf.setLocationRelativeTo(null);
        
        jf.add(this,BorderLayout.CENTER);
        this.setBackground(Color.ORANGE);
        
        jf.setDefaultCloseOperation(3);
        this.setLayout(new FlowLayout());
        
        JPanel jp2 = new JPanel();
        jp2.setPreferredSize(new Dimension(100, 0));
        jp2.setBackground(Color.CYAN);
        
//        JButton jbuStart = new JButton("開始");
//        jbuStart.setPreferredSize(new Dimension(70, 70));
        
        JButton jbuReg = new JButton("悔棋");
        jbuReg.setPreferredSize(new Dimension(70, 50));
        
        JButton jbuR = new JButton("重來");
        jbuR.setPreferredSize(new Dimension(70, 50));
        
        JButton jbup2p = new JButton("雙人");
        jbup2p.setPreferredSize(new Dimension(70, 70));
        
        JButton jbup2c = new JButton("人機");
        jbup2c.setPreferredSize(new Dimension(70, 70));
        
        JLabel la2 = new JLabel("當前執子:black");

        jp2.add(jbup2p);
        jp2.add(jbup2c);
        jp2.add(jbuReg);
        jp2.add(jbuR);
        
        jp2.add(la2);
        
        jf.add(jp2,BorderLayout.EAST);

        jf.setVisible(true);
        
        Graphics g = this.getGraphics();
        
        ChessListener e = new ChessListener(g,chesses,this);
        jbup2p.addActionListener(e);
        jbup2c.addActionListener(e);
        jbuReg.addActionListener(e);
        jbuR.addActionListener(e);
    
    }
    /**
     * 重寫重繪方法
     */
    public void paint(Graphics g){
        //調用父類的重繪窗體
        super.paint(g);
        //重繪窗體的同時繪制棋盤和棋子
        drawChessTable(g);
        drawChesses(g);
    }
    //畫棋盤
    public void drawChessTable (Graphics g){
        g.setColor(Color.BLACK);
        for (int i=0;i

其次是界面鼠標監聽器的設計,窗體被分為2個界面,左邊的界面作為棋盤,右邊的界面用作放按鈕,模式,悔棋,重來等按鈕都放在上面。

在做這里的時候意識到自己還不會傳參,因此要在不同類里對同一個對象進行修改就會很困難。于是我向請教學會了傳參的方法,即構造函數傳參法。在一個類的構造函數的參數里添加需要傳遞的參數,并聲明this.var=var(var即為參數)然后在另一個類里調用這個類的方法時,聲明對象時加入要傳的參數,即實現了參數傳遞。

通過繼承mouseAdapter類,重寫該類的mouseReleased的方法,實現鼠標點擊后畫一個棋子。(重寫方法時要求名稱相同,參數相同,返回值相同)同時,要想做到在鼠標點擊的附近的交叉點上畫棋子,需要先計算出鼠標點擊處的行列坐標。

定義一與棋盤相同大小的二維數組,用來存放棋子,每在一個交叉點下一顆棋子,就在數組相應位置將其置為1或2,便于之后的判斷輸贏以及人機算法的實現。另加一個變量判斷所下棋子的黑白。

public ChessListener(Graphics g, int[][] chesses,JPanel jp) {
        this.g = g;
        this.chesses = chesses;
        this.jp=jp;
        a = new Check(chesses);
    }
    int flag=0;
    int r=0,c=0;
    public void mouseReleased(MouseEvent e) {
        // 得到鼠標事件發生的時候光標的位置

        int x = e.getX();
        int y = e.getY();

        r = (x - X0 + CHESS_SIZE / 2) / CHESS_SIZE;
        c = (y - Y0 + CHESS_SIZE / 2) / CHESS_SIZE;

        if (chesses[r][c] == 0) {
            if (count == 0) {
                chesses[r][c] = 1;
                g.setColor(Color.BLACK);
                g.fillOval(X0 + r * CHESS_SIZE - CHESS_SIZE / 2, Y0 + c * CHESS_SIZE - CHESS_SIZE / 2,
                        CHESS_SIZE, CHESS_SIZE);
                count++;
            } else if (count == 1) {
                chesses[r][c] = 2;
                g.setColor(Color.WHITE);
                g.fillOval(X0 + r * CHESS_SIZE - CHESS_SIZE / 2, Y0 + c * CHESS_SIZE - CHESS_SIZE / 2,
                        CHESS_SIZE, CHESS_SIZE);
                count--;
            }                
        }
        if (a.validateChess(r, c)) {
            if (count == 0) {
                JOptionPane.showMessageDialog(null, "WhiteWin");
                jp.removeMouseListener(this);
                
            } else {
                JOptionPane.showMessageDialog(null, "BlackWin");
                jp.removeMouseListener(this);
            }
        }
    }

然后就是五子棋判斷輸贏的方法了。原理很簡單,只要對每次下的子的四個方向判斷是否有5個子連在一起即可。只要中間有一個顏色不同,立即break。

幾天后發現,這里的判斷輸贏的方法有些不合理,斜向的判斷方法有問題。有時會出現斜向4個棋子就被判贏了,經過
觀察發現,斜向的兩個方向我把合在了一起。所以就會出現4+1=5,判斷贏的情況。
改進后代碼如下:

package wuziqi;

public class Check {
    private int[][] chesses;
    public Check(int[][] chesses) {
        this.chesses = chesses;
    }
    public boolean validateChess(int x, int y) {
        boolean state = false;
        if (checkRow(x, y) == 5||checkColumn(x,y)==5||checkDiagonal1(x,y)==5||checkDiagonal2(x,y)==5)
            state = true;
//        System.out.print(chesses.length);
        return state;
    }
    
    public int checkRow(int x,int y) {
        int count=0;
        for (int i=x+1;i=0;i--) {//go left
            if (chesses[i][y]==chesses[x][y]) {
                count++;
            }
            else
                break;
        }
        return count;
    }
    public int checkColumn(int x,int y) {
        int count=0;
        for (int i=y+1;i=0;i--) {//go up
            if (chesses[x][i]==chesses[x][y]) {
                count++;
            }
            else
                break;
        }
        return count;
    }
    public int checkDiagonal1(int x,int y) {
        int count=1;
for(inti=1;x+i=0&&y-i>=0;i++) {//go left up
            if (chesses[x-i][y-i]==chesses[x][y]) {
                count++;
            }
            else
                break;
        }
        return count;
    }
    public int checkDiagonal2(int x,int y) {
        int count=1;
        for (int i=1;x+i=0;i++) {//go right up
            if (chesses[x+i][y-i]==chesses[x][y]) {
                count++;
            }
             else
                break;
        }
        for (int i=1;x-i>=0&&y+i

接下來,就是花費我時間最長的人機算法了。首先要讓電腦實現下棋,而且是在相對正常的位置落子,即要通過判斷棋盤上棋子的形勢。由于二維數組中1代表黑棋,2代表白棋,1,2的數字集合即可代表棋盤上的棋子情況,可以對整個棋盤數組進行遍歷,得到每一個可以下的位置的八個方向的棋子情況。因此可以讓每一種情況對應一種權值,權值越大,說明該位置越危險,最后只需找到權值最大的那個位置,落子,即可。

string來代表棋子情況,數組存權值,建立一個同時存string和int的的hashmap。并預存好每個情況對應的權值。

權值修改:(使電腦更智能)

public ChessAI(int chesses[][], int chessValue[][]) {
        this.chesses = chesses;
        this.chessValue = chessValue;
        //black
        hm.put("1", 11);
        hm.put("11", 110);
        hm.put("111", 1200);
        hm.put("1111", 11000);
        
        hm.put("12", 11);
        hm.put("112", 110);
        hm.put("1112", 1100);
        hm.put("11112", 11000);
        
        hm.put("21", 11);
        hm.put("211", 110);
        hm.put("2111", 1100);
        hm.put("21111", 11000);
        
        //white
        hm.put("2", 10);
        hm.put("22", 100);
        hm.put("222", 1100);
        hm.put("2222", 10000);
        
        hm.put("221", 100);
        hm.put("2221", 1000);
        hm.put("22221", 10000);
        hm.put("122", 100);
        hm.put("1222", 1000);
        hm.put("12222", 10000);
    }
``
每個位置,八個方向遍歷,存入權值數組。
public void AI() {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLUMNS; j++) {
                if (chesses[i][j] == 0) {
                    String code = "";
                    color = 0;
                    // 向東
                    for (int k = i + 1; k < ROWS; k++) {
                        if (chesses[k][j] == 0) {// 為空跳出循環
                            break;
                        } else {
                            if (color == 0) {// 用color記住開始的地方棋子的顏色
                                color = chesses[k][j];
                                code += chesses[k][j];
                            } else if (chesses[k][j] == color) {// 顏色相同
                                code += chesses[k][j];
                            } else {// 顏色不同
                                code += chesses[k][j];
                                break;
                            }
                        }
                    }
//                     System.out.print(code);
                    Integer value = hm.get(code);
                    if (value != null) {
                        chessValue[i][j] += value;
                    }
                    // 向西
                    code = "";
                    color = 0
// south-east
                    code = "";
                    color = 0;
                    for (int p = 1; i + p < ROWS && j + p < COLUMNS; p++) {
                        if (chesses[i + p][j + p] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 開始的地方棋子的顏色
                                color = chesses[i + p][j + p];
                                code += chesses[i + p][j + p];
                            } else if (chesses[i + p][j + p] == color) {
                                code += chesses[i + p][j + p];
                            } else {
                                code += chesses[i + p][j + p];
                                break;
                            }
                        }

                    }
                    value = hm.get(code);
                    if (value != null) {
                        chessValue[i][j] += value;
                    }

以及接下來ai監聽器的設計,先由玩家自己下黑子之后,判斷輸贏。再調用ai算法,獲取權值最大的點,然后在該點畫白子,下完之后立即清空權值數組。以便于下次下子時,重新統計。

public void mouseReleased(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();

        r = (x - X0 + CHESS_SIZE / 2) / CHESS_SIZE;
        c = (y - Y0 + CHESS_SIZE / 2) / CHESS_SIZE;
        if (chesses[r][c] == 0 && count == 0) {
            chesses[r][c] = 1;
            g.setColor(Color.BLACK);
            g.fillOval(X0 + r * CHESS_SIZE - CHESS_SIZE / 2, Y0 + c * CHESS_SIZE - CHESS_SIZE / 2, CHESS_SIZE,
                    CHESS_SIZE);
            count++;
        }
        if (a.validateChess(r, c)) {
            JOptionPane.showMessageDialog(null, "BlackWin");
            jp.removeMouseListener(this);
        }
        else {
        ai.AI();
        r1 = ai.getr(chessValue);
        c1 = ai.getc(chessValue);

        if (chesses[r1][c1] == 0 && count == 1) {
            chesses[r1][c1] = 2;
            g.setColor(Color.WHITE);
            g.fillOval(X0 + r1 * CHESS_SIZE - CHESS_SIZE / 2, Y0 + c1 * CHESS_SIZE - CHESS_SIZE / 2, CHESS_SIZE,
                    CHESS_SIZE);

            count--;
        }
        if (a.validateChess(r1, c1)) {
            JOptionPane.showMessageDialog(null, "WhiteWin");
            jp.removeMouseListener(this);
        }
        }
        // 電腦下完后清空
        for (int i1 = 0; i1 < ROWS; i1++) {
            for (int j1 = 0; j1 < COLUMNS; j1++) {
                chessValue[i1][j1] = 0;
            }
        }
    }


至此,五子棋項目設計完成。但實際下的結果電腦有時候下的子還是不太科學,希望之后還能改善讓難度更高些。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70313.html

相關文章

  • 練習項目備選清單

    摘要:練習項目備選清單文件下載器功能概要設計實現新建下載功能以為基礎給出下載鏈接可以啟動下載任務實現局域網內下載傳輸文件以單線程下載方式實現附加功能支持斷點續傳實現多線程下載實現下載參考技術套接字編程多線程編程音視頻播放器功能概要設計實現播放常見 練習項目備選清單 Utilities 1. 文件下載器 功能概要設計: 實現新建下載功能(以ftp為基礎) 給出下載鏈接可以啟動下載任務 實現局...

    guyan0319 評論0 收藏0
  • 練習項目備選清單

    摘要:練習項目備選清單文件下載器功能概要設計實現新建下載功能以為基礎給出下載鏈接可以啟動下載任務實現局域網內下載傳輸文件以單線程下載方式實現附加功能支持斷點續傳實現多線程下載實現下載參考技術套接字編程多線程編程音視頻播放器功能概要設計實現播放常見 練習項目備選清單 Utilities 1. 文件下載器 功能概要設計: 實現新建下載功能(以ftp為基礎) 給出下載鏈接可以啟動下載任務 實現局...

    peixn 評論0 收藏0
  • BetaMeow----利用機器學習做子棋AI

    摘要:簡言之,機器學習是內功,而數據挖掘則是機器學習的一種用途。但本質上是我在學習機器學習方面的實戰項目,所以我想辦法利用機器學習的方面的算法實現。 BetaMeow的起源 前段時間AlphaGo和李世石廣受關注,作為人工智能的腦殘粉,看完比賽后激動不已,因為有一定的機器學習的基礎,便打算擼一個棋類的AI,但我還算有點自知之明,圍棋AI,甚至google打算做得通用AI是做不出的了,所以打算...

    bingchen 評論0 收藏0
  • React 官網示例實現 + 子棋 + 簡單文章發表 demo

    摘要:五子棋游戲博客官網示例實現源碼之前一直在用,前幾天看了下的官方文檔,寫了個加強對的理解,歡迎指正。五子棋游戲該模塊實現了五子棋和井字游戲兩個游戲。五子棋游戲只記錄了最近步的數據,步以前的數據不會記錄,故悔棋只可悔步以內的棋。 五子棋游戲 + 博客 demo + React官網示例實現 github 源碼:https://github.com/moshang-xc/react-demo ...

    Astrian 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<