24點撲克牌游戲——(含java源碼)(GUI實現)


給出四個數字,要求,在其間添加運算符和括號,使得計算結果等於24

 

括號的放置即為決定哪幾個數先進行計算。所以,我們先確定首先進行計算的兩個相鄰的數,計算完成后,就相當於剩下三個數字,仍需要在它們之間添加符號;然后再決定在這三個數中哪兩個相鄰的數先計算。由此,我們就成功解決了數字的運算次序問題,此時不需要再考慮不同運算符號的優先級問題,因為括號的優先級高於加減乘除。

通過循環,我們可以得到第一第二第三次計算的運算符,再通過計算,就可以得出和,若和等於24,即為所求解。

 

在輸出格式中,由於括號的放置共六種情況,故根據計算先后順序的不同,輸出時在不同地方放置括號;

 

以下是java源碼:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.JOptionPane;

public class  TwentyFourPoke_Game extends JFrame
{
	private JButton jbsolution = new JButton("Find a Solution");
	private JButton jbrefresh = new JButton("Refresh");
	private JButton jbverify = new JButton("Verify");

	private JLabel jlmessage = new JLabel("Enter an expression:");

	private JTextField jtsolution = new JTextField();
	private JTextField jtexpression = new JTextField();

	private ImagePanel pp = new ImagePanel();

	private int[] card = new int[4];
	private double[] bcard = new double[4];

	private double sum;
	private double[] temp1 = new double[3];
	private double[] temp2 = new double[2];
	private char[] sign = {'+','-','*','/'};


	public TwentyFourPoke_Game()
	{
		JPanel p1 = new JPanel(new GridLayout(1,3));
		p1.add(jbsolution);
		p1.add(jtsolution);
		p1.add(jbrefresh);
		JPanel p3 = new JPanel(new GridLayout(1,3));
		p3.add(jlmessage);
		p3.add(jtexpression);
		p3.add(jbverify);
		
		add(p1,BorderLayout.NORTH);
		add(pp,BorderLayout.CENTER);
		add(p3,BorderLayout.SOUTH);

		ButtonListener listener = new ButtonListener();
		jbsolution.addActionListener(listener);
		jbrefresh.addActionListener(listener);
		jbverify.addActionListener(listener);
	}

	class ButtonListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			if(e.getSource() == jbsolution)
			{
				for(int i = 0;i < 4;i++)
				{
					bcard[i] = (double)card[i] % 13;
					if(card[i] % 13 == 0)
						bcard[i] = 13;
				}
				search();
			}
			else if(e.getSource() == jbrefresh)
			{
				pp.sshow();

			}
			else if(e.getSource() == jbverify)
			{
				String expression = jtexpression.getText();
				int result = evaluateExpression(expression);
				if(result == 24)
				{
					JOptionPane.showMessageDialog(null,"恭喜你!你答對了!","消息框",JOptionPane.INFORMATION_MESSAGE);
				}
				else
				{
					JOptionPane.showMessageDialog(null,"抱歉!請再次嘗試。","消息框",JOptionPane.INFORMATION_MESSAGE);
				}
			}
		}
	}

	public static double calcute(double a,double b,char c)
	{
		if(c == '+')
			return a+b;
		else if(c == '-')
			return  a-b;
		else if(c == '*')
			return a*b;
		else if(c == '/' && b != 0)
			return a/b;
		else
			return -1;
	}

	public  void search()
	{
		boolean judge = false;
		for(int i=0;i<4;i++)
		//第一次放置的符號
		{
			for(int j=0;j<4;j++)
			//第二次放置的符號
			{
				for(int k=0;k<4;k++)
				//第三次放置的符號
				{
					for(int m=0;m<3;m++)
					//首先計算的兩個相鄰數字,共有3種情況,相當於括號的作用
					{
						if(bcard[m+1]==0 && sign[i]=='/') break;
						temp1[m]=calcute(bcard[m],bcard[m+1],sign[i]);
						temp1[(m+1)%3]=bcard[(m+2)%4];
						temp1[(m+2)%3]=bcard[(m+3)%4];
						//先確定首先計算的兩個數字,計算完成相當於剩下三個數,按順序儲存在temp數組中
						for(int n=0;n<2;n++)
						//三個數字選出先計算的兩個相鄰數字,兩種情況,相當於第二個括號
						{
							if(temp1[n+1]==0 && sign[j]=='/') break;
							temp2[n]=calcute(temp1[n],temp1[n+1],sign[j]);
							temp2[(n+1)%2]=temp1[(n+2)%3];
							//先確定首先計算的兩個數字,計算完成相當於剩下兩個數,按順序儲存在temp數組中
							if(temp2[1]==0 && sign[k]=='/') break;
							sum=calcute(temp2[0],temp2[1],sign[k]);
							//計算和
							if(sum==24) 
							//若和為24
							{
								judge=true;
								//判斷符為1,表示已求得解
									if(m==0 && n==0) 
									{
										String sss ="(("+(int)bcard[0]+sign[i]+(int)bcard[1]+")"+sign[j]+(int)bcard[2]+")"+sign[k]+(int)bcard[3]+"="+(int)sum;
										jtsolution.setText(sss);
										return ;
									}
									else if(m==0 && n==1)
									{
										String sss ="("+(int)bcard[0]+sign[i]+(int)bcard[1]+")"+sign[k]+"("+(int)bcard[2]+sign[j]+(int)bcard[3]+")="+(int)sum;
										jtsolution.setText(sss);
										return ;
									}
									else if(m==1 && n==0)
									{
										String sss ="("+(int)bcard[0]+sign[j]+"("+(int)bcard[1]+sign[i]+(int)bcard[2]+"))"+sign[k]+(int)bcard[3]+"="+(int)sum;
										jtsolution.setText(sss);
										return ;
									}
									else if(m==2 && n==0)
									{
										String sss ="("+(int)bcard[0]+sign[j]+(int)bcard[1]+")"+sign[k]+"("+(int)bcard[2]+sign[i]+(int)bcard[3]+")="+(int)sum;
										jtsolution.setText(sss);
										return ;
									}
									else if(m==2 && n==0)
									{
										String sss =(int)bcard[0]+sign[k]+"("+(int)bcard[1]+sign[j]+"("+(int)bcard[2]+sign[i]+(int)bcard[3]+"))="+(int)sum;
										jtsolution.setText(sss);
										return ;
									}
										//m=0,1,2 n=0,1表示六種括號放置可能,並按照這六種可能輸出相應的格式的計算式
								
							}
						}
					}
				}
			}
		}
		if(judge==false) 
			jtsolution.setText("No solution!");
		//如果沒有找到結果,符號位為0
	}


	public static int evaluateExpression(String expression)
	{
		// Create operandStack to store operands
		java.util.Stack<Integer> operandStack = new java.util.Stack<Integer>();

		// Create operatorStack to store operators
		java.util.Stack<Character> operatorStack = new java.util.Stack<Character>();

		// Extract operands and operators
		java.util.StringTokenizer tokens = new java.util.StringTokenizer(expression, "()+-/*", true);

		// Phase 1: Scan tokens
		while (tokens.hasMoreTokens()) 
		{
			String token = tokens.nextToken().trim(); // Extract a token
			if (token.length() == 0) // Blank space
				continue; // Back to the while loop to extract the next token
			else if (token.charAt(0) == '+' || token.charAt(0) == '-') 
			{
				// Process all +, -, *, / in the top of the operator stack
				while (!operatorStack.isEmpty() &&(operatorStack.peek().equals('+') ||operatorStack.peek().equals('-') || operatorStack.peek().equals('*') ||
           operatorStack.peek().equals('/')))
				{
					processAnOperator(operandStack, operatorStack);
				}
				// Push the + or - operator into the operator stack
				operatorStack.push(new Character(token.charAt(0)));
			}
			else if (token.charAt(0) == '*' || token.charAt(0) == '/')
			{
				// Process all *, / in the top of the operator stack
				while (!operatorStack.isEmpty() && (operatorStack.peek().equals('*') || operatorStack.peek().equals('/')))
				{
					processAnOperator(operandStack, operatorStack);
				}

				// Push the * or / operator into the operator stack
				operatorStack.push(new Character(token.charAt(0)));
			}
			else if (token.trim().charAt(0) == '(')
			{
				operatorStack.push(new Character('(')); // Push '(' to stack
			}
			else if (token.trim().charAt(0) == ')') 
			{
				// Process all the operators in the stack until seeing '('
				while (!operatorStack.peek().equals('(')) 
				{
					 processAnOperator(operandStack, operatorStack);
				}
				operatorStack.pop(); // Pop the '(' symbol from the stack
			}
			else 
			{ 
				// An operand scanned
				// Push an operand to the stack
				operandStack.push(new Integer(token));
			}
		}

		// Phase 2: process all the remaining operators in the stack
		while (!operatorStack.isEmpty()) 
		{
			processAnOperator(operandStack, operatorStack);
		}

		// Return the result
		return ((Integer)(operandStack.pop())).intValue();
	}

	public static void processAnOperator(java.util.Stack<Integer> operandStack,java.util.Stack<Character> operatorStack)
	{
		if (operatorStack.peek().equals('+'))
		{
			operatorStack.pop();
			int op1 = ((Integer)(operandStack.pop())).intValue();
			int op2 = ((Integer)(operandStack.pop())).intValue();
			operandStack.push(new Integer(op2 + op1));
		}
		else if (operatorStack.peek().equals('-')) 
		{
			operatorStack.pop();
			int op1 = ((Integer)(operandStack.pop())).intValue();
			int op2 = ((Integer)(operandStack.pop())).intValue();
			operandStack.push(new Integer(op2 - op1));
		}
		else if (operatorStack.peek().equals('*')) 
		{
			operatorStack.pop();
			int op1 = ((Integer)(operandStack.pop())).intValue();
			int op2 = ((Integer)(operandStack.pop())).intValue();
			operandStack.push(new Integer(op2 * op1));
		}
		else if (operatorStack.peek().equals('/'))
		{
			operatorStack.pop();
			int op1 = ((Integer)(operandStack.pop())).intValue();
			int op2 = ((Integer)(operandStack.pop())).intValue();
			operandStack.push(new Integer(op2 / op1));
		}
	}
	
	class ImagePanel extends JPanel
	{
		public void sshow()
		{
			int i;
			for(i = 0;i < 4;i++)
			{
				card[i] = (int)(1 + Math.random() * 52);
			}
			repaint();
		}
		
		protected void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			int i;
			int w = getWidth() / 4;
			int h = getHeight();
			int x = 0;
			int y = 0;
			for(i = 0;i < 4;i++)
			{
				ImageIcon imageIcon = new ImageIcon("image/card/" + card[i] + ".png");
				Image image = imageIcon.getImage();
				if(image != null)
				{
					g.drawImage(image,x,y,w,h,this);
				}
				x += w;
			}
		}
	}

	public static void main(String[] args) 
	{
		TwentyFourPoke_Game frame = new TwentyFourPoke_Game();
		frame.setTitle("24 Poke Game");
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(368,200);
		frame.setVisible(true);
	}
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM