Rumah  >  Artikel  >  Java  >  Bagaimana untuk melaksanakan permainan catur Cina menggunakan Java

Bagaimana untuk melaksanakan permainan catur Cina menggunakan Java

PHPz
PHPzke hadapan
2023-05-12 18:58:041387semak imbas

1. Antara Muka

Papan catur untuk bermain catur mesti disediakan terlebih dahulu Ini ialah antara muka dengan saiz, perkadaran dan lokasi yang betul, dan kemudian lukiskannya pada borang (ya, drawLine) n garisan lurus. dan garis miring, nilai khusus ditetapkan mengikut saiz antara muka anda. Antara muka yang dilukis dengan cara ini adalah kemas dan cantik~

public void paint(Graphics g){
        
        super.paint(g);//重写画图函数
        Font f=new Font("微软雅黑",Font.BOLD,30);
        g.setFont(f);
        
        g.drawRect(60, 50, 500, 560);//外圈
        g.drawRect(70, 60, 480, 540);//内圈
        //横线部分
        int length=60;
        for(int i=0;i<9;i++){
            g.drawLine(70, length, 550, length);
            length+=60;
        }
        //中间汉字
        g.drawString("楚河", 160, 340);
        g.drawString("汉界", 400, 340);
        //竖线部分
        length=130;
        for(int i=0;i<7;i++){
            //上半部分竖线
            g.drawLine( length,60, length,300);
            //下半部分竖线
            g.drawLine( length,360, length,600);
            length+=60;
        }
        //上半部分九宫格斜线
        g.drawLine(250, 60, 370, 180);
         g.drawLine(370, 60, 250, 180);
         //下半部分九宫格斜线
         g.drawLine(250, 480, 370, 600);
         g.drawLine(250, 600, 370, 480);
     
    }

2 Butang

Selepas melukis papan catur, tambahkan butang fungsi pada masa ini tidak dianggap untuk dilaksanakan untuk masa ini sedang. Anda boleh menambahnya sesuka hati mengikut keutamaan anda. Adalah disyorkan di sini untuk menetapkan jenis butang kepada tatasusunan untuk memudahkan penambahan dan pemadaman tepat pada masanya.

//添加到面板上
        String[] type = {"开始游戏","重新开始","认 输","悔 棋"};
        for(int i=0;i<type.length;i++){
            Button btn = new Button(type[i]);
            btn.setPreferredSize(new Dimension(150,50));
            anniu.add(btn);
        }

Bagaimana untuk melaksanakan permainan catur Cina menggunakan Java

Pada masa ini anda akan mendapati bahawa butang itu sangat padat Penyelesaian saya ialah menambah panel lain pada panel ini dan menetapkannya kepada putih bergerak ke bawah mengikut susun atur bendalir panel Melaraskan lebar panel kosong boleh menukar kedudukan butang.

3. Tambah buah catur

Tambahkan gambar buah catur yang ditemui pada kedudukan persimpangan papan catur untuk menyuntik jiwa ke dalam papan catur tersebut boleh Jalankan pada komputer lain (format png disyorkan di sini, format jpg akan mempunyai sempadan segi empat sama).
Tiga langkah seterusnya ialah

1 Cipta tatasusunan integer dengan 10 baris dan 9 lajur untuk menyimpan data di setiap lokasi
2 Buat tatasusunan Imej dengan panjang 14 untuk sepadan dengan jenis buah catur; 🎜>

Sesuaikan Imej dengan gambar buah catur:

//初始化给每个chess定义
        for(int k=0; k<14; k++){
            chess[k] = new ImageIcon(this.getClass().getResource((k+1)+".png")).getImage();
        }
Bagaimana untuk melaksanakan permainan catur Cina menggunakan Java Lintas lukisan:

//根据棋盘布局
        for(int i=0;i<place.length;i++){
            for(int j=0;j<place[0].length;j++){
                if(place[i][j] >0){
                    bg.drawImage(chess[place[i][j]-1], chessX+60*j, chessY+60*i, 50, 50, null); 
                }
            }
        }

4. Realisasikan pergerakan buah catur

Dapatkan seretan tetikus melalui fungsi Gerakkan kedudukan pada papan catur yang diwakili oleh dua mata sebelum dan selepas, tukar nilai tatasusunan dua dimensi kedua-dua kedudukan ini, dan kemudian lukis semula untuk merealisasikan pergerakan buah catur.

int x1, y1, x2, y2;
public void mousePressed(MouseEvent e) {
        
            x1 = e.getX();
            y1 = e.getY();
            x1 = getj(x1);
            y1 = geti(y1);
    }
    public void mouseReleased(MouseEvent e) {
        
            x2 = e.getX();
            y2 = e.getY();
            x2 = getj(x2);
            y2 = geti(y2);
    }
    //根据点的坐标得到其代表的位置,具体参数可以微调,我的格子是60x60大小
    public int getj(int x){
        return (x-50)/60;
    }
    public int geti(int y){
        return (y-40)/60;
    }

Situasi yang anda hadapi pada masa ini ialah setiap kali anda bergerak, keseluruhan antara muka akan dilukis semula, dan gambar dilukis terus pada borang, dan data akan dihantar terus ke perkakasan komputer. Dengan cara ini Kelajuan lukisan adalah perlahan, jadi antara muka akan berkelip setiap kali anda mengambil langkah Dalam kes ini, kami boleh menyimpan gambar dalam cache dan melukisnya secara langsung tanpa melalui perkakasan, jadi kecekapan boleh menjadi ketara. bertambah baik.

BufferedImage buffer = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics bg = buffer.getGraphics();

//这个中间写的是你画界面的方法,也就是上面提到的paint方法内部
//......

//绘制缓存到窗体上
g.drawImage(buffer, 0, 0, null);

5. Tentukan keputusan

Pasukan yang mendahului untuk mengalahkan jeneral atau komander lawan menang pada masa yang sama, mulakan data kepada 0 dan bersedia untuk pusingan lain:

(kaedah showMessageDialog boleh melompat keluar dari kotak secara langsung)

//判断游戏结束并显示胜局
public void isWine() {
        
        System.out.println(place[y1][x1]+" "+place[y2][x2]);
        if (place[y2][x2]==7&&place[y1][x1]!=0) {
            place[y2][x2] = place[y1][x1];
            place[y1][x1] = 0;
            UI.repaint();
            JOptionPane.showMessageDialog(null, "黑方  胜利!");
            again();
        } else if(place[y2][x2]==14&&place[y1][x1]!=0) {
            place[y2][x2] = place[y1][x1];
            place[y1][x1] = 0;
            UI.repaint();
            JOptionPane.showMessageDialog(null, "红方  胜利!");
            again();
        }
    }
    //游戏结束时要重绘
    public void again(){
          for(int i=0; i<place.length; i++){
              
              for(int j=0; j<place[0].length; j++){
                  
                  place[i][j] = 0;
              }
         }
    }

6.


Tambah pendengar tindakan

public void actionPerformed(ActionEvent e) {
        
        type = e.getActionCommand();
        if("开始游戏".equals(type)||"重新开始".equals(type)){
            x=0;
            count = 1;//这里要把每次的走棋方刷新,认输时也需要刷新
            init();
            UI.repaint();
        }
    }
    //初始化place坐标
    public void init(){

        /*红兵 1.png
         *红炮 2.png
         *红車 3.png
         *红马 4.png
         *红相 5.png
         *红仕 6.png
         *红帥 7.png
         *黑卒 8.png
         *黑炮 9.png
         *黑車 10.png
         *黑马 11.png
         *黑象 12.png
         *黑士 13.png
         *黑将 14.png
         */
        
            
        for(int i=0;i<place.length;i++){
                
            for(int j=0;j<place[0].length;j++){
                            
                place[i][j] = 0;
            }
        }
            place[0][0] = 10;    place[9][0] = 3;
            place[0][1] = 11;    place[9][1] = 4;
            place[0][2] = 12;    place[9][2] = 5;
            place[0][3] = 13;    place[9][3] = 6;
            place[0][4] = 14;    place[9][4] = 7;
            place[0][5] = 13;    place[9][5] = 6;
            place[0][6] = 12;    place[9][6] = 5;
            place[0][7] = 11;    place[9][7] = 4;
            place[0][8] = 10;    place[9][8] = 3;
            place[2][1] = 9;    place[7][1] = 2;
            place[2][7] = 9;    place[7][7] = 2;
            place[3][0] = 8;    place[6][0] = 1;
            place[3][2] = 8;    place[6][2] = 1;
            place[3][4] = 8;    place[6][4] = 1;
            place[3][6] = 8;    place[6][6] = 1;
            place[3][8] = 8;    place[6][8] = 1;
            
    }

Fungsi init di sini adalah untuk memulakan tatasusunan dua dimensi integer kepada keadaan di mana buah catur boleh ditambah selepas melintasi permainan.

7. Menambah peraturan

//规定各个棋子的移动规则
public boolean rule(int gi, int gj,int si, int sj){
        int x = place[gi][gj];
        int y = place[si][sj];
        int start, end;
        
        //判断为何种棋子
        //車:只能走直线
        if(x == 3||x == 10){
            
            if(gi != si&&gj != sj)    return false;
            else if(gi == si){
                start = Math.min(gj, sj);
                end = Math.max(gj, sj);
                for(int m = 1; m < end - start; m++){
                    if(place[gi][start+m] != 0)    return false;
                }
                return true;
            }
            else if(gj == sj){
                start = Math.min(gi, si);
                end = Math.max(gi, si);
                for(int m = 1; m < end - start; m++){
                    if(place[start+m][gj] != 0)    return false;
                }
                return true; 
            }
            else return true;
        }
        //马:走日,且某个位置不可以有棋子
        else if(x == 4||x == 11){
            //下
            if(si - gi == 2&&Math.abs(gj-sj) == 1&&place[gi+1][gj] == 0)    return true;
            //上
            else if(gi - si == 2&&Math.abs(gj-sj) == 1&&place[gi-1][gj] == 0)    return true;
            //右
            else if(sj - gj == 2&&Math.abs(gi-si) == 1&&place[gi][gj+1] == 0)    return true;
            //左
            else if(gj - sj == 2&&Math.abs(gi-si) == 1&&place[gi][gj-1] == 0)    return true;
            //否则不可以走
            else return false;
        }
        //相:走田,且不能过河
        else if(x == 5||x == 12){
            //左上
            if(gi - si == 2&&gj - sj == 2&&place[gi-1][gj-1] == 0){
                
                if((x == 5&&si >= 5)||(x == 12&&si < 5))    return true;
                else return false;
            }
            //右上
            else if(gi - si == 2&&sj - gj == 2&&place[gi-1][gj+1] == 0){
                
                if((x == 5&&si >= 5)||(x == 12&&si < 5))    return true;
                else return false;
            }
            //左下
            else if(si - gi == 2&&gj - sj == 2&&place[gi+1][gj-1] == 0){
                
                if((x == 5&&si >= 5)||(x == 12&&si < 5))    return true;
                else return false;
            }
            //右下
            else if(si - gi == 2&&sj - gj == 2&&place[gi+1][gj+1] == 0){
                
                if((x == 5&&si >= 5)||(x == 12&&si < 5))    return true;
                else return false;
            }
            else return false;
        }
        //士:斜着走不能出田字格
        else if(x == 6||x == 13){
            
            if(Math.abs(gj-sj)==1&&Math.abs(gi-si)==1){
                
                if(x == 6&&si >= 7&&sj >= 3&&sj <= 5)    return true;
                else if(x == 13&&si <= 2&&sj >= 3&&sj <= 5)    return true;
                else return false;
            }
            else return false;
        }
        //将:不能出田字格且不能会面
        else if(x == 7||x == 14){
            
            if((Math.abs(gj-sj)==1&&gi - si ==0)||(gj - sj ==0&&Math.abs(gi-si)==1)){
                
                if(x == 7&&si >= 7&&sj >= 3&&sj <= 5)    return true;
                else if(x == 14&&si <= 2&&sj >= 3&&sj <= 5)    return true;
                else return false;
            }
            else return false;
            
        }
        //炮:隔一个
        else if(x == 2||x == 9){
            
            //若要吃棋子,必须中间有且只有一枚棋子
            if(x*y!=0){
                int t = 0;
                if(gi == si){
                    for(int m = Math.min(gj, sj); m <= Math.max(gj, sj); m++){
                        if(place[gi][m] != 0)    t++;
                    }
                }
                else if(gj == sj){
                    for(int m = Math.min(gi, si); m <= Math.max(gi, si); m++){
                        if(place[m][gj] != 0)    t++;
                    }
                }
                if(t == 3)    return true;
                
            }    
                
            //若为不吃棋子的情况,中间不可以有其他棋子,且只能走直线
            else {
                int t = 0;
                if(gi == si){
                    for(int m = Math.min(gj, sj); m <= Math.max(gj, sj); m++){
                        if(place[gi][m] != 0)    t++;
                    }
                }
                else if(gj == sj){
                    for(int m = Math.min(gi, si); m <= Math.max(gi, si); m++){
                        if(place[m][gj] != 0)    t++;
                    }
                }
                if(t == 1) return true;
                else return false;
            }
        }
        //兵:不能后退,且过了河才可以左右移动
        else if(x == 1||x == 8){
            //判断是否过河
            if(x == 1){
                if(gi >=5){
                    if(gi - si == 1&&gj == sj)    return true;
                    else return false;
                }
                else if((gi - si == 1&&sj - gj == 0)||(gi - si == 0&&Math.abs(sj-gj) == 1))    return true;
                else return false;
            }
            else if(x == 8){
                if(gi <5){
                    if(si - gi == 1&&gj == sj)    return true;
                    else return false;
                }
                else if(((si - gi == 1&&sj - gj == 0))||(gi - si == 0&&Math.abs(sj-gj) == 1))    return true;
                else return false;
            }
            else return false;
        }
        
        return false;
    }

Senarai panjang di sini, artileri dan jeneral perlu dipertimbangkan secara berasingan dipertimbangkan secara berasingan, dan jeneral perlu dipertimbangkan secara berasingan Ia lebih menyusahkan

//判断将是否会面
public boolean meet(){
        int jiangi=0, jiangj=0, shuaii=0, shuaij=0, temp=0;
        for(int i=0; i<10; i++){
            for(int j=0; j<9; j++){
                if(place[i][j]==7){
                    shuaii = i;
                    shuaij = j;
                }
                else if(place[i][j]==14){
                    jiangi = i;
                    jiangj = j;
                }
            }
        }
        if(shuaij == jiangj){
            for(int i=jiangi+1; i<shuaii; i++){
                if(place[i][shuaij] != 0)    temp++;
            }
        }
        else return false;//没会面
        if(temp != 0)    return false;//没会面
        else return true;//会面了
    }

8. Pusingan

Merah dan hitam bergilir-gilir bermain catur

Saya menulis kaedah berasingan untuk menentukan sama ada jeneral akan bertemu, kerana yang menyebabkan jeneral bertemu bukan sahaja pergerakan jeneral sendiri Akibatnya, ia mungkin juga pergerakan buah catur yang lain, jadi ia juga boleh digerakkan jika ia memenuhi fungsi sebelumnya dan fungsi tidak mengembalikan muka Apabila bergerak, saya menentukan parameter x untuk merekodkan bilangan permainan mengikut Ganjilnya dan juga menentukan giliran sebelah mana. Dengan cara ini, peraturan catur dilaksanakan.

9. Menyesal catur


Tidak dapat dielakkan akan berlaku kesilapan, dan adalah lebih sesuai untuk menambah fungsi catur penyesalan.

Apabila kita menukar nilai dua mata (atau dalam kes menangkap sekeping), kita perlu merekodkan nilai sebelumnya, dan kemudian menukarnya semula apabila pendengar tindakan mendengar untuk mengklik butang penyesalan.

Anda hanya boleh menyesali langkah itu sekali pada satu masa, dan anda tidak boleh menyesali langkah itu jika buah catur itu tidak bergerak pada awalnya.

10. Latar Belakang dan Petua

Tambah latar belakang pilihan anda, dan untuk kemudahan bermain catur, tandakan giliran sebelah mana.

Untuk menambah latar belakang, anda boleh menggunakan kaedah yang sama seperti melukis buah catur, jadi ia hendaklah dilukis di hadapan papan catur untuk mengelakkannya daripada ditutup.

Terdapat masalah yang jelas dengan menambah ini, iaitu, setiap kali anda mengendalikan butang di sebelah kanan, ia akan hilang dan dilindungi oleh imej latar belakang anda. Apa yang perlu saya lakukan?

Jadi, tiga kaedah telah diringkaskan:


1 Tulis semula kaedah cat
2. Tambah butang di sudut kiri atas dalam bentuk
3 . Hanya p butang terus pada imej latar belakang (ambil tangkapan skrin) dan kemudian lukiskannya

Selain itu, anda juga boleh menambah perkataan "pemain catur semasa" pada imej latar belakang untuk memaparkan pemain catur semasa di sebelah Gambar Jeneral Fang.
Parameter kiraan dipinjam di sini dan diserahkan kepada pendengar, dan pembina ditulis semula.

int count=1;

if(listener.count==1){
            //画帥
        bg.drawImage(chess[6], 708, 322, 50, 50, null); 
    }else if(listener.count==-1){
            //画将
        bg.drawImage(chess[13], 708, 322, 50, 50, null); 
}

Setiap kali sekeping dimainkan, kira×(-1), tandakan sebelah mana ia dan lukiskan gambar.


Dilampirkan gambar hasil:

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan permainan catur Cina menggunakan Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam