java 24点经典纸牌益智游戏

java 24点经典纸牌益智游戏

内容

24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1. 程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。

算法分析

创建一个person类存放玩家的分数和生命值;创建一个洗牌类Makepuker实现洗牌和发牌,用Hashmap储存扑克,调用Collctions的suffer方法实现习洗牌;类player实现游戏的运行,其中calculate函数中实现中缀表达式计算,play函数用于中调用Makerpuker中的makerpuker函数洗牌,然后用户根据puker输入表达式,计时器判断是否超时,如果超时则不用比价结果直接进入下一行,否则比较;play类中的make函数对makerpuker函数中的返回值进行判断,并向用户响应相应的结果,main函数调用make函数,并将结果写入文件。

概要设计

在这里插入图片描述

代码

package game;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class Makepuker {
    public  String[] makepuker() {
        List<String> color = List.of("♥", "♠", "♣", "♦");
        List<String> number = List.of("A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "k");
        //存放扑克
        HashMap<Integer, String> pai = new HashMap<>();
        //存放扑克的所引
        ArrayList<Integer> index = new ArrayList<>();
        int i = 0;
        //循环嵌套存放扑克和索引
        for (String c : color) {
            for (String n : number) {
                pai.put(i, n + c);
                index.add(i);
                i++;
            }
        }
        //洗牌
        Collections.shuffle(index);
       // System.out.println(index);
        //System.out.println(pai);
        //取出前4张牌
        String puker[] = new String[4];
        for (int j = 0; j <= 3; j++) {
            puker[j] = pai.get(index.get(j));
            System.out.println(puker[j]);
        }
        return puker;
    }
}

package game;

public class person {
    private int  life;
    private int score ;

    public person(int life, int score) {
        this.life = life;
        this.score = score;
    }

    public person() {
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

package game;

import game.thread.threadpool;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

public class player {
     public int play(){
         //获取开始游戏时系统时间
         long star = System.currentTimeMillis();
         //洗牌
         Makepuker makepuker=new Makepuker();
         makepuker.makepuker();
         System.out.println("根据扑克输入表达式");
         Scanner scanner=new Scanner(System.in);
         String s=scanner.next();
         BigDecimal a= new BigDecimal(24);
         person p=new person();
         //获取系统时间
         long end = System.currentTimeMillis();
         if(end-star<20000) {//如果时间小于10秒则进行比较
             if (calculate(s).equals(a)) {//输入的表达式等于24
                 return 1;
             } else {//输入的表达式不等于24
                 return 2;
             }
         }else {//时间到了
         return 3;

         }
    }

    //计算加减乘除四则运算
    public BigDecimal calculate(String str){
        // 对表达式进行预处理,并简单验证是否是正确的表达式
        // 存放处理后的表达式
        List<String> list = new ArrayList<>();
        char[] arr = str.toCharArray();
        // 存放数字临时变量
        StringBuffer tmpStr = new StringBuffer();
        for (char c : arr) {
            // 如果是数字或小数点,添加到临时变量中
            if (c >= '0' && c <= '9') {
                tmpStr.append(c);
            } else if (c == '.') {
                if (tmpStr.indexOf(".") > 0) {
                    throw new RuntimeException("非法字符");
                }
                tmpStr.append(c);
            }
            // 如果是加减乘除或者括号,将数字临时变量和运算符依次放入list中
            else if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')') {
                if (tmpStr.length() > 0) {
                    list.add(tmpStr.toString());
                    tmpStr.setLength(0);
                }
                list.add(c + "");
            }
            // 如果是空格,跳过
            else if (c == ' ') {
                continue;
            } else {
                throw new RuntimeException("非法字符");
            }
        }
        if (tmpStr.length() > 0) {
            list.add(tmpStr.toString());
        }
        // 初始化后缀表达式
        List<String> strList = new ArrayList<>();
        // 运算过程中,使用了两次栈结构,第一次是将中缀表达式转换为后缀表达式,第二次是计算后缀表达式的值
        Stack<String> stack = new Stack<>();
        // 声明临时变量,存放出栈元素
        String tmp;
        // 1. 将中缀表达式转换为后缀表达式
        for (String s : list) {
            // 如果是左括号直接入栈
            if (s.equals("(")) {
                stack.push(s);
            }
            // 如果是右括号,执行出栈操作,依次添加到后缀表达式中,直到出栈元素为左括号,左括号和右括号都不添加到后缀表达式中
            else if (s.equals(")")) {
                while (!(tmp = stack.pop()).equals("(")) {
                    strList.add(tmp);
                }
            }
            // 如果是加减乘除,弹出所有优先级大于或者等于该运算符的栈顶元素(栈中肯定没有右括号,认为左括号的优先级最低),然后将该运算符入栈
            else if (s.equals("*") || s.equals("/")) {
                while (!stack.isEmpty()) {
                    // 取出栈顶元素
                    tmp = stack.peek();
                    if (tmp.equals("*") || tmp.equals("/")) {
                        stack.pop();
                        strList.add(tmp);
                    } else {
                        break;
                    }
                }
                stack.push(s);
            } else if (s.equals("+") || s.equals("-")) {
                while (!stack.isEmpty()) {
                    // 取出栈顶元素
                    tmp = stack.peek();
                    if (!tmp.equals("(")) {
                        stack.pop();
                        strList.add(tmp);
                    } else {
                        break;
                    }
                }
                stack.push(s);
            }
            // 如果是数字,直接添加到后缀表达式中
            else {
                strList.add(s);
            }
        }
        // 最后依次出栈,放入后缀表达式中
        while (!stack.isEmpty()) {
            strList.add(stack.pop());
        }
        // 2.计算后缀表达式的值
        Stack<BigDecimal> newStack = new Stack<>();
        for (String s : strList) {
            // 若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的放到运算符左边,
            // 运算后的结果再进栈,直到后缀表达式遍历完毕
            if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
                BigDecimal b1 = newStack.pop();
                BigDecimal b2 = newStack.pop();
                switch (s) {
                    case "+":
                        newStack.push(b2.add(b1));
                        break;
                    case "-":
                        newStack.push(b2.subtract(b1));
                        break;
                    case "*":
                        newStack.push(b2.multiply(b1));
                        break;
                    case "/":
                        newStack.push(b2.divide(b1, 9, BigDecimal.ROUND_HALF_UP));
                        break;
                }
            }
            // 如果是数字,入栈
            else {
                newStack.push(new BigDecimal(s));
            }
        }
        // 最后,栈中仅有一个元素,就是计算结果
        return newStack.peek();
    }


}

package game;

import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

public class play {
    public static void main(String[] args) throws IOException {
        //创建玩家p
        person p=new person(3,2);
        System.out.println("你的生命值: "+p.getLife()+"你的分数为: "+p.getScore());
        //player player1=new player();
        play.mmake(p);
        FileWriter fileWriter = new FileWriter("wrrite,txt");
        String life=p.getLife()+"";
        String score=p.getScore()+"";
        String str="生命值:"+life+"分数为:"+score;
        fileWriter.write(str);
        fileWriter.close();
        System.out.println("1游戏结束!");

    }
    //进行游戏
    public static void mmake(person p) {
        player player1=new player();
        int resust=player1.play();
        if(resust==1){
            int score=p.getScore()+1;
            p.setScore(score);
            System.out.println("回答正确,您的分数为"+score);
            return;
        }
        if(resust==2){
            int life=p.getLife();
            life--;
            p.setLife(life);
            if(life>0){
                System.out.println("回答错误!你的生命值为"+life);
                mmake(p);
              }else{
                return;
            }
        }
        if(resust==3){
            int life=p.getLife();
            life--;
            p.setLife(life);
            if(life>0){
            System.out.println("时间到了,开始下一轮,你的生命值:"+life);
           mmake(p);
            }else{
                return;
            }
        }

    }

测试

在这里插入图片描述

心得体会

刚才开始使用定时器来记时,但无法在主线程中找到定时器提供的信息,最后使用System.currenttimemillist( )函数解决了问题。## 标题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值