Java implements simple tic-tac-toe (OX game) V2.0

Introduction

Job description
Still following the last OX game, this time the teacher ’s request is strange and weird to tell the truth, but after reading it a few times, we have to grasp a few key points, "upper left corner", "draw" . It seems that I just learned to paint, so, in all cases, I use paint () to write it. Note: paint () is automatically executed! ! ! In other words, you don't need to call it, it will automatically draw on the layer of the class it is in when you run the program! !

Main idea

  1. Place the button in the upper left corner of each square. Cancel the original nine buttons to fill a chessboard (JPanel), instead of filling 9 chesspanels (ChessPanel extends JPanel) into the chessboard according to the table layout, and then fill the original buttons into the empty layout (null) chesspanel respectively (1. If the layout is not empty, the size of the button cannot be set. 2. The empty layout defaults to placing the component in the upper left corner). Set the chesspanel border to be visible, reflecting the "small square". (Mainly modified in initChessboard ())
  2. Respond to events and draw pictures. First of all, we have to be clear that our goal is to perform a circle or fork operation on the chesspanel after the button is clicked, but paint is automatically executed, we have no way to directly control, therefore, we can only set each chesspanal The visibility of the inner circle or fork, and then redraw (plus repaint ()) through the event response (modify actionPerformed ()) to achieve the effect (see paint () for details). How to draw a picture? The topic requires drawing circles and forks, so drawLine () is used to draw two vertical lines, and drawOval is enough to draw a circle. If you want a beautiful point of view, first adjust the thickness of the brush and draw the color. These two methods are reflected in my code. Finally, emphasize that the coordinates are relative coordinates, that is, if your paint is in chesspanel [3], then the coordinates refer to the relative position of the upper left corner of the drawn component to the upper left corner of chesspannel [3]. See this blog post for details .

effect

Insert picture description here
PS: I originally wanted to change the button to keep the number unchanged, but it was too much trouble to change, so I did n’t do it.

Code

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestOXGame {
    public static void main(String[] args) {
        MyOXGame myoxgame=new MyOXGame();
    }
}

class MyOXGame extends JFrame implements ActionListener {
    //主体部分,绘制GUI,编辑有关响应

    JButton[] button;//对象数组,表示棋盘上的九个格子
    ChessPanel[] chessPanel;//小方格,放棋子的panel
    JButton restart;//重置键
    JLabel judgement;//裁判,用来显示游戏的结果
    JPanel chessboard,basicPanel;//棋盘,棋盘下部区域
    int player=0;//显示当前玩家编号
    boolean gameOverFlag=false;//记录游戏是否结束,如果结束值为true,停止对事件的响应

    MyOXGame(){//生成函数,生成游戏
        setTitle("MY OXGAME");
        setBounds(400,400,340,360);//窗体基本设置

        button=new JButton[10];
        chessPanel=new ChessPanel[10];
        restart=new JButton("Restart");
        chessboard=new JPanel();
        basicPanel=new JPanel();
        judgement=new JLabel("");
        chessboard.setLayout(new GridLayout(3,3));
        basicPanel.setLayout(new FlowLayout());//组件初始化设置

        add(chessboard,BorderLayout.CENTER);
        add(basicPanel,BorderLayout.SOUTH);
        basicPanel.add(restart);
        basicPanel.add(judgement);//布局设置

        initChessboard();//初始化棋盘,使九个按钮按顺序加上1-9的标签,
        addChessToChessboard(chessboard);//将九个按钮添加至chessboard
        restart.addActionListener(this);//添加监听器

        buttonListener();//为按钮添加监听器

        setVisible(true);//设置可视化
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//使关闭键有用
    }

    private void addChessToChessboard(JPanel chessboard){
        //添加按钮至小方格
        for(int i=1;i<=9;i++) {
            chessboard.add(chessPanel[i]);
        }
    }

    private void initChessboard(){
        //使棋子按钮初始化为1-9
        for(int i=1;i<=9;i++){
            button[i]=new JButton(  ""+i);
            button[i].setSize(45,45);
            chessPanel[i]=new ChessPanel();
            chessPanel[i].setLayout(null);
            chessPanel[i].setBorder(BorderFactory.createLineBorder(Color.black, 1));
            chessPanel[i].add(button[i]);
        }
    }

    private void buttonListener(){
        //为棋子按钮添加监听器
        for(int i=1;i<=9;i++)
        {
            button[i].addActionListener(this);
        }
    }

    private void restartTheGame(){
        //重置游戏
        chessboard.removeAll();//必须于repaint和updateUI一起用不然要不啥都没有,要不没有改动
        //必须注意removll会清空布局
        chessboard.setLayout(new GridLayout(3,3));
        initChessboard();
        addChessToChessboard(chessboard);
        buttonListener();
        chessboard.updateUI();
        chessboard.repaint();

        judgement.setText("");
        gameOverFlag=false;
    }
    private boolean checkDogfall(char[] chess){
        //检查是否被填满,填满即为平局
        for(int i=1;i<chess.length;i++){
            if (chess[i]>='1'&&chess[i]<='9')
                return false;
        }
        return true;
    }

    private int checkWinner(int playerNow) {
        //检查当前游戏状态,-2表示没有决出胜负,-1表示平局。0表示O玩家胜利,1表示X玩家胜利
        char[] chess=new char[10];
        for(int i=1;i<=9;i++){
            chess[i]=button[i].getLabel().charAt(0);
        }
        if(     (chess[1]==chess[2]&&chess[2]==chess[3])||
                (chess[4]==chess[5]&&chess[5]==chess[6])||
                (chess[7]==chess[8]&&chess[8]==chess[9])||
                (chess[1]==chess[5]&&chess[5]==chess[9])||
                (chess[7]==chess[5]&&chess[5]==chess[3])||
                (chess[1]==chess[4]&&chess[4]==chess[7])||
                (chess[2]==chess[5]&&chess[5]==chess[8])||
                (chess[3]==chess[6]&&chess[6]==chess[9])){
            //判断当前玩家是否为赢家
            return playerNow;
        }
        else if(checkDogfall(chess))
            return -1;
        return -2;
    }

    public class ChessPanel extends JPanel{

        int paintCode=-1;//状态码,用来设置可见性及类型,-1表示不可见,0表示圈圈,1表示叉叉
        public void paint(Graphics g) {
            super.paint(g);
            if(paintCode==0){
                Graphics2D g_2D=(Graphics2D)g;
                g_2D.setStroke(new BasicStroke(6.0f));
                g.drawOval(43,43,23,23);//用笔画
                //Image oo = new ImageIcon("src/oo.png").getImage();
                //g.drawImage(oo,40,40,40,40,this);//用图画

            }
            else if(paintCode==1){
                Image xx = new ImageIcon("src/xx.png").getImage();
                g.drawImage(xx,43,43,25,25,this);//用图画
                //g.drawLine(50,50,60,60);
                //g.drawLine(50,60,60,50);//用笔画
            }
        }
    }


    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        //对监听的事件进行响应
        int statueCode;
        int id;
        JButton buttonSource=(JButton)actionEvent.getSource();
        if(buttonSource==restart){
            //判断是否使restart键,如果是,重置游戏
            restartTheGame();
        }
        if (gameOverFlag==true) return;
        String buttonMark=buttonSource.getLabel();
        id=(int)(buttonMark.charAt(0)-'0');
        if(buttonMark.matches("[0-9]")){
            if(player==0){
                //绘制o
                buttonSource.setLabel("O");
                chessPanel[id].paintCode=0;//更改状态码
                repaint();//使所有chessPanel重绘
            }
            else{
                //绘制x
                buttonSource.setLabel("X");
                chessPanel[id].paintCode=1;
                repaint();
            }
            statueCode=checkWinner(player);
            if(statueCode==0){
                judgement.setText("Player O wins the game! ");
                gameOverFlag=true;
            }
            else if(statueCode==1){
                judgement.setText("Player X wins the game!");
                gameOverFlag=true;
            }
            else if(statueCode==-1){
                judgement.setText("The game a draw!");
            }
            player=(player+1)%2;//更换玩家
        }
    }

}

postscript

In the spirit of the Internet, I will exchange experience with you. I hope everyone still writes their own. Do n’t directly copy the assignment to affect me and affect you (how can you change the variable name), the other two assignments this time are both If it's really good, don't talk about it! This question has been spent a lot of time. I checked it for a long time before I realized that I ca n’t click to draw one directly. I found the origin of the coordinates drawn for a long time. Save a lot of time. Support me if you like it? If you have any questions, please comment ~

Published 2 original articles · praised 7 · visits 373

Guess you like

Origin blog.csdn.net/weixin_44321098/article/details/105571615