猜字母小游戏

/**
猜字母小游戏  需求如下:         
程序随机产生5个按照一定顺序排列的字符作为猜测的结果(5个字符不允许重复),由玩家来猜测此字符串。
玩家可以猜测多次(不区分大小写),每猜测一次,则由系统提示结果。
(猜测过程中输入非英文字符或超过5个字符会要求重新输入正确字符).
如果猜测的完全正确,则游戏结束,计算玩家的游戏得分并输出;
如果没有猜对,则提示猜测的结果,例如 猜对了几个字符,以及猜对了几个字符的位置等信息,并提示玩家游戏继续。
如果玩家在控制台录入 exit(不区分大小写),则游戏中止,程序结束。
 
升级:
1.增加难度选项,根据输入不同数字,生成字母个数不同.    
    难度不写了,把所有出现5的地方,改成变量就可以了.
2.增加计时功能
3.增加游戏开始时间
4.增加游戏结束时间
普通版本思路:
数据结构:
1.5个随机的字符,用数组(集合)存.因为有固定长度,同一种类型,用数组更方便一些.
randomChar[]
2.猜测的次数, int count
3.分数 int score
4.用户输入的5个字符, inputChar[]
5.猜测的结果,需要一个装 inputChar[]和randomChar[]比对结果的变量,用什么呢?
如果没有猜对,则提示猜测的结果,例如 猜对了几个字符,以及猜对了几个字符的位置等信息
分析这句话,猜错提示 : 猜对了几个字符? 以及猜对了几个字符的位置?
inputChar[]和randomChar[]中,都有字符和下标 两个属性.下标可以用来表示字符的位置.
仅仅字符相同的有几个? 用一个int a接收. 字符和下标都相同的呢? 用一个int b接收.
但是考虑到对比的过程肯定是需要封装在一个方法中的,最终要返回对比的结果,来统计分数,或者是
由调用者做其他的输出等等,所以最好用int[]数组同时返回a,b才对.所以此处用int[] result,
result[0]表示字符正确,result[1]表示字符及位置都正确,分别接收两个对比的结果.

过程:
1.游戏开始前,系统生成随机字符组合,并隐藏在后台提示开始游戏
2.游戏开始
循环开始
   用户输入猜测"字符串"(将用户输入字符串转成大写并判断)
   //合理的条件:1.输入的是不是数字  2.长度为5以内  3.中文不行(正则表达式判断字符是否合理)
    如果合理:
        如果不是exit:        将用户输入"字符串"转成'字符',存入inputChar[]数组中,进入对比阶段.
                            对比阶段返回result[]结果,进入统计阶段
        如果是exit:         终止游戏
    如果不合理:     字符不合理,请重新输入
3.对比阶段,比对两个字符数组是否相等,返回结果
4.进入统计阶段,记次数,算成绩,没有全答对的情况,继续游戏,全部答对,退出游戏.

需要实现的方法:
1.随机生成字符的方法 ,返回字符数组给randomChar[]数组.     定义: char[] randomLetter()
2.判断输入字符合理与否的方法,合理返回true,否则返回false    定义: boolean inputRegex(inputStr)
3.对比阶段的方法: 对比两个字符数组有哪些字符是相同的,哪些是字符和位置都相同,返回result[]数组
定义: int[] checkCorrect(randomChar[],inputChar[])
4.统计阶段的方法: 根据result[1]的数量判断,如果为5个,证明5个字符全部猜对.结束游戏.
                否则,给出提示对应猜测个数的提示,继续游戏

根据以上思路,可以在代码中体现了.
 */
public class GuessLetter {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        /*用来接收随机生成字符randomLetter()方法的返回值*/
        char[] randomChar = {};
        /*分数及次数*/
        int count = 0;
        int score = 0;
        /*用户输入的字符,用来接收用户输入的字符串(inputStr),
         * 转换成字符inputStr.toCharArray()的返回值 */
        char[] inputChar = {};
        /*用来接收checkCorrect()方法返回值*/
        int[] result = new int[2];

        /*游戏难度选择器插入点*/

        /*1.游戏开始前,系统生成随机字符组合,并隐藏在后台提示开始游戏*/
        randomChar = randomLetter();
        System.out.println(randomChar);
        /*2.游戏开始, 循环开始*/
        System.out.println("欢迎来到猜字符小游戏,下面正式开始");

        /*游戏开始时间插入点  计时时间插入点*/
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = sdf.format(date);
        System.out.println("游戏开始时间: "+nowTime);
        long startTime = System.currentTimeMillis();

        while(true){
            /*用户输入猜测"字符串"(正则表达式判断字符是否合理)*/
            System.out.println("请输入您猜测的字符(不能超过5个字符,不能输入中文及数字),exit:退出游戏");
            String inputStr = scan.next().trim().toUpperCase();

            /*判断输入字符合理与否的方法,合理返回true,否则返回false*/
            if(inputRegex(inputStr)){
                //如果合理: 判断输入的是不是exit
                if("EXIT".equals(inputStr)){
                    System.out.println("再见,欢迎再来游戏挑战");
                    break;
                }else{

                    //将用户输入"字符串"转成'字符',存入inputChar[]数组中,进入对比阶段.
                    inputChar = inputStr.toCharArray();

                    //对比阶段,比对两个字符数组是否相等,对比阶段返回result[]结果
                    result = checkCorrect(randomChar,inputChar);

                    //进入统计阶段,记次数,算成绩,没有全答对的情况,继续游戏,全部答对,退出游戏.
                    /*根据result[1]的数量判断,如果为5个,证明5个字符全部猜对.结束游戏.
                    否则,给出提示对应猜测个数的提示,继续游戏*/
                    if(result[1] == 5){
                        score = randomChar.length*100 - 20*count;
                        System.out.println("恭喜,全部正确,得分: "+score+"分");
                        /*游戏结束时间插入点 计时插入点*/
                        long endTime = System.currentTimeMillis();
                        System.out.println("总共用时:" +(endTime-startTime)/1000+"秒");
                        System.out.println("游戏结束时间: "+nowTime);
                        break;
                    }else{
                        count++;
                        System.out.println("猜对"+result[0]+"个字符"+"其中位置也正确的有"+result[1]+"个");
                    }
                }
            }else{
                //如果不合理: 字符不合理,请重新输入
                System.out.println("字符输入不合理,请重新输入");
            }
        }
    }

    /**
     * 对比两个字符数组有哪些字符是相同的
     * @param randomChar    系统随机生成字符
     * @param inputChar        玩家输入字符
     * @return result[]        玩家猜测结果统计
     */
    public static int[] checkCorrect(char[] randomChar, char[] inputChar) {
        int[] result = new int[2];
        /*对比的方法,需要每一组的每个字符依次和另一组的一个字符依次去比对,*/
        //所以用双层嵌套循环.
        for (int i = 0; i < randomChar.length; i++) {
            for (int j = 0; j < inputChar.length; j++) {
                if(randomChar[i] == inputChar[j]){
                    //字符正确的个数
                    result[0]++;
                    if(i == j){
                        //字符及位置都正确的个数
                        result[1]++;
                        break;
                    }
                }
            }
        }
        return result;
    }

    /**
     * 判断用户输入的字符是否合理
     * @param str    用户输入的字符串
     * @return    合理返回true,否则返回false
     */
    public static boolean inputRegex(String str) {
        //合理的条件:1.输入的是不是数字  2.长度为5以内  3.中文不行
        String inputRegex = "([a-zA-Z]){1,5}";
        return str.matches(inputRegex);
    }

    /**
     * 随机字符生成方法
     * @return char[] random  生成完毕的字符数组
     */
    public static char[] randomLetter() {
        Random rand = new Random();
        /*加入难度,5可以设置成变量即可*/
        char[] random = new char[5];

        /*字母表,作用:将随机从这里选则字符,赋值给random数组.
         *需要一个index变量表示letters的下标.
         *index循环5次赋值,取得5个下标对应的5个字符,赋值给random数组.但是不能保证不重复.
         *想保证不重复,需要随机5次的数字不相同,怎么控制呢? 
         *可以用另一个数组,boolean型数组,长度等同于letters数组.只要被挑选过的字母下标,
         *再次出现的话,开关就变成true,即再多一次循环,不选择这次重复的下标的字母.
         **/
        int index = 0;
        char[] letters = {'A','B','C','D','E','F','G','H','I','J','K','L','M'
                ,'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
        boolean[] flags = new boolean[letters.length]; //默认值均为false;

        /*为数组赋值,需要遍历数组*/
        for (int i = 0; i < random.length; i++) {
            //只要开关数组的下标是true状态,表示这个字符被使用过.即再次循环,直到随机出不同的下标
            while(flags[index]){
                index = rand.nextInt(letters.length);
            }
            //赋值给random
            random[i] = letters[index];
            //只要赋值过的下标,都被标记为true;
            flags[index] = true;
        }
        return random;
    }
    /*
    生成字符: ACHZW  输出结果:
        欢迎来到猜字符小游戏,下面正式开始
        请输入您猜测的字符(不能超过5个字符,不能输入中文及数字),exit:退出游戏
        5爱过后
        字符输入不合理,请重新输入
        请输入您猜测的字符(不能超过5个字符,不能输入中文及数字),exit:退出游戏
        achze
        猜对4个字符其中位置也正确的有4个
        请输入您猜测的字符(不能超过5个字符,不能输入中文及数字),exit:退出游戏
        achzw
        恭喜,全部正确,得分: 480分 
     */
}
View Code

 

posted @ 2016-05-01 10:56  安仔80  阅读(447)  评论(0编辑  收藏  举报