Experiment 3: maze game development based on A * search algorithm

Experimental requirements

1. Maze game is a very classic game. In this problem, it is required to randomly generate a maze and solve the maze.
2. The game is required to support two modes: players walking the maze and the system walking the maze path. Players walk through the maze, control through the keyboard direction keys, and leave traces on the walking path; System maze path requirements based on A* Algorithm implementation, output the optimal path of maze and display.
3. Design interactive and friendly game graphical interface.

Programming tools

        1. Using JAVA language,

        2. Development environment: IntelliJ IDEA Community Edition 2021.2

Experimental code part

The experimental code is divided into two parts: interface design and algorithm. The interface shall be reasonably arranged, concise and beautiful; The algorithm should be robust.

1, Interface design

1. Create a Calculator class for javax Inheritance of JFrame class in swing Java awt. event. Assemble the interface of actionlisten in, and then generate the constructor. Create a container named frame.

public class Calculator extends JFrame implements ActionListener {
    Calculator() {
        init();
    }
    public void init() {
        JFrame frame = new JFrame("The Calculator Of Czf");                      //Create a top-level container with the title "calculator" in a normal window;
        frame.setLayout(null);                                                   //Set to use a specific layout manager;

2. The layout of keys shall be reasonable, the keys shall be overlapped, and the keys shall be beautiful and neatly arranged. Setboundaries contains four parameters. The upper left corner of the setting window is located in the upper left corner of the screen (the left vertex is (x, y)), with width pixels and height pixels.

 //Place number 0
        button0 = new JButton("0");                                         //Note: when naming the keys, it should be based on the size of the keys, otherwise the marks on the keys cannot be fully displayed;
        button0.setBounds(100, 400, 110, 50);
        frame.add(button0);
        //Place number 1
        button1 = new JButton("1");
        button1.setBounds(40, 340, 50, 50);
        frame.add(button1);
        //Place number 2
        button2 = new JButton("2");
        button2.setBounds(100, 340, 50, 50);
        frame.add(button2);
        //Place number 3
        button3 = new JButton("3");
        button3.setBounds(160, 340, 50, 50);
        frame.add(button3);
        //Place number 4
        button4 = new JButton("4");
        button4.setBounds(40, 280, 50, 50);
        frame.add(button4);
        //Place number 5
        button5 = new JButton("5");
        button5.setBounds(100, 280, 50, 50);
        frame.add(button5);
        //Place number 6
        button6 = new JButton("6");
        button6.setBounds(160, 280, 50, 50);
        frame.add(button6);
        //Place number 7
        button7 = new JButton("7");
        button7.setBounds(40, 220, 50, 50);
        frame.add(button7);
        //Place number 8
        button8 = new JButton("8");
        button8.setBounds(100, 220, 50, 50);
        frame.add(button8);
        //Place number 9
        button9 = new JButton("9");
        button9.setBounds(160, 220, 50, 50);
        frame.add(button9);
        //place.
        buttonPoint = new JButton(".");                                                   //text: is the explanatory word of the automatically generated parameter
        buttonPoint.setBounds(40, 400, 50, 50);                            //Parameter interpreter for automatic complement
        frame.add(buttonPoint);
        //Place+
        buttonAdd = new JButton("+");
        buttonAdd.setBounds(220, 400, 50, 50);
        frame.add(buttonAdd);
        //Place-
        buttonSub = new JButton("-");
        buttonSub.setBounds(220, 340, 50, 50);
        frame.add(buttonSub);
        //Place*
        buttonMul = new JButton("*");
        buttonMul.setBounds(220, 280, 50, 50);
        frame.add(buttonMul);
        //Place/
        buttonDiv = new JButton("/");
        buttonDiv.setBounds(220, 220, 50, 50);
        frame.add(buttonDiv);
        //Place=
        buttonequl = new JButton("=");
        buttonequl.setBounds(280, 340, 110, 110);
        frame.add(buttonequl);
        //Abdication key
        buttondele = new JButton("B");
        buttondele.setBounds(280, 220, 110, 110);
        frame.add(buttondele);
        //Place left parenthesis(
        buttonzuo = new JButton("(");
        buttonzuo.setBounds(40, 160, 80, 50);
        frame.add(buttonzuo);
        //Place right parenthesis)
        buttonyou = new JButton(")");
        buttonyou.setBounds(130, 160, 80, 50);
        frame.add(buttonyou);
        //Place C to eliminate all inputs
        buttonC = new JButton("C");
        buttonC.setBounds(220, 160, 80, 50);
        frame.add(buttonC);
        //Place CE to eliminate the current input
        buttonCE = new JButton("CE");
        buttonCE.setBounds(310, 160, 80, 50);
        frame.add(buttonCE);

3. Use JButton to define the key, JTextField to define the text box of the displayed expression and result, and JTextArea to define the text box of the displayed history.

    /**
     * Define button
     */
    private JTextField textField1;
    private JTextArea textField2;
    private JButton buttonzuo;//(
    private JButton buttonyou;//)
    private JButton buttonC;//c
    private JButton buttonCE;//CE
    private JButton buttondele;//< - delete
    private JButton buttonDiv;//÷
    private JButton button7;//7
    private JButton button8;//8
    private JButton button9;//9
    private JButton buttonAdd;//+
    private JButton button4;//4
    private JButton button5;//5
    private JButton button6;//6
    private JButton buttonSub;//-
    private JButton button1;//1
    private JButton button2;//2
    private JButton button3;//3
    private JButton buttonMul;//x
    private JButton buttonequl;//=
    private JButton button0;//0
    private JButton buttonPoint;//.

4.java.awt.event.ActionListener calls the method of the monitor. addActionListener() must have an event listening object. this represents the object of the current class and is used to monitor the key status.

        textField1.addActionListener(this);
        buttonzuo.addActionListener(this);
        buttonyou.addActionListener(this);
        buttonC.addActionListener(this);
        buttonCE.addActionListener(this);
        buttondele.addActionListener(this);
        buttonDiv.addActionListener(this);
        button7.addActionListener(this);
        button8.addActionListener(this);
        button9.addActionListener(this);
        buttonAdd.addActionListener(this);
        button4.addActionListener(this);
        button5.addActionListener(this);
        button6.addActionListener(this);
        buttonSub.addActionListener(this);
        button1.addActionListener(this);
        button2.addActionListener(this);
        button3.addActionListener(this);
        buttonMul.addActionListener(this);
        buttonequl.addActionListener(this);
        button0.addActionListener(this);
        buttonPoint.addActionListener(this);

 5. Define the flag bit.

    String str = null;
    int pointbook = 0;
    int equalbook = 0;
    int zuonum = 0;
    int younum = 0;
    int equnum = 0;

II. Algorithm

1. Operation of keys monitored by the monitor. The contents of 0 ~ 9 are the same, and some special situations need to be considered for symbols. For example, a number can only have one decimal point, and the number of left parentheses and right parentheses should be equal. The decimal point and brackets are set here.

public void actionPerformed(ActionEvent e) {
        if (equnum == 1) {
            textField1.setText("0");
            equnum = 0;
        }
        //Press 0
        if (e.getSource().equals(button0)) {
            str = textField1.getText();
            if (str.length() > 16 || str.equals("0") || equalbook == 1) {

            } else {
                textField1.setText(str + "0");
            }
        }
        //Press 1
        if (e.getSource().equals(button1)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {

            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("1");
            } else {
                textField1.setText(str + "1");
            }
        }
        //When the button is 2
        if (e.getSource().equals(button2)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("2");
            } else {
                textField1.setText(str + "2");
            }
        }
        //When the button is 3
        if (e.getSource().equals(button3)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("3");
            } else {
                textField1.setText(str + "3");
            }
        }
        //When the button is 4
        if (e.getSource().equals(button4)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("4");
            } else {
                textField1.setText(str + "4");
            }
        }
        //When the button is 5
        if (e.getSource().equals(button5)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("5");
            } else {
                textField1.setText(str + "5");
            }
        }
        //When the button is 6
        if (e.getSource().equals(button6)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("6");
            } else {
                textField1.setText(str + "6");
            }
        }
        //When the button is 7
        if (e.getSource().equals(button7)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("7");
            } else {
                textField1.setText(str + "7");
            }
        }
        //When the button is 8
        if (e.getSource().equals(button8)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("8");
            } else {
                textField1.setText(str + "8");
            }
        }
        //When the button is 9
        if (e.getSource().equals(button9)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("9");
            } else {
                textField1.setText(str + "9");
            }
        }
        //When the button is a decimal point
        if (e.getSource().equals(buttonPoint)) {
            str = textField1.getText();
            if (str.length() > 15 || equalbook == 1) {                   //The decimal point is in the last digit of the operand, and the operation is not performed;
            }
            if (pointbook == 0) {                                    //An operand can only have one decimal point. If there is already a decimal point, no decimal point will be added;
                textField1.setText(str + ".");
                pointbook = 1;                                    //Decimal point judgment position 1;
            }
        }
        //Each input is a number + operator, which is transferred from the number text box to the expression text box;
        //When the button is a plus sign
        if (e.getSource().equals(buttonAdd)) {
            str = textField1.getText();                              //Gets the previous operand of the operator;
            char ch1[] = str.toCharArray();                        //Assigning the first operand together with the + sign to ch1 for the operation of converting a string to a character array;
            int length1 = str.length() - 1;                        //length1 obtains the number of bits of the first operand other than the + sign;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
                //When the number is empty or 0 (the operation is meaningless); or the last digit of the number is the decimal point (wait if the input is not completed or the input is wrong)
            } else {
                textField1.setText(str + "+");   //Merge existing and new expressions
                // Here we explain why s did not extract the symbols in the number box, because the number box is not updated when entering symbols, but directly performs a series of operations, and the number box has never appeared an operator;
            }
            pointbook = 0;
        }
        //When the button is minus
        if (e.getSource().equals(buttonSub)) {
            str = textField1.getText();
            char ch1[] = str.toCharArray();
            int length1 = str.length() - 1;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
            } else {
                textField1.setText(str + "-");
            }
            pointbook = 0;
        }
        //When the button is a multiplier
        if (e.getSource().equals(buttonMul)) {
            str = textField1.getText();
            char ch1[] = str.toCharArray();
            int length1 = str.length() - 1;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
            } else {
                textField1.setText(str + "*");
            }
            pointbook = 0;
        }
        //When the button is division
        if (e.getSource().equals(buttonDiv)) {
            str = textField1.getText();
            char ch1[] = str.toCharArray();
            int length1 = str.length() - 1;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
            } else {
                textField1.setText(str + "/");
            }
            pointbook = 0;
        }
        //When the button is left parenthesis
        if (e.getSource().equals(buttonzuo)) {
            str = textField1.getText();
            char ch[] = str.toCharArray();
            int length = str.length() - 1;
            if (length == -1 || ch[length] == '+' || ch[length] == '-' || ch[length] == '*' || ch[length] == '/') {
                //Judgment on whether there are several or symbol categories on the left of the bracket;
                textField1.setText(str + '(');     //If the conditions are met, add the left parenthesis;
                zuonum++;                                            //Add one mark to the number of left parentheses;
            }
            if (length == -1 || ch[length] == '+' || ch[length] == '-' || ch[length] == '*' || ch[length] == '/')
                pointbook = 0;
            if (length == 0 || ch[length] == 0) {
                textField1.setText("(");
                zuonum++;
            }
        }
        //When the button is a right parenthesis;
        if (e.getSource().equals(buttonyou)) {
            str = textField1.getText();
            char ch[] = str.toCharArray();
            int length = str.length() - 1;
            if (Character.isDigit(ch[length]) && zuonum > younum) {      //The right parenthesis can be added only when the front is a number and the number of left parentheses is greater than the number of right parentheses;
                younum++;                                                 //Add one mark to the number of right parentheses;
                textField1.setText(str + ')');
            }
            pointbook = 0;
        }
        //When the C key is pressed;
        if (e.getSource().equals(buttonC)) {
            textField1.setText("0");                  //Set the current digital box to 0;
            zuonum = 0;                              //After a calculation is completed, a new calculation can be carried out only by pressing the CE button, because all flag bits should be cleared, otherwise the next operation will be affected;
            younum = 0;
            pointbook = 0;
            equalbook = 0;
            textField2.setText(" ");
        }
        //When the button is CE,
        if (e.getSource().equals(buttonCE)) {
            textField1.setText("0");                       //Clear the contents of the current digital box;
            pointbook = 0;                                 //Update decimal point status to 0;
        }
        //When B is pressed,
        if (e.getSource().equals(buttondele)) {
            str = textField1.getText();
            char []nums=str.toCharArray();
            if (nums[str.length()-1]=='('){
                zuonum--;
            }
            str = str.substring(0, str.length() - 1);
            textField1.setText(str);
        }
        //When = is pressed,
        if (e.getSource().equals(buttonequl)) {
            str = textField1.getText();
            if (zuonum != younum) {
                textField1.setText("Relational error.");
            } else {
                ans(str);
            }
            String s = str + "=" + textField1.getText();
            textField2.setText(s + "\r\n" + textField2.getText());                //Store expressions in history.
            equnum = 1;
        }
    }

 2. Infix expression changes to suffix expression, and the priority of the symbol is defined first.

/**
     * Define the priority of symbols in advance
     */
    private static final Map<Character, Integer> basic = new HashMap<Character, Integer>();

    static {
        basic.put('-', 1);
        basic.put('+', 1);
        basic.put('*', 2);
        basic.put('/', 2);
        basic.put('(', 0);//The priority of () is the highest in the operation, but it is set to 0 because it is required in the program
    }



    /**
     * Convert infix expression to suffix expression
     */
    public String toSuffix(String infix) {
        List<String> queue = new ArrayList<String>();                                    //Defines the queue used to store numbers and the last suffix expression
        List<Character> stack = new ArrayList<Character>();                             //Defines the stack used to store operators. The last stack will be empty

        char[] charArr = infix.trim().toCharArray();                                    //Character arrays are used to split numbers or symbols
        String standard = "*/+-()";                                                        //Criteria: write out the operators that will appear in the expression
        char ch = '&';                                                                    //In the loop, the current loop variable used to save the character array is just initializing a value, which is meaningless
        int len = 0;                                                                    //Used to record the character length [for example, 100 * 2, then the recorded len is 3, and the first three digits of the intercepted string will be numbers]
        for (int i = 0; i < charArr.length; i++) {                                        //Start iteration

            ch = charArr[i];                                                            //Save current iteration variables
            if (Character.isDigit(ch)) {                                                    //If the current variable is a number
                len++;
            } else if (Character.isLetter(ch)) {                                            //If the current variable is a letter
                len++;
            } else if (ch == '.') {                                                        //If the current variable is Will appear in decimals
                len++;
            } else if (Character.isSpaceChar(ch)) {                                        //If the current variable is a space, spaces in the expression are supported
                if (len > 0) {                                                            //If a space represents the end of a period, it can be stored in the queue [for example, if there is a space after 100 * 2 100, it can be stored in the queue before the space]
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //Store the intercepted string into the queue
                    len = 0;                                                            //Length null
                }
                continue;                                                                //If a space appears, the end of a paragraph will jump out of this cycle
            } else if (standard.indexOf(ch) != -1) {                                        //If it is any symbol in the above standard
                if (len > 0) {                                                            //The length also has
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //Before the description symbol, it can be intercepted as a number
                    len = 0;                                                            //Length null
                }
                if (ch == '(') {                                                            //If left parenthesis
                    stack.add(ch);                                                        //Put the left bracket on the stack
                    continue;                                                            //Jump out of this cycle and continue to find the next position
                }
                if (!stack.isEmpty()) {                                                    //If the stack is not empty
                    int size = stack.size() - 1;                                        //Get the size of the stack - 1, which represents the subscript of the last element of the stack
                    boolean flag = false;                                                //Set flag bit
                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {            //If the current ch is a right parenthesis, the elements in the stack pop up from the top of the stack until they pop up to the left parenthesis
                        queue.add(String.valueOf(stack.remove(size)));                    //Note the condition here: ch is not stacked, so it is not inserted into the queue; Similarly, until the left bracket is found, the loop ends, so the left bracket will not be put in the queue [that is, there will be no bracket in the suffix expression]
                        size--;                                                            //size -- ensure that the subscript is always at the last element of the stack [stack concept: the pointer always refers to the element at the top of the stack]
                        flag = true;                                                    //Setting the flag bit to true indicates that the element in () has been fetched
                    }
                    while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {    //If you get an element that is not in () and the priority of the current top element is > = the comparison element, you will get out of the stack and insert it into the queue
                        queue.add(String.valueOf(stack.remove(size)));                    //Similarly, here is the remove() method, which can not only get the elements to be obtained, but also remove the elements from the stack
                        size--;
                    }
                }
                if (ch != ')') {                                                            //If the current element is not a closing bracket
                    stack.add(ch);                                                        //It is necessary to ensure that this symbol is put on the stack
                } else {                                                                //Otherwise, the symbols in the stack will be released
                    stack.remove(stack.size() - 1);
                }
            }
            if (i == charArr.length - 1) {                                                //If you have reached the last bit of infix expression
                if (len > 0) {                                                            //If len > 0, intercept the number
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len + 1, i + 1)));
                }
                int size = stack.size() - 1;                                            //size indicates the subscript of the last element in the stack
                while (size >= 0) {                                                        //Keep all the symbols in the stack out of the stack and added to the queue [the final suffix expression is stored in the queue, and the stack will be empty at last]
                    queue.add(String.valueOf(stack.remove(size)));
                    size--;
                }
            }

        }
        return queue.stream().collect(Collectors.joining(","));                            //Splits the elements in the queue and returns a string
    }

Then calculate the suffix expression.

/**
     * Operate the suffix expression to calculate the result
     *
     * @param equation
     * @return
     */
    public String dealEquation(String equation) {
        String[] arr = equation.split(",");                                    //Split strings according to
        List<String> list = new ArrayList<String>();                            //It is used to store the set of operation procedures during calculation [for example, if 100 20 5 is currently placed in the list, take out 20 / 5 and finally store the result 4 in the list. At this time, the result in the list is 100 4]


        for (int i = 0; i < arr.length; i++) {                                    //Here is the operation process mentioned above, because list Because of remove, the last number is taken out, and the last two numbers are both size-2
            int size = list.size();
            switch (arr[i]) {
                case "+":
                    double a = Double.parseDouble(list.remove(size - 2)) + Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(a));
                    break;
                case "-":
                    double b = Double.parseDouble(list.remove(size - 2)) - Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(b));
                    break;
                case "*":
                    double c = Double.parseDouble(list.remove(size - 2)) * Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(c));
                    break;
                case "/":
                    double d = Double.parseDouble(list.remove(size - 2)) / Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(d));
                    break;
                default:
                    list.add(arr[i]);
                    break;                                    //If it is a number, put it directly into the list
            }
        }
        return list.size() == 1 ? list.get(0) : "Operation failed";                    //There is only one result in the final list, otherwise it is wrong
    }

Display the calculation results on the calculator

    public void ans(String str) {
        String a = toSuffix(str);//Pass in a string of arithmetic formulas
        textField1.setText(dealEquation(a));

    }

All codes

package Calculator;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.stream.Collectors;


public class Calculator extends JFrame implements ActionListener {
    Calculator() {
        init();
    }

    /**
     * Define button
     */
    private JTextField textField1;
    private JTextArea textField2;
    private JButton buttonzuo;//(
    private JButton buttonyou;//)
    private JButton buttonC;//c
    private JButton buttonCE;//CE
    private JButton buttondele;//< - delete
    private JButton buttonDiv;//÷
    private JButton button7;//7
    private JButton button8;//8
    private JButton button9;//9
    private JButton buttonAdd;//+
    private JButton button4;//4
    private JButton button5;//5
    private JButton button6;//6
    private JButton buttonSub;//-
    private JButton button1;//1
    private JButton button2;//2
    private JButton button3;//3
    private JButton buttonMul;//x
    private JButton buttonequl;//=
    private JButton button0;//0
    private JButton buttonPoint;//.

    public void init() {
        JFrame frame = new JFrame("The Calculator Of Czf");                  //Create a top-level container with the title "calculator" in a normal window;
        frame.setLayout(null);                                                   //Set to use a specific layout manager;
        //Radio button
        //The layout and design of keys need to consider the overall layout rationality in advance, and no key overlap is allowed; In order to ensure beauty, it is necessary to consider neat typesetting;
        //Place number 0
        button0 = new JButton("0");                                         //Note: when naming the keys, it should be based on the size of the keys, otherwise the marks on the keys cannot be fully displayed;
        button0.setBounds(100, 400, 110, 50);
        frame.add(button0);
        //Place number 1
        button1 = new JButton("1");
        button1.setBounds(40, 340, 50, 50);
        frame.add(button1);
        //Place number 2
        button2 = new JButton("2");
        button2.setBounds(100, 340, 50, 50);
        frame.add(button2);
        //Place number 3
        button3 = new JButton("3");
        button3.setBounds(160, 340, 50, 50);
        frame.add(button3);
        //Place number 4
        button4 = new JButton("4");
        button4.setBounds(40, 280, 50, 50);
        frame.add(button4);
        //Place number 5
        button5 = new JButton("5");
        button5.setBounds(100, 280, 50, 50);
        frame.add(button5);
        //Place number 6
        button6 = new JButton("6");
        button6.setBounds(160, 280, 50, 50);
        frame.add(button6);
        //Place number 7
        button7 = new JButton("7");
        button7.setBounds(40, 220, 50, 50);
        frame.add(button7);
        //Place number 8
        button8 = new JButton("8");
        button8.setBounds(100, 220, 50, 50);
        frame.add(button8);
        //Place number 9
        button9 = new JButton("9");
        button9.setBounds(160, 220, 50, 50);
        frame.add(button9);
        //place.
        buttonPoint = new JButton(".");                                                   //text: is the explanatory word of the automatically generated parameter
        buttonPoint.setBounds(40, 400, 50, 50);                            //Parameter interpreter for automatic complement
        frame.add(buttonPoint);
        //Place+
        buttonAdd = new JButton("+");
        buttonAdd.setBounds(220, 400, 50, 50);
        frame.add(buttonAdd);
        //Place-
        buttonSub = new JButton("-");
        buttonSub.setBounds(220, 340, 50, 50);
        frame.add(buttonSub);
        //Place*
        buttonMul = new JButton("*");
        buttonMul.setBounds(220, 280, 50, 50);
        frame.add(buttonMul);
        //Place/
        buttonDiv = new JButton("/");
        buttonDiv.setBounds(220, 220, 50, 50);
        frame.add(buttonDiv);
        //Place=
        buttonequl = new JButton("=");
        buttonequl.setBounds(280, 340, 110, 110);
        frame.add(buttonequl);
        //Abdication key
        buttondele = new JButton("B");
        buttondele.setBounds(280, 220, 110, 110);
        frame.add(buttondele);
        //Place left parenthesis(
        buttonzuo = new JButton("(");
        buttonzuo.setBounds(40, 160, 80, 50);
        frame.add(buttonzuo);
        //Place right parenthesis)
        buttonyou = new JButton(")");
        buttonyou.setBounds(130, 160, 80, 50);
        frame.add(buttonyou);
        //Place C to eliminate all inputs
        buttonC = new JButton("C");
        buttonC.setBounds(220, 160, 80, 50);
        frame.add(buttonC);
        //Place CE to eliminate the current input
        buttonCE = new JButton("CE");
        buttonCE.setBounds(310, 160, 80, 50);
        frame.add(buttonCE);
        //Add an expression text box to enter a calculation formula
        textField1 = new JTextField();           //Text box
        textField1.setBounds(40, 20, 350, 60);
        frame.add(textField1);
        textField2 = new JTextArea();
        textField2.setBounds(400, 20, 280, 430);
        frame.add(textField2);


        textField1.addActionListener(this);
        buttonzuo.addActionListener(this);
        buttonyou.addActionListener(this);
        buttonC.addActionListener(this);
        buttonCE.addActionListener(this);
        buttondele.addActionListener(this);
        buttonDiv.addActionListener(this);
        button7.addActionListener(this);
        button8.addActionListener(this);
        button9.addActionListener(this);
        buttonAdd.addActionListener(this);
        button4.addActionListener(this);
        button5.addActionListener(this);
        button6.addActionListener(this);
        buttonSub.addActionListener(this);
        button1.addActionListener(this);
        button2.addActionListener(this);
        button3.addActionListener(this);
        buttonMul.addActionListener(this);
        buttonequl.addActionListener(this);
        button0.addActionListener(this);
        buttonPoint.addActionListener(this);

        frame.setBounds(0, 0, 700, 520);       //Set the size of the entire graphics window; (called by window name)
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE). Click the close button of the window to exit the program (without this sentence, the program will not exit)
        frame.setVisible(true);
    }

    String str = null;
    int pointbook = 0;
    int equalbook = 0;
    int zuonum = 0;
    int younum = 0;
    int equnum = 0;


    public void actionPerformed(ActionEvent e) {
        if (equnum == 1) {
            textField1.setText("0");
            equnum = 0;
        }
        //Press 0
        if (e.getSource().equals(button0)) {
            str = textField1.getText();
            if (str.length() > 16 || str.equals("0") || equalbook == 1) {

            } else {
                textField1.setText(str + "0");
            }
        }
        //Press 1
        if (e.getSource().equals(button1)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {

            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("1");
            } else {
                textField1.setText(str + "1");
            }
        }
        //When the button is 2
        if (e.getSource().equals(button2)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("2");
            } else {
                textField1.setText(str + "2");
            }
        }
        //When the button is 3
        if (e.getSource().equals(button3)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("3");
            } else {
                textField1.setText(str + "3");
            }
        }
        //When the button is 4
        if (e.getSource().equals(button4)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("4");
            } else {
                textField1.setText(str + "4");
            }
        }
        //When the button is 5
        if (e.getSource().equals(button5)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("5");
            } else {
                textField1.setText(str + "5");
            }
        }
        //When the button is 6
        if (e.getSource().equals(button6)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("6");
            } else {
                textField1.setText(str + "6");
            }
        }
        //When the button is 7
        if (e.getSource().equals(button7)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("7");
            } else {
                textField1.setText(str + "7");
            }
        }
        //When the button is 8
        if (e.getSource().equals(button8)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("8");
            } else {
                textField1.setText(str + "8");
            }
        }
        //When the button is 9
        if (e.getSource().equals(button9)) {
            str = textField1.getText();
            if (str.length() > 16 || equalbook == 1) {
            } else if (str.equals("0") || str.equals("")) {
                textField1.setText("9");
            } else {
                textField1.setText(str + "9");
            }
        }
        //When the button is a decimal point
        if (e.getSource().equals(buttonPoint)) {
            str = textField1.getText();
            if (str.length() > 15 || equalbook == 1) {                   //The decimal point is in the last digit of the operand, and the operation is not performed;
            }
            if (pointbook == 0) {                                    //An operand can only have one decimal point. If there is already a decimal point, no decimal point will be added;
                textField1.setText(str + ".");
                pointbook = 1;                                    //Decimal point judgment position 1;
            }
        }
        //Each input is a number + operator, which is transferred from the number text box to the expression text box;
        //When the button is a plus sign
        if (e.getSource().equals(buttonAdd)) {
            str = textField1.getText();                              //Gets the previous operand of the operator;
            char ch1[] = str.toCharArray();                        //Assigning the first operand together with the + sign to ch1 for the operation of converting a string to a character array;
            int length1 = str.length() - 1;                        //length1 obtains the number of bits of the first operand other than the + sign;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
                //When the number is empty or 0 (the operation is meaningless); or the last digit of the number is the decimal point (wait if the input is not completed or the input is wrong)
            } else {
                textField1.setText(str + "+");   //Merge existing and new expressions
                // Here we explain why s did not extract the symbols in the number box, because the number box is not updated when entering symbols, but directly performs a series of operations, and the number box has never appeared an operator;
            }
            pointbook = 0;
        }
        //When the button is minus
        if (e.getSource().equals(buttonSub)) {
            str = textField1.getText();
            char ch1[] = str.toCharArray();
            int length1 = str.length() - 1;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
            } else {
                textField1.setText(str + "-");
            }
            pointbook = 0;
        }
        //When the button is a multiplier
        if (e.getSource().equals(buttonMul)) {
            str = textField1.getText();
            char ch1[] = str.toCharArray();
            int length1 = str.length() - 1;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
            } else {
                textField1.setText(str + "*");
            }
            pointbook = 0;
        }
        //When the button is division
        if (e.getSource().equals(buttonDiv)) {
            str = textField1.getText();
            char ch1[] = str.toCharArray();
            int length1 = str.length() - 1;
            if ((length1 == -1 || ch1[length1] != ')') && (str.equals("0") || str.equals("") || ch1[length1] == '.' || ch1[length1] == '+' || ch1[length1] == '-' || ch1[length1] == '*' || ch1[length1] == '/' || ch1[length1] == '(' || ch1[length1] == ')')) {
            } else {
                textField1.setText(str + "/");
            }
            pointbook = 0;
        }
        //When the button is left parenthesis
        if (e.getSource().equals(buttonzuo)) {
            str = textField1.getText();
            char ch[] = str.toCharArray();
            int length = str.length() - 1;
            if (length == -1 || ch[length] == '+' || ch[length] == '-' || ch[length] == '*' || ch[length] == '/') {
                //Judgment on whether there are several or symbol categories on the left of the bracket;
                textField1.setText(str + '(');     //If the conditions are met, add the left parenthesis;
                zuonum++;                                            //Add one mark to the number of left parentheses;
            }
            if (length == -1 || ch[length] == '+' || ch[length] == '-' || ch[length] == '*' || ch[length] == '/')
                pointbook = 0;
            if (length == 0 || ch[length] == 0) {
                textField1.setText("(");
                zuonum++;
            }
        }
        //When the button is a right parenthesis;
        if (e.getSource().equals(buttonyou)) {
            str = textField1.getText();
            char ch[] = str.toCharArray();
            int length = str.length() - 1;
            if (Character.isDigit(ch[length]) && zuonum > younum) {      //The right parenthesis can be added only when the front is a number and the number of left parentheses is greater than the number of right parentheses;
                younum++;                                                 //Add one mark to the number of right parentheses;
                textField1.setText(str + ')');
            }
            pointbook = 0;
        }
        //When the C key is pressed;
        if (e.getSource().equals(buttonC)) {
            textField1.setText("0");                  //Set the current digital box to 0;
            zuonum = 0;                              //After a calculation is completed, a new calculation can be carried out only by pressing the CE button, because all flag bits should be cleared, otherwise the next operation will be affected;
            younum = 0;
            pointbook = 0;
            equalbook = 0;
            textField2.setText(" ");
        }
        //When the button is CE,
        if (e.getSource().equals(buttonCE)) {
            textField1.setText("0");                       //Clear the contents of the current digital box;
            pointbook = 0;                                 //Update decimal point status to 0;
        }
        //When B is pressed,
        if (e.getSource().equals(buttondele)) {
            str = textField1.getText();
            char []nums=str.toCharArray();
            if (nums[str.length()-1]=='('){
                zuonum--;
            }
            str = str.substring(0, str.length() - 1);
            textField1.setText(str);
        }
        //When = is pressed,
        if (e.getSource().equals(buttonequl)) {
            str = textField1.getText();
            if (zuonum != younum) {
                textField1.setText("Relational error.");
            } else {
                ans(str);
            }
            String s = str + "=" + textField1.getText();
            textField2.setText(s + "\r\n" + textField2.getText());                //Store expressions in history.
            equnum = 1;
        }
    }


    /**
     * Define the priority of symbols in advance
     */
    private static final Map<Character, Integer> basic = new HashMap<Character, Integer>();

    static {
        basic.put('-', 1);
        basic.put('+', 1);
        basic.put('*', 2);
        basic.put('/', 2);
        basic.put('(', 0);//The priority of () is the highest in the operation, but it is set to 0 because it is required in the program
    }


    public void ans(String str) {
        String a = toSuffix(str);//Pass in a string of arithmetic formulas
        textField1.setText(dealEquation(a));

    }

    /**
     * Convert infix expression to suffix expression
     */
    public String toSuffix(String infix) {
        List<String> queue = new ArrayList<String>();                                    //Defines the queue used to store numbers and the last suffix expression
        List<Character> stack = new ArrayList<Character>();                             //Defines the stack used to store operators. The last stack will be empty

        char[] charArr = infix.trim().toCharArray();                                    //Character arrays are used to split numbers or symbols
        String standard = "*/+-()";                                                        //Criteria: write out the operators that will appear in the expression
        char ch = '&';                                                                    //In the loop, the current loop variable used to save the character array is just initializing a value, which is meaningless
        int len = 0;                                                                    //Used to record the character length [for example, 100 * 2, then the recorded len is 3, and the first three digits of the intercepted string will be numbers]
        for (int i = 0; i < charArr.length; i++) {                                        //Start iteration

            ch = charArr[i];                                                            //Save current iteration variables
            if (Character.isDigit(ch)) {                                                    //If the current variable is a number
                len++;
            } else if (Character.isLetter(ch)) {                                            //If the current variable is a letter
                len++;
            } else if (ch == '.') {                                                        //If the current variable is Will appear in decimals
                len++;
            } else if (Character.isSpaceChar(ch)) {                                        //If the current variable is a space, spaces in the expression are supported
                if (len > 0) {                                                            //If a space represents the end of a period, it can be stored in the queue [for example, if there is a space after 100 * 2 100, it can be stored in the queue before the space]
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //Store the intercepted string into the queue
                    len = 0;                                                            //Length null
                }
                continue;                                                                //If a space appears, the end of a paragraph will jump out of this cycle
            } else if (standard.indexOf(ch) != -1) {                                        //If it is any symbol in the above standard
                if (len > 0) {                                                            //The length also has
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //Before the description symbol, it can be intercepted as a number
                    len = 0;                                                            //Length null
                }
                if (ch == '(') {                                                            //If left parenthesis
                    stack.add(ch);                                                        //Put the left bracket on the stack
                    continue;                                                            //Jump out of this cycle and continue to find the next position
                }
                if (!stack.isEmpty()) {                                                    //If the stack is not empty
                    int size = stack.size() - 1;                                        //Get the size of the stack - 1, which represents the subscript of the last element of the stack
                    boolean flag = false;                                                //Set flag bit
                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {            //If the current ch is a right parenthesis, the elements in the stack pop up from the top of the stack until they pop up to the left parenthesis
                        queue.add(String.valueOf(stack.remove(size)));                    //Note the condition here: ch is not stacked, so it is not inserted into the queue; Similarly, until the left bracket is found, the loop ends, so the left bracket will not be put in the queue [that is, there will be no bracket in the suffix expression]
                        size--;                                                            //size -- ensure that the subscript is always at the last element of the stack [stack concept: the pointer always refers to the element at the top of the stack]
                        flag = true;                                                    //Setting the flag bit to true indicates that the element in () has been fetched
                    }
                    while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {    //If you get an element that is not in () and the priority of the current top element is > = the comparison element, you will get out of the stack and insert it into the queue
                        queue.add(String.valueOf(stack.remove(size)));                    //Similarly, here is the remove() method, which can not only get the elements to be obtained, but also remove the elements from the stack
                        size--;
                    }
                }
                if (ch != ')') {                                                            //If the current element is not a closing bracket
                    stack.add(ch);                                                        //It is necessary to ensure that this symbol is put on the stack
                } else {                                                                //Otherwise, the symbols in the stack will be released
                    stack.remove(stack.size() - 1);
                }
            }
            if (i == charArr.length - 1) {                                                //If you have reached the last bit of infix expression
                if (len > 0) {                                                            //If len > 0, intercept the number
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len + 1, i + 1)));
                }
                int size = stack.size() - 1;                                            //size indicates the subscript of the last element in the stack
                while (size >= 0) {                                                        //Keep all the symbols in the stack out of the stack and added to the queue [the final suffix expression is stored in the queue, and the stack will be empty at last]
                    queue.add(String.valueOf(stack.remove(size)));
                    size--;
                }
            }

        }
        return queue.stream().collect(Collectors.joining(","));                            //Splits the elements in the queue and returns a string
    }


    /**
     * Operate the suffix expression to calculate the result
     *
     * @param equation
     * @return
     */
    public String dealEquation(String equation) {
        String[] arr = equation.split(",");                                    //Split strings according to
        List<String> list = new ArrayList<String>();                            //It is used to store the set of operation procedures during calculation [for example, if 100 20 5 is currently placed in the list, take out 20 / 5 and finally store the result 4 in the list. At this time, the result in the list is 100 4]


        for (int i = 0; i < arr.length; i++) {                                    //Here is the operation process mentioned above, because list Because of remove, the last number is taken out, and the last two numbers are both size-2
            int size = list.size();
            switch (arr[i]) {
                case "+":
                    double a = Double.parseDouble(list.remove(size - 2)) + Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(a));
                    break;
                case "-":
                    double b = Double.parseDouble(list.remove(size - 2)) - Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(b));
                    break;
                case "*":
                    double c = Double.parseDouble(list.remove(size - 2)) * Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(c));
                    break;
                case "/":
                    double d = Double.parseDouble(list.remove(size - 2)) / Double.parseDouble(list.remove(size - 2));
                    list.add(String.valueOf(d));
                    break;
                default:
                    list.add(arr[i]);
                    break;                                    //If it is a number, put it directly into the list
            }
        }
        return list.size() == 1 ? list.get(0) : "Operation failed";                    //There is only one result in the final list, otherwise it is wrong
    }

    public static void main(String[] args) {
        Calculator calculator = new Calculator();
    }
}

Operation results

Blog reference template: Design of GUI Graphical interface calculator based on JAVA 2020-12-03_ Evening breeze Czf blog CSDN blog_ JAVA GUI interface design calculator

Infix variable suffix: [java] infix expression to suffix expression java implementation - Angel squeeze - blog Park

   

Keywords: Java

Added by gofeddy on Sat, 01 Jan 2022 06:23:59 +0200