【入门】Java取火柴游戏

一个取火柴的小游戏,规则:一堆火柴,玩家(或电脑)轮流取1到4根,取到最后一根算输。

游戏中可以人机(一个人)或者多人(30人以内)对战,火柴数可以指定或者随机,电脑难度有两种,困难难度要赢很困难(废话)。初学作品,还请多多指教。

package aMatchGame;
//主类
public class Main {
    public static void main(String []args){
        new Show().showMe();
    }
}

package aMatchGame;
//主界面
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

class Show {
    private Config config;
    private DateFormat df = new SimpleDateFormat("HH:mm:ss");

    private JFrame frame;
    private JMenuBar bar;
    private JMenu mode;
    private JMenuItem pC;
    private JMenuItem pP;
    private JMenuItem isRandom;
    private JMenu setting;
    private JMenuItem sysSet;
    private JMenuItem aiSet;
    private JMenu help;
    private JMenuItem rule;
    private JMenuItem about;
    private JLabel match;
    private JTextArea log;
    private JLabel player;
    private JTextField field;
    private JButton submit;

    private final static String RUL = "游戏规则:\n  规定或随机取一些火柴,玩家轮流取1~4根火柴,取到最后一根火柴的玩家算输。\n\n操作方法:\nstart:开始游戏\nstop:结束游戏";
    private final static String VER = "火柴游戏 \n\n版本号:V2.5\n\n开发者:董悦\n开发时间:2017年10月";
    private final static Object[] AI = {"简单","困难"};


    Show(){
        config = new Config();
        frame = new JFrame("火柴游戏");
        bar = new JMenuBar();
        mode = new JMenu("模式(M)");
        mode.setMnemonic(KeyEvent.VK_M);
            pC = new JMenuItem("人机对战(当前)");
            pC.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_DOWN_MASK));
            pP = new JMenuItem("多人对战");
            pP.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,InputEvent.CTRL_DOWN_MASK));
            isRandom = new JMenuItem("随机(当前)");
            isRandom.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,InputEvent.CTRL_DOWN_MASK));
        setting = new JMenu("设置(S)");
        setting.setMnemonic(KeyEvent.VK_S);
            sysSet = new JMenuItem("系统设置");
            sysSet.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,InputEvent.CTRL_DOWN_MASK));
            aiSet = new JMenuItem("AI 设置");
            aiSet.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,InputEvent.CTRL_DOWN_MASK));
        help = new JMenu("帮助(H)");
        help.setMnemonic(KeyEvent.VK_H);
            rule = new JMenuItem("游戏帮助");
            rule.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,InputEvent.CTRL_DOWN_MASK));
            about = new JMenuItem("关于");
            about.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,InputEvent.CTRL_DOWN_MASK));
        match = new JLabel("————输入start开始游戏————");
        log = new JTextArea(5,20);
        log.setEditable(false);
        log.setLineWrap(true);
        player = new JLabel("");
        field = new JTextField(12);
        submit = new JButton("确认");
    }
    private void init(){
        mode.add(pC);
        mode.add(pP);
        mode.add(isRandom);
        setting.add(sysSet);
        setting.add(aiSet);
        help.add(rule);
        help.add(about);
        bar.add(mode);
        bar.add(setting);
        bar.add(help);
        frame.setJMenuBar(bar);
        JPanel north = new JPanel();
        north.add(match);
        frame.add(north,BorderLayout.NORTH);
        JPanel center = new JPanel();
        JScrollPane jsp = new JScrollPane(log);
        center.add(jsp);
        frame.add(center, BorderLayout.CENTER);
        JPanel south = new JPanel();
        GridLayout grid = new GridLayout(2,1,3,3);
        south.setLayout(grid);
        south.add(player);
        JPanel input = new JPanel();
        input.add(field);
        input.add(submit);
        south.add(input);
        frame.add(south,BorderLayout.SOUTH);
        frame.pack();
        frame.setResizable(false);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        field.requestFocus();
        frame.setLocationRelativeTo(null);
    }
    private void reg(){		//整理事件注册
        submit.addActionListener(new Submit());
        pC.addActionListener(e1 -> {
            pC.setText("人机对战(当前)");
            pP.setText("多人对战");
            config.setMode(1);
            System.out.println(df.format(new Date()) + "设置模式为人机对战");
        });
        pP.addActionListener(e2 -> {
            String tmp = JOptionPane.showInputDialog(frame,"请输入游戏人数:\n","提示",JOptionPane.PLAIN_MESSAGE);
            int mode;
            if(tmp == null){
                mode = -2;
            }
            else {
                mode = config.toInt(tmp);
            }
            if((mode <= 1 && mode != -2) || mode > 30){
                JOptionPane.showMessageDialog(frame,"您输入的人数不正确,已经帮您恢复默认设置。","提示",JOptionPane.INFORMATION_MESSAGE);
                pC.setText("人机对战(当前)");
                pP.setText("多人对战");
                config.setMode(1);
                System.out.println(df.format(new Date()) + "设置错误模式为人机对战");
            }
            else if(mode != -2){
                pC.setText("人机对战");
                pP.setText(mode + "人对战(当前)");
                config.setMode(mode);
                System.out.println(df.format(new Date()) + "设置模式为" + config.getMode() + "人对战");
            }
        });
        isRandom.addActionListener(e3 -> {
            if(isRandom.getText().equals("随机(当前)")){
                String tmp =JOptionPane.showInputDialog(frame,"请输入火柴数:","提示",JOptionPane.PLAIN_MESSAGE);
                int matchNum;
                if(tmp == null)
                    matchNum = -2;
                else
                    matchNum = config.toInt(tmp);
                if(matchNum == -1){
                    JOptionPane.showMessageDialog(frame,"您输入的火柴数不正确,已帮您恢复随机模式。","提示",JOptionPane.INFORMATION_MESSAGE);
                }
                else if((matchNum < 10 || matchNum > 250) && matchNum != -2){
                    if(JOptionPane.showConfirmDialog(frame,"您选择的火柴数不是很适合,您确定吗?","提示",JOptionPane.YES_NO_OPTION) == 0){
                        config.setRandom(false);
                        config.setMatchNum(matchNum);
                        isRandom.setText("选择(当前)");
                        System.out.println(df.format(new Date()) + "设置模式随机,火柴数" + matchNum);
                    }
                }
                else if(matchNum != -2){
                    config.setRandom(false);
                    config.setMatchNum(matchNum);
                    isRandom.setText("选择(当前)");
                    System.out.println(df.format(new Date()) + "设置模式为选择,火柴数" + matchNum);
                }
            }
            else{
                config.setRandom(true);
                isRandom.setText("随机(当前)");
                System.out.println(df.format(new Date()) + "设置模式为随机");
            }
        });
        sysSet.addActionListener(new SystemSet());
        aiSet.addActionListener(e4 -> {
            String aiLv = (String)JOptionPane.showInputDialog(frame,"请选择 AI 难度\n","AI 设置",JOptionPane.QUESTION_MESSAGE,null,AI,config.getAiLv());
            if(aiLv != null) {
                config.setAiLv(aiLv);
                System.out.println(df.format(new Date()) + "设置AI难度为" + aiLv);
            }
        });
        rule.addActionListener(e5 -> JOptionPane.showMessageDialog(frame,RUL,"游戏帮助",JOptionPane.PLAIN_MESSAGE));
        about.addActionListener(e6 -> JOptionPane.showMessageDialog(frame,VER,"关于",JOptionPane.PLAIN_MESSAGE));
    }
    void showMe(){
        init();
        reg();
        frame.setVisible(true);
    }
    private class SystemSet implements ActionListener{		//系统设置界面
        private JDialog dialog;
        private JLabel min;
        private JTextField minField;
        private JLabel max;
        private JTextField maxField;
        private JCheckBox pre;
        private JButton yes;
        private JButton no;

        SystemSet(){
            dialog = new JDialog(frame,"系统设置",true);
            min = new JLabel("随机最小值:");
            minField = new JTextField(3);
            max = new JLabel("随机最大值:");
            maxField = new JTextField(3);
            pre = new JCheckBox("人机对战先手");
            yes = new JButton("确认");
            no = new JButton("取消");
            JPanel north = new JPanel();
            GridLayout grid = new GridLayout(1,2);
            north.setLayout(grid);
            JPanel minInput = new JPanel();
            minInput.add(min);
            minInput.add(minField);
            JPanel maxInput = new JPanel();
            maxInput.add(max);
            maxInput.add(maxField);
            north.add(minInput);
            north.add(maxInput);
            JPanel center = new JPanel();
            center.add(pre);
            JPanel south = new JPanel();
            south.add(yes);
            south.add(no);
            dialog.add(north,BorderLayout.NORTH);
            dialog.add(center,BorderLayout.CENTER);
            dialog.add(south,BorderLayout.SOUTH);
            dialog.pack();
            dialog.setResizable(false);
            dialog.setDefaultCloseOperation(dialog.DISPOSE_ON_CLOSE);
            dialog.setLocationRelativeTo(null);
            yes.addActionListener(e1 ->{
                int r1 = config.toInt(minField.getText());
                int r2 = config.toInt(maxField.getText());
                boolean isPre;
                if(r1 == -1 || r2 == -1 || r1 >= r2){
                    JOptionPane.showMessageDialog(dialog,"数值不正确哦!","提示",JOptionPane.INFORMATION_MESSAGE);
                }
                else {
                    if (r1 < 10 || r1 > 250 || r2 < 10 || r2 > 250)
                        if(JOptionPane.showConfirmDialog(dialog,"数值不是很合适,你确定吗?","提示",JOptionPane.YES_NO_OPTION) == 1)
                            return;
                    isPre = pre.isSelected();
                    config.set(r1,r2,isPre);
                    System.out.println(df.format(new Date()) + "设置" + config.dataOut());
                    dialog.dispose();
                }
            });
            no.addActionListener(e2 -> dialog.dispose());
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            pre.setSelected(config.getPre());
            minField.setText("" + config.getMinRandom());
            maxField.setText("" + config.getMaxRandom());
            dialog.setVisible(true);
        }
    }
    private class Submit implements ActionListener{		//提交按钮事件
        @Override
        public void actionPerformed(ActionEvent e) {
            String txt = field.getText();
            int num;
            if(txt.equals("start")){
                if(!config.start())
                    JOptionPane.showMessageDialog(frame,"游戏已经开始喽!\n如果想重新开始输入“stop”结束哦!","提示",JOptionPane.INFORMATION_MESSAGE);
                else {
                    match.setText("————剩余" + config.getMatchNum() + "根火柴————");
                    if(config.getMode() == 1) {
                        if(config.getPre())
                            player.setText("轮到玩家抽取");
                        else {
                            log.append("电脑取走" + config.ai() + "根火柴\n");
                            if(config.getMatchNum() == 0){
                                JOptionPane.showMessageDialog(frame,"恭喜!玩家赢了","提示",JOptionPane.PLAIN_MESSAGE);
                                config.stop();
                                match.setText("————输入start开始游戏————");
                                field.setText("");
                                player.setText("");
                            }
                            else {
                                match.setText("————剩余" + config.getMatchNum() + "根火柴————");
                                player.setText("轮到玩家抽取");
                            }
                        }
                    }
                    else
                        player.setText("轮到玩家" + config.getTurn() + "抽取");
                }
            }
            else if(txt.equals("stop")){
                if(!config.stop())
                    JOptionPane.showMessageDialog(frame,"游戏已经停止楼!\n如果想开始游戏输入“start”开始哦!","提示",JOptionPane.INFORMATION_MESSAGE);
                else {
                    log.setText("");
                    match.setText("————输入start开始游戏————");
                    player.setText("");
                }
            }
            else if(!txt.equals("")){
                num = config.toInt(txt);
                if(num == -1 || num < 1 || num > 4 || num > config.getMatchNum())
                    JOptionPane.showMessageDialog(frame,"您的输入不正确哦!","提示",JOptionPane.INFORMATION_MESSAGE);
                else{
                    if(config.getMode() == 1){
                        config.remove(num);
                        log.append("玩家取走" + num + "根火柴\n");
                        if(config.getMatchNum() == 0){
                            JOptionPane.showMessageDialog(frame,"很遗憾,电脑赢了","提示",JOptionPane.PLAIN_MESSAGE);
                            config.stop();
                            match.setText("————输入start开始游戏————");
                            log.setText("");
                            player.setText("");
                        }
                        else {
                            log.append("电脑取走" + config.ai() + "根火柴\n");
                            if(config.getMatchNum() == 0){
                                JOptionPane.showMessageDialog(frame,"恭喜!玩家赢了","提示",JOptionPane.PLAIN_MESSAGE);
                                config.stop();
                                match.setText("————输入start开始游戏————");
                                log.setText("");
                                player.setText("");
                            }
                            else {
                                match.setText("————剩余" + config.getMatchNum() + "根火柴————");
                                player.setText("轮到玩家抽取");
                            }
                        }
                    }
                    else{
                        config.remove(num);
                        log.append("玩家" + config.getTurn() + "取走" + num + "根火柴\n");
                        if(config.getMatchNum() == 0){
                            JOptionPane.showMessageDialog(frame,"很遗憾,玩家" + config.getTurn() + "输了","提示",JOptionPane.PLAIN_MESSAGE);
                            config.stop();
                            match.setText("————输入start开始游戏————");
                            log.setText("");
                            player.setText("");
                        }
                        else {
                            config.next();
                            match.setText("————剩余" + config.getMatchNum() + "根火柴————");
                            player.setText("轮到玩家" + config.getTurn() + "抽取");
                        }
                    }
                }
            }
            field.setText("");
        }
    }
}
package aMatchGame;
//数据存储和游戏处理(类名取得不太好)
class Config {
    private boolean isStart;
    private String aiLv;
    private int matchNum;
    private boolean isRandom;
    private int minRandom;
    private int maxRandom;
    private int mode;
    private int turn;
    private boolean pre;
    private  AI ai;

    Config(){
        isStart = false;
        aiLv = "简单";
        matchNum = 21;
        isRandom = true;
        minRandom = 15;
        maxRandom = 35;
        mode = 1;
        pre = false;
        turn = 0;
    }

    int getMatchNum() {
        return matchNum;
    }
    void setMatchNum(int matchNum) {
        this.matchNum = matchNum;
    }
    int getMode() {
        return mode;
    }
    void setMode(int mode) {
        this.mode = mode;
    }
    int getMinRandom() {
        return minRandom;
    }
    int getMaxRandom() {
        return maxRandom;
    }
    boolean getPre(){
        return pre;
    }
    String getAiLv(){
        return aiLv;
    }
    void setAiLv(String lv){
        aiLv = lv;
    }
    void setRandom(boolean isRandom){
        this.isRandom = isRandom;
    }
    int toInt(String str){
        int sum = 0;
        for(int i = 0;i < str.length();i++){
            if(str.charAt(i) < '0' || str.charAt(i) > '9')
                return -1;
            else {
                sum *= 10;
                sum += str.charAt(i) - '0';
            }
        }
        return sum;
    }
    void set(int min,int max,boolean pre){
        minRandom = min;
        maxRandom = max;
        this.pre = pre;
    }
    String dataOut(){
        return "最小值" + minRandom + ",最大值" + maxRandom + ",玩家先手" + pre;
    }
    int getTurn(){
        return turn;
    }
    void next(){
        if(turn == mode)
            turn = 1;
        else
            turn ++;
    }

    boolean start(){
        if(isStart)
            return false;
        else {
            isStart = true;
            turn = 1;
            if(isRandom){
                matchNum = (int)(Math.random() * (maxRandom - minRandom + 1) + minRandom);
            }
            if(mode == 1){
                if(aiLv.equals("简单"))
                    ai = new EasyAi();
                else
                    ai = new DifficultAi();
            }
            return true;
        }
    }
    boolean stop(){
        if(!isStart)
            return false;
        else {
            isStart = false;
            return true;
        }
    }
    void remove(int num){
        matchNum -= num;
    }
    int ai(){
        int drop = ai.index(matchNum);
        matchNum -= drop;
        return drop;
    }
}
package aMatchGame;
//AI接口(虽然没有必要,但我初学练手)
public interface AI {
    int index(int match);
}

package aMatchGame;
//简单级别AI
public class EasyAi implements AI {
    @Override
    public int index(int match) {
        if(match == 1)
            return 1;
        else if(match <= 5){
            return match - 1;
        }
        else {
            return (int)(Math.random() * 4 +1);		//随机取火柴直到火柴小于6根
        }
    }
}
package aMatchGame;
//困难模式AI
public class DifficultAi implements AI {
    @Override
    public int index(int match) {
        if(match == 1)
            return 1;
        else if(match <= 5)
            return match - 1;
        else {
            if((match - 5) % 4 == 0)
                return 4;			//将局面扳向玩家取走倒数第6根,这样剩下2-5根电脑取走火柴数-1根玩家必输
            else
                return (match - 5) % 4;
        }
    }
}




  • 6
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值