服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java实现五子棋游戏(2.0)

Java实现五子棋游戏(2.0)

2022-11-23 10:51宝贝垚 Java教程

这篇文章主要为大家详细介绍了Java实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Java实现五子棋游戏的具体代码,供大家参考,具体内容如下

简介

相比之前,做出了以下修改:

1.新增菜单栏,将重新开始和退出的按钮移到了菜单栏;
2.可以实时显示时间(多线程);
3.下棋时可以显示当前是哪一方在下棋;
4.可以更改背景颜色;
5.可以更改先行方(默认黑子)。

结果

Java实现五子棋游戏(2.0)

Java实现五子棋游戏(2.0)

Java实现五子棋游戏(2.0)

完整代码

1.Frame.java(主界面)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
package Gobang;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
 
//import java.applet.*;
//import java.net.*;
//import java.io.*;
//import javax.imageio.*;
public class Frame  extends JFrame implements MouseListener,ActionListener{//JFrame的扩展类
    
    //ImageIcon image;
    //JLayeredPane layeredPane;
    //JPanel jp;
    /*本来想用于播放背景音乐,但是没有成功,,,先暂时放弃
    File f;
    URI uri;
    URL url;
    @SuppressWarnings("deprecation")
    */
    private static final long serialVersionUID = 1L;
    public JButton AdmitDefeatButton,RegretButton;//两个按钮,各有其功能。
    JLabel TimeLabel;//用来显示时间
    JLabel jl1,jl2,jl3;//游戏信息
    Graphics g;//画笔
    BufferedImage buf;
    
    int x;//鼠标的坐标
    int y;
    int[][] Chess = new int[20][20];   // 保存棋子,1表示黑子,2表示白子
    boolean IsBlack = true;   //表示当前要下的是黑子还是白子,true表示黑子,false表示白子
    boolean IsFinish = false;   //表示当前游戏是否结束
    int xRange;
    int yRange;
    int[] chessX = new int[400];//用来保存从开始到当前的所有棋子,用于悔棋;
    int[] chessY = new int[400];
    int countX = 0;
    int countY = 0;
    
    
    //菜单栏
    JMenuBar menubar;
    JMenu menu;
    JMenu setmenu;
    JMenuItem RestartItem,ExitItem,IntroItem,BackgroundItem,FirstItem;
    
    //获取屏幕的宽度和高度
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    int screenWidth = screenSize.width;
    int screenHeight = screenSize.height;
    
    public Frame() {
        /*插入背景图片
        //layeredPane=new JLayeredPane();
        //image=new ImageIcon("F:\\JAVA\\eclipse-workspace\\Gobang\\src\\1.jpg");//随便找一张图就可以看到效果。
        //jp=new JPanel();
        //jp.setBounds(0,0,600,600);
        //jl=new JLabel(image);
        //jl.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
        //jp.add(jl);
        //layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);
        //this.setLayeredPane(layeredPane);
        */
        
        /*音频播放部分
        try {
            f = new File("");
            uri = f.toURI();
            url = uri.toURL();
            AudioClip aau; 
            aau = Applet.newAudioClip(url);
            aau.loop();  //循环播放
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        */
        
        //设置标题、大小、排列方式等
        this.setTitle("五子棋");
        this.setSize(600,600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setLayout(null);
        int height = this.getHeight();
        int width = this.getWidth();
        this.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
        
        //实时显示时间,用到多线程来实时显示。
        jl1 = new JLabel("北京时间");
        jl1.setLocation(430, 120);
        jl1.setSize(80,20);
        this.add(jl1);
        TimeLabel = new JLabel();
        new Thread(new Time(TimeLabel)).start();//新建一个线程
        TimeLabel.setLocation(510, 120);
        TimeLabel.setSize(80,20);
        this.add(TimeLabel);
        
        //显示游戏信息,当前是谁执子;
        jl2 = new JLabel("游戏信息");
        jl2.setLocation(430, 150);
        jl2.setSize(80,20);
        jl3 = new JLabel("黑方先行");
        jl3.setLocation(510, 150);
        jl3.setSize(80,20);
        this.add(jl2);
        this.add(jl3);
        
        //设置背景颜色
        this.getContentPane().setBackground(new Color(255, 239 ,213));
        this.getContentPane().setVisible(true);
        
        //设置菜单栏
        menubar = new JMenuBar();//菜单栏
        menu = new JMenu("游戏操作"); 
        RestartItem = new JMenuItem("重新开始");
        ExitItem = new JMenuItem("退出");
        menu.add(RestartItem);
        menu.add(ExitItem);
        menubar.add(menu);
        setmenu = new JMenu("设置");
        IntroItem = new JMenuItem("游戏说明");
        BackgroundItem = new JMenuItem("背景颜色");
        FirstItem = new JMenuItem("先行方");
        setmenu.add(IntroItem);
        setmenu.add(BackgroundItem);
        setmenu.add(FirstItem);
        menubar.add(setmenu);
        menubar.setBackground(new Color(249,205,173));
        menubar.setVisible(true);
        this.setJMenuBar(menubar);
        
        //两个按钮,认输和悔棋;
        AdmitDefeatButton = new JButton("认输");
        AdmitDefeatButton.setSize(80,40);
        AdmitDefeatButton.setLocation(120, 480);
        RegretButton = new JButton("悔棋" );
        RegretButton.setSize(80,40);
        RegretButton.setLocation(240, 480);
        this.add(AdmitDefeatButton);
        this.add(RegretButton);
        
        
        /*
        五个按钮添加到中间容器;
        panel1 = new JPanel();
        panel1.setBorder(BorderFactory.createLoweredBevelBorder()); //设置边框
        panel1.setLayout(new GridLayout(1,5));
        panel1.add(RestartButton);
        panel1.add(SetButton);
        panel1.add(AdmitDefeatButton);
        panel1.add(RegretButton);
        panel1.add(ExitButton);
        this.add(panel1);
        panel1.setSize(460,30);
        panel1.setLocation(0, 460);
        */
        
        this.repaint();//表示重新绘制画布,可以自动调用paint函数;
        //本类作为监听类,包括鼠标监听和按钮动作监听;
        this.addMouseListener(this);
        IntroItem.addActionListener(this);
        BackgroundItem.addActionListener(this);
        FirstItem.addActionListener(this);
        RestartItem.addActionListener(this);
        AdmitDefeatButton.addActionListener(this);
        RegretButton.addActionListener(this);
        ExitItem.addActionListener(this);
    }
    //画布绘制
    public void paint(Graphics g)
    {
        if(g == null)//如果第一次绘制,新建一个图片,并且创建画布。
        {
            buf = new BufferedImage(450, 450, BufferedImage.TYPE_INT_RGB);
            g =  buf.createGraphics();
        }
        if(g != null)//
        {
            super.paint(g);//表示在原来图像的基础上,再画图
            g.setColor(new Color(249,205,173));//画笔颜色调成褐色;
            g.fill3DRect(20, 130, 400, 400,true);//用画笔画一个边长为400的正方形;边距为20,130
            for(int i = 0; i <= 20; i++)//用画笔横竖各画19条线
            {
                g.setColor(Color.BLACK);//画笔颜色调为黑色;
                g.drawLine(20,130+i*20,420,130+i*20);
                g.drawLine(20+i*20,130,20+i*20,530);
            }
        }
         for(int i=0; i<20; i++){
                for (int j = 0; j < 20; j++) {
                    //画实心黑子,直径16
                    if(Chess[i][j] == 1){    
                        int tempX = i*20+12;
                        int tempY = j*20+122;
                        g.setColor(Color.BLACK);
                        g.fillOval(tempX, tempY, 16, 16);
                        g.setColor(Color.BLACK);
                        g.drawOval(tempX, tempY, 16, 16);
                    }
                    
                    //画实心白子,直径16
                    if(Chess[i][j] == 2){
                        int tempX = i*20+12;
                        int tempY = j*20+122;
                        g.setColor(Color.WHITE);
                        g.fillOval(tempX, tempY, 16, 16);
                        g.setColor(Color.WHITE);
                        g.drawOval(tempX, tempY, 16, 16);
                    }
                }
            }
        g.drawImage(buf, 0, 0,this);
        
    }        
 
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
        
        if(!IsFinish)    //判断棋局是否结束
        {
            x = e.getX();    //获取当前鼠标点击位置
            y = e.getY();
            if(x >= 20 && x < 420 && y >= 130 && y<= 530)//判断鼠标是否在棋局内
            {
                xRange = (x-20)%20;
                if(xRange > 10 && xRange < 20)    //如果在交叉点的边长为10的范围内,就把棋子下在这;
                {
                    x = (x - 20) / 20 + 1;
                }
                else
                {
                    x = (x - 20) / 20;
                }
                yRange = (y-130)%20;
                if(yRange > 10 && yRange < 20)
                {
                    y = (y - 130) / 20 + 1;
                }
                else
                {
                    y = (y - 130) / 20;
                }
                
                if(Chess[x][y] == 0)    //如果该交叉点没有被下过;
                {
                    chessX[countX++] = x;    //存储当前棋子的位置;
                    chessY[countY++] = y;
                    if(jl3.getText().equals("黑方先行"))            //如果是黑子
                    {
                        Chess[x][y] = 1;
                        IsBlack = false;
                        jl3.setText("白方先行");
                    }
                    else if(jl3.getText().equals("白方先行"))
                    {
                        Chess[x][y] = 2;
                        IsBlack = true;
                        jl3.setText("黑方先行");
                    }
                    this.repaint();//重新绘制画布
                }
                
                if(this.isWin())//如果下棋之后赢了,弹出对话框
                {
                    if(Chess[x][y] == 1)
                    {
                        JOptionPane.showMessageDialog(this, "黑方胜利");
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(this, "白方胜利");
                    }
                    this.IsFinish = true;  //游戏结束
                }
                
            }
            
 
        }
    }
    
    public boolean isWin(){
        boolean flag = false;
        int count = 1
        int color = Chess[x][y];  
        //判断横向是否有5个棋子相连
        count = this.checkCount(1,0,color);
        if(count >= 5){
            flag = true;
        }else {
            //判断纵向
            count = this.checkCount(0,1,color);
            if(count >= 5){
                flag = true;
            }else {
                 //判断右上,左下
                count = this.checkCount(1,-1,color);
                if(count >= 5){
                    flag = true;
                }else {
                    //判断右下,左上
                    count = this.checkCount(1,1,color);
                    if(count >= 5){
                        flag =  true;
                    }
                }
            }
        }
        return flag;
    }
     // 检查棋盘中的五子棋是否连成五子,xChange,yChange为相对于当前棋子位置的变化量
    public int checkCount(int xChange , int yChange ,int color){
        int count = 1;//统计总共有几个连着的棋子;
        int tempX = xChange;
        int tempy = yChange;  
        //判断棋子右边有没有相同颜色的棋子;
        while(x + xChange >=0 && x+xChange <20  && y+yChange >=0 && 
                y+yChange < 20 && color == Chess[x+xChange][y+yChange])
        {
            count++;                        //如果有,棋子数加一
            if(xChange != 0)  
                xChange++;                    //如果横向方向变化,x相对位置加一
            if(yChange != 0 )                
            {      
                if(yChange != 0)            
                {
                    if(yChange > 0)            //如果纵向方向增加,y相对位置加一
                    {   
                        yChange++;        
                    }
                    else                     //如果纵向方向减小,y相对位置减一
                    {
                        yChange--;        
                    }
                }
            }
            
        }
        xChange = tempX;
        yChange = tempy;  
        //判断棋子左边有没有相同颜色的棋子;
        while(x-xChange >=0 && x-xChange <20 && y-yChange >=0 &&
                y-yChange <20 && color == Chess[x-xChange][y-yChange])
        {        
            count++;
            if(xChange != 0)
            {
                xChange++;
            }
            if(yChange != 0)
            {
                if (yChange > 0
                {
                    yChange++;            
                }
                else
                {
                    yChange--;            
                }
            }
        }
        return count;
    }
    //监听动作函数
    //@SuppressWarnings("deprecation")
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        
        if(e.getActionCommand()=="重新开始")//如果点击的按钮是RestartButton,清空画板,还原设置
        {
            if(JOptionPane.showConfirmDialog(this, "是否重新开始游戏?") == 0)
            {
                for (int i = 0; i < 20; i++) 
                {
                    for (int j = 0; j < 20; j++) 
                    {
                        Chess[i][j] = 0;  //清空棋盘的棋子
                    }
                    
                }
                
                //清空下棋棋子坐标的记录
                for (int i = 0; i < 400; i++)
                {
                    chessX[i] = 0;
                    chessY[i] = 0;
                }
                countX =0;
                countY =0;
                IsBlack = true;
                jl3.setText("黑方先行");
                IsFinish = false;
                this.repaint();
            }
        }
        if(e.getSource() == AdmitDefeatButton)//如果点击的按钮是AdmitDefeatButton,结束游戏,并提示
        {
            if(!IsFinish)    //判断棋局是否结束
            {
                if(JOptionPane.showConfirmDialog(this, "是否确定认输?") == 0)
                {
                    if(IsBlack == true)
                    {
                        JOptionPane.showMessageDialog(this,"白方获胜");
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(this,"黑方获胜");
                    }
                    IsFinish = true;
                }
            }
        }
        if(e.getActionCommand()=="退出")//如果点击的按钮是ExitButton,退出程序
        {
            if(JOptionPane.showConfirmDialog(this, "是否确定退出?") == 0)
            {
                System.exit(0);
            }
        }
        if(e.getSource() == RegretButton)///如果点击的按钮是RegretButton,悔棋一步
        {
            if(!IsFinish)    //判断棋局是否结束
            {
            if(IsBlack == true)    //如果现在是黑子要下,表示悔棋的是白子
            {
                if(JOptionPane.showConfirmDialog(this, "白方想要悔棋,是否同意?") == 0)
                {
                    int tempX = chessX[--countX];    //获取上一步白子下的位置;
                    int tempY = chessY[--countY];
                    Chess[tempX][tempY] = 0;    //撤回白子
                    IsBlack = false;    //当前要下的变为白方
                    jl3.setText("白方先行");
                }
            }
            else
            {
                if(JOptionPane.showConfirmDialog(this, "黑方想要悔棋?") == 0)
                {
                    int tempX = chessX[--countX];
                    int tempY = chessY[--countY];
                    Chess[tempX][tempY] = 0;
                    IsBlack = true;
                    jl3.setText("黑方先行");
                }
            }
            this.repaint();    //重新绘制画布
            }
        }
        if(e.getActionCommand()=="游戏说明")
        {
            JDialog frame1 = new JDialog();//新建对话框
            frame1.setSize(200,200);
            int height = frame1.getHeight();
            int width = frame1.getWidth();
            frame1.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
             JTextArea ta = new JTextArea();//新建文本框
             ta.setText("双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜。");
             ta.setEditable(false);
             JScrollPane jsp = new JScrollPane(ta);
             frame1.setTitle("规则");
             frame1.getContentPane().add(jsp);    //添加文本框
             frame1.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);    // 设置模式类型
             frame1.setVisible(true);
        }
        if(e.getActionCommand()=="背景颜色")
        {
            JDialog frame2 = new JDialog();//新建对话框
            frame2.setSize(150,200);
            int height = frame2.getHeight();
            int width = frame2.getWidth();
            frame2.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
            frame2.setLayout(new GridLayout(3,2,10,10));
            //三个文本框;
            JLabel label1 = new JLabel("Red");
            JLabel label2 = new JLabel("Green");
            JLabel label3 = new JLabel("Blue");
            JTextField tf1 = new JTextField("255");
            //tf1.setSize(80, 20);
            JTextField tf2 = new JTextField("239");
            //tf2.setBounds(10, 40, 80, 20);
            JTextField tf3 = new JTextField("213");
            //tf3.setBounds(10, 70, 80, 20);
            frame2.setTitle("设置背景颜色");
            frame2.getContentPane().add(label1);
            frame2.getContentPane().add(tf1);    //
            frame2.getContentPane().add(label2);
            frame2.getContentPane().add(tf2);
            frame2.getContentPane().add(label3);
            frame2.getContentPane().add(tf3);                    
            frame2.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);    // 设置模式类型
            frame2.setVisible(true);
            
            //改变背景颜色
            int Red =Integer.parseInt(tf1.getText());
            int Green =Integer.parseInt(tf2.getText());
            int Blue =Integer.parseInt(tf3.getText());
            this.getContentPane().setBackground(new Color(Red,Green,Blue));
            this.repaint();
        }
        if(e.getActionCommand() == "先行方") {
            new FirstDialog(IsBlack,jl3);//新建对话框,改变先行方
            
        }
    }
    public static void main(String[] args) {
        new Frame();
}
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
}
//改变先行方
class FirstDialog extends JDialog implements ItemListener{
 
    /**
    
     */
    private static final long serialVersionUID = 1L;
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    int screenWidth = screenSize.width;
    int screenHeight = screenSize.height;
    Boolean IsBlack;
    JLabel jl = new JLabel();
    JRadioButton rbWhite,rbBlack;
 
    FirstDialog(Boolean IsBlack,JLabel jl)
    {
        this.IsBlack = IsBlack;
        this.jl = jl;
        this.setSize(150,200);
        int height = this.getHeight();
        int width = this.getWidth();
        this.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
        this.setTitle("先行方");
        
        //一个单选组合;
        rbWhite = new JRadioButton("白子");
        rbBlack = new JRadioButton("黑子");
        this.setLayout(new FlowLayout());
        this.getContentPane().add(rbWhite);
        this.getContentPane().add(rbBlack);    //
        ButtonGroup bgroup = new ButtonGroup();
        bgroup.add(rbWhite);
        bgroup.add(rbBlack);
        
        //本类做监听类
        rbWhite.addItemListener(this);
        rbBlack.addItemListener(this);
        this.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);    // 设置模式类型
        this.setVisible(true);
    }
    public void itemStateChanged(ItemEvent e) {
        if(rbWhite.isSelected())//选中白子时,将先行方设为白子;
        {
            IsBlack = false;
            jl.setText("白方先行");
        }
        else if(rbBlack.isSelected())
        {
            IsBlack = true;
            jl.setText("黑方先行");
        }
    }
    
}

2.Time.java(实时显示时间)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package Gobang;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.text.*;
public class Time implements Runnable{
    private JLabel lab = new JLabel();
    public Time(JLabel lab) {
        this.lab = lab;
    }
    public void run() {
        while(true) {
            SimpleDateFormat simpleFormat = new SimpleDateFormat("HH:mm:ss");
            Calendar c = Calendar.getInstance();
            lab.setText(simpleFormat.format(c.getTime()));
            lab.setForeground(Color.RED);
            try {
                Thread.sleep(1000);
            }catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_43533435/article/details/109764861

延伸 · 阅读

精彩推荐