java实现猜数字AB


前言

前几天刚好看了《登录圆鱼洲》,对里面的一个游戏环节"猜数字AB"很感兴趣,所以想用Java来实现这个小游戏。

规则是:选中0~9 十个数中不重复的四个,然后由参与者来猜,如果某一个数猜中并且对应的位置也对则表示为1A,如果某一个数猜中但对应的位置不对则表示为1B,比如写下的数为1234,你猜1245,则表示为2A1B;参与者通过几A几B来判定所猜的数是否正确,当四个数数值和位置都对并且猜的次数不超过10次即为挑战成功!


代码实现

代码如下:(思路简单,代码有点粗糙,如果有更简单的,请大佬贴在讨论区一起学习)

import java.util.Scanner;
import java.util.List;
import java.util.Random;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Arrays;
public class GuessNumberAB {
    
    

    public static void main(String[] args) {
    
    

        Scanner scanner = new Scanner(System.in);
        Scanner scanner2 = new Scanner(System.in);
        Random random = new Random();
        String[] num = {
    
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        HashSet<String> set = new HashSet<>();
        while(set.size() != 4){
    
    
            set.add(num[random.nextInt(10)]);
        }
        ArrayList<String> target = new ArrayList<>(set);
        while(true){
    
    
            System.out.print("是否进行游戏(y:是 , n否)");
            String isGame = scanner.next();
            if ("n".equals(isGame)){
    
    
                System.out.println("游戏结束!");
                break;
            }else if ("y".equals(isGame)){
    
    
                String guessNum = null;
                String[] arr=null;
                    int times = 0;
                    while (times++ < 10){
    
    
                        System.out.print("输入你的答案不重复的四位数:");
                        guessNum = scanner2.next();
                        arr = guessNum.trim().split("");
                        if ((arr.length == 4)&& (isRepeat(arr))) {
    
    
                            String tar = isReal(arr, target);
                            System.out.printf("第%d轮,结果为%s\n",times,tar);
                            if("4A0B".equals(tar)){
    
    
                                System.out.println("您猜对了!恭喜");
                                return;
                            }
                        }else System.out.println("必须输入4个不重复的数,再次输入");
                    }
                    if (times>10){
    
    
                        System.out.println("游戏失败! target="+set);
                        return;
                    }
            }else{
    
    
                System.out.println("输入错误,请重新输入");
            }
        }

    }

    public static boolean isRepeat(String[] arr){
    
      //判断每次输入答案是否有重复
        HashSet<String> set = new HashSet<>(Arrays.asList(arr));
        return set.size() == arr.length;
    }

    private static String isReal(String[] arr,List<String> target) {
    
    
        String result = "%dA%dB";
        int A = 0;  //判断A值
        for (int i=0;i<arr.length;i++){
    
    
            if (target.get(i).equals(arr[i]))
                A++;
        }
        int B = 0; 
        for (String a:arr){
    
    
            for (String b: target){
    
    
                if (a.equals(b)){
    
    
                    B++;
                    break;
                }
            }
        } //这里B表示所有数值相同的个数,减去位置和数值都相同的A,就是位置不同数值相同的个数
        return String.format(result, A,(B-A));
    }
}

个人对游戏的解题思路

一开始在玩这个游戏时,完全没有思路,只能一个一个去猜,单纯靠运气,后面玩了几次后逐渐有了一种比盲猜稍微好点的方法,记录一下:
我将数分成三份(1,2,3,4)、(5,6,7,8)、(0,9)前两轮分别猜(1,2,3,4)、(5,6,7,8)这样就可以得到得到目标数的大致分布;再通过已经确定好的目标数/非目标数来判定不确定的数,当得到四个数以后再通过之前判断的位置来判断顺序。下面以执行代码的方式运用一下这个解题思路。

step1: 1234结果为0A1B,说明1234只有1个是目标数
在这里插入图片描述

step2: 5678结果为0A2B,说明5678里面有两个目标数,所以(0,9) 里面必须有一个目标数,那么第三轮可以用(0,9) 与只用一个目标数的(1,2,3,4)中的两个数进行猜测;随机选(0,9,1,2)
在这里插入图片描述
step3: (0,9,1,2) 结果是2B,说明(1,2)有一个目标数,而(1,2,3,4)只有一个目标数,故而(3,4)就是非目标数,那么第四轮就可以用(3,4)非目标数与(5,6,7,8)其中两个进行猜测,随机选择(3,4,5,6)
在这里插入图片描述

step4: (3,4,5,6)结果是没有一个目标数,所以(5,6,7,8)中的两个目标数为(7,8), (5,6)是非目标数;现在的非目标数有(3,4,5,6), 目标数有(7,8), (1,2)与(0,9)各一个。 选用(3,1,4,5)判断出(1,2)中的目标数
在这里插入图片描述
step5: 如图:1不是目标数,所以(1,2)中的目标数为2,现在确定的目标数有(2,7,8),非目标数有(1,3,4,5,6);再用(1,3,9,4)确定(0,9)中的目标数
在这里插入图片描述
step6: 如图:说明9是目标数,0非目标数,四个目标数分别为(2,7,8,9);接下来就是判断顺序(用非目标数猜测时应该顺序尽量与原来调换)
在这里插入图片描述

判断顺序:
在这里插入图片描述
首先四个数分成四个位置abcd,(2,7,8,9)中,由第一轮中2不能在b,由第三轮2不能在d; 由第二轮7不能在c;由第三轮9不能在b, 第六轮9不能在c; 由第二轮8不能在d; 所以如图:
在这里插入图片描述
因为bd不能为2,ac有一个为2,所以假设a=2,那么d就只能是9,因为bc都不能为9,又因为c不能为7,在剩下的bc中只能b=7,所以最后c=8; 那么可以猜测2789, 将2789再与前几轮作对比看看是否有错。
结果:在这里插入图片描述
那么如果先选择了c=2,并不能得到唯一的结果,所以不可取。

我们也可以选择假设a=9(因为只能ad其中一个为9),那么d只能=7,对于2,在剩下的bc中b不能为2,所以b=8,c=2; 此时猜测结果为 9827;9827由正确结果可以在第七轮显示为0A4B,所以推断a不能为9,故d=9,在此情况下有(2,7,8,9)和(7,8,2,9)和 (8,7,2,9)三种情况,在最坏运气时可以刚好第10轮得到结果,挑战成功!

猜你喜欢

转载自blog.csdn.net/qq_49472679/article/details/126686172