魔术游戏
- 一、问题描述
- 二、基本流程
- 三、具体步骤
- 1.在集合中随机生成起始牌
- 2.菜单栏
- 3.找到包含[选中牌]的一组牌在大集合中的索引
- 4.洗牌
- 5.发牌
 
- 四、完整代码
- 五、效果展示
 
一、问题描述
这是一个魔术游戏,将15张牌分为三组,每组5张,让玩家从中任选一张牌并记下,将这张牌记为[选中牌]。
1.依次询问玩家这三组牌里是否包含[选中牌],将包含这张牌的一组牌放在两组中间。
2.发牌,重新将15张牌分为三组。
3.重复上述步骤,将包含[选中牌]的一组牌放到中间。
4.重复上述步骤3次(完成发牌和将[选中牌]放在中间为一次)。
二、基本流程
一开始随机生成15张牌,[1,5]在第一个小集合中,[6,10]在第二个小集合中,[11,15]在第三个小集合中。
使用集合嵌套,将每一组牌放在一个小集合中。
三、具体步骤
1.在集合中随机生成起始牌
    public static List<ArrayList<Integer>> list1 = new ArrayList<>();
    public static List<Integer> list1_1 = new ArrayList<>();
    public static List<Integer> list1_2 = new ArrayList<>();
    public static List<Integer> list1_3 = new ArrayList<>();
    public static List<ArrayList<Integer>> list2 = new ArrayList<>();
    public static List<Integer> list2_1 = new ArrayList<>();
    public static List<Integer> list2_2 = new ArrayList<>();
    public static List<Integer> list2_3 = new ArrayList<>();
    static {
        Integer[] list_1_arr = {0, 0, 0, 0, 0};
        Integer[] list_2_arr = {0, 0, 0, 0, 0};
        Integer[] list_3_arr = {0, 0, 0, 0, 0};
        addNumInArr(list_1_arr, 1);
        addNumInArr(list_2_arr, 6);
        addNumInArr(list_3_arr, 11);
        list1_1.addAll(Arrays.asList(list_1_arr));
        list1_2.addAll(Arrays.asList(list_2_arr));
        list1_3.addAll(Arrays.asList(list_3_arr));
        list1.add((ArrayList<Integer>) list1_1);
        list1.add((ArrayList<Integer>) list1_2);
        list1.add((ArrayList<Integer>) list1_3);
        list2.add((ArrayList<Integer>) list2_1);
        list2.add((ArrayList<Integer>) list2_2);
        list2.add((ArrayList<Integer>) list2_3);
    }
    /**
     * 向数组添加不重复元素
     *
     * @param list_1_arr
     * @param n2         生成随机值的偏移量
     */
    private static void addNumInArr(Integer[] list_1_arr, int n2) {
        Random ran = new Random();
        int count = 0;
        while (true) {
            for (int i = 0; i < 5; i++) {
                while (true) {
                    boolean flag = true;
                    boolean flag2 = false;
                    int num = ran.nextInt(5) + n2;
                    for (int j = 0; j < 5; j++) {
                        if (num == list_1_arr[j]) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        list_1_arr[i] = num;
                        count++;
                        flag2 = true;
                    }
                    if (flag2)
                        break;
                }
            }
            if (count == 5)
                break;
        }
2.菜单栏
    /**
     * 菜单栏
     */
    private static void menu() {
        System.out.println("-------------------------------------------------------");
        System.out.println("魔术,随机让玩家记住一张牌,通过游戏规则变换三次后即可猜出那张牌");
        System.out.println("洗牌:将带有输入数字的一组牌放到中间位置");
        System.out.println("发牌:按照洗牌后的顺序发牌");
        System.out.println("-------------------------------------------------------");
        System.out.println("#######################################################");
        System.out.println("游戏规则:");
        System.out.println("1:让玩家从15张牌中随机选出一张记下【选中牌】");
        System.out.println("2:将15张牌按照顺序发牌,分为3组,每组5张");
        System.out.println("3:依次询问每组牌是否包含【选中牌】");
        System.out.println("4:将包含【选中牌】的那组放到中间,另外两组随意");
        System.out.println("5:重复步骤2,3,4,保证洗牌次数大于等于3后,即可在中间那组的第3张找到【选中牌】");
        System.out.println("#######################################################");
        System.out.println("请输入1——15之间的一个数字:");
    }
3.找到包含[选中牌]的一组牌在大集合中的索引
    /**
     * 查找指定元素在大集合中的索引(0 1 2)
     *
     * @param list1
     * @param n
     * @return
     */
    private static int getNumInList(List<ArrayList<Integer>> list1, int n) {
        int flag = 0;
        for (int i = 0; i < list1.size(); i++) {
            for (int j = 0; j < list1.get(i).size(); j++) {
                if (n == list1.get(i).get(j)) {
                    flag = i;
                    break;
                }
            }
        }
        return flag;
    }
}
4.洗牌
将包含[选中牌]的一组牌放到中间
    /**
     * 查找指定元素在大集合中的索引(0 1 2)
     *
     * @param list1
     * @param n
     * @return
     */
    private static int getNumInList(List<ArrayList<Integer>> list1, int n) {
        int flag = 0;
        for (int i = 0; i < list1.size(); i++) {
            for (int j = 0; j < list1.get(i).size(); j++) {
                if (n == list1.get(i).get(j)) {
                    flag = i;
                    break;
                }
            }
        }
        return flag;
    }
}
5.发牌
先将15个元素转化为数组
    /**
     * 元素转为数组
     *
     * @param list11
     * @return
     */
    private static int[] card_toArr(List<ArrayList<Integer>> list11) {
        int[] arr = new int[15];
        int k = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                arr[k] = list11.get(i).get(j);
                k++;
            }
        }
        return arr;
    }
发牌
    /**
     * 发牌
     *
     * @param list2
     * @param list1
     */
    private static void deal(List<ArrayList<Integer>> list1, List<ArrayList<Integer>> list2) {
        int[] card_arr = card_toArr(list1);
        int j = 0;
        int count = 0;
        for (int i = 0; i < 15; i++) {
            int num = card_arr[i];
            int index = i % 3;
            list2.get(index).set(j, num);
            count++;
            if (count % 3 == 0)
                j++;
        }
    }
四、完整代码
import java.util.*;
public class Main {
    public static List<ArrayList<Integer>> list1 = new ArrayList<>();
    public static List<Integer> list1_1 = new ArrayList<>();
    public static List<Integer> list1_2 = new ArrayList<>();
    public static List<Integer> list1_3 = new ArrayList<>();
    public static List<ArrayList<Integer>> list2 = new ArrayList<>();
    public static List<Integer> list2_1 = new ArrayList<>();
    public static List<Integer> list2_2 = new ArrayList<>();
    public static List<Integer> list2_3 = new ArrayList<>();
    static {
        Integer[] list_1_arr = {0, 0, 0, 0, 0};
        Integer[] list_2_arr = {0, 0, 0, 0, 0};
        Integer[] list_3_arr = {0, 0, 0, 0, 0};
        addNumInArr(list_1_arr, 1);
        addNumInArr(list_2_arr, 6);
        addNumInArr(list_3_arr, 11);
        list1_1.addAll(Arrays.asList(list_1_arr));
        list1_2.addAll(Arrays.asList(list_2_arr));
        list1_3.addAll(Arrays.asList(list_3_arr));
        list1.add((ArrayList<Integer>) list1_1);
        list1.add((ArrayList<Integer>) list1_2);
        list1.add((ArrayList<Integer>) list1_3);
        list2.add((ArrayList<Integer>) list2_1);
        list2.add((ArrayList<Integer>) list2_2);
        list2.add((ArrayList<Integer>) list2_3);
    }
    /**
     * 向数组添加不重复元素
     *
     * @param list_1_arr
     * @param n2         生成随机值的偏移量
     */
    private static void addNumInArr(Integer[] list_1_arr, int n2) {
        Random ran = new Random();
        int count = 0;
        while (true) {
            for (int i = 0; i < 5; i++) {
                while (true) {
                    boolean flag = true;
                    boolean flag2 = false;
                    int num = ran.nextInt(5) + n2;
                    for (int j = 0; j < 5; j++) {
                        if (num == list_1_arr[j]) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        list_1_arr[i] = num;
                        count++;
                        flag2 = true;
                    }
                    if (flag2)
                        break;
                }
            }
            if (count == 5)
                break;
        }
    }
    public static void main(String[] args) {
        Scanner sca = new Scanner(System.in);
        menu();
        int n = sca.nextInt();
        System.out.println("初始牌:");
        System.out.println(list1);
        System.out.println("第一次洗牌后:");
        riffle(list1, list2, n);//洗牌
        System.out.println(list2);
        System.out.println("发牌后:");
        deal(list2, list1);//发牌
        System.out.println(list1);
        System.out.println("第二次洗牌后:");
        riffle(list1, list2, n);//洗牌
        System.out.println(list2);
        System.out.println("发牌后:");
        deal(list2, list1);//发牌
        System.out.println(list1);
        System.out.println("第三次洗牌后:");
        riffle(list1, list2, n);//洗牌
        System.out.println(list2);
        System.out.println("------------------------------------------------------------");
        System.out.println("----------------------------第四次---------------------------");
        System.out.println("------------------------------------------------------------");
        System.out.println("发牌后:");
        deal(list2, list1);//发牌
        System.out.println(list1);
        System.out.println("第四次洗牌后:");
        riffle(list1, list2, n);//洗牌
        System.out.println(list2);
        System.out.println("------------------------------------------------------------");
        System.out.println("----------------------------第五次---------------------------");
        System.out.println("------------------------------------------------------------");
        System.out.println("发牌后:");
        deal(list2, list1);//发牌
        System.out.println(list1);
        System.out.println("第五次洗牌后:");
        riffle(list1, list2, n);//洗牌
        System.out.println(list2);
        System.out.println("------------------------------------------------------------");
    }
    /**
     * 菜单栏
     */
    private static void menu() {
        System.out.println("-------------------------------------------------------");
        System.out.println("魔术,随机让玩家记住一张牌,通过游戏规则变换三次后即可猜出那张牌");
        System.out.println("洗牌:将带有输入数字的一组牌放到中间位置");
        System.out.println("发牌:按照洗牌后的顺序发牌");
        System.out.println("-------------------------------------------------------");
        System.out.println("#######################################################");
        System.out.println("游戏规则:");
        System.out.println("1:让玩家从15张牌中随机选出一张记下【选中牌】");
        System.out.println("2:将15张牌按照顺序发牌,分为3组,每组5张");
        System.out.println("3:依次询问每组牌是否包含【选中牌】");
        System.out.println("4:将包含【选中牌】的那组放到中间,另外两组随意");
        System.out.println("5:重复步骤2,3,4,保证洗牌次数大于等于3后,即可在中间那组的第3张找到【选中牌】");
        System.out.println("#######################################################");
        System.out.println("请输入1——15之间的一个数字:");
    }
    /**
     * 发牌
     *
     * @param list2
     * @param list1
     */
    private static void deal(List<ArrayList<Integer>> list1, List<ArrayList<Integer>> list2) {
        int[] card_arr = card_toArr(list1);
        int j = 0;
        int count = 0;
        for (int i = 0; i < 15; i++) {
            int num = card_arr[i];
            int index = i % 3;
            list2.get(index).set(j, num);
            count++;
            if (count % 3 == 0)
                j++;
        }
    }
    /**
     * 元素转为数组
     *
     * @param list11
     * @return
     */
    private static int[] card_toArr(List<ArrayList<Integer>> list11) {
        int[] arr = new int[15];
        int k = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                arr[k] = list11.get(i).get(j);
                k++;
            }
        }
        return arr;
    }
    /**
     * 洗牌
     *
     * @param list1
     * @param list2
     * @param n     选定的数字
     */
    private static void riffle(List<ArrayList<Integer>> list1, List<ArrayList<Integer>> list2, int n) {
        int index = getNumInList(list1, n);
        list2.set(1, list1.get(index));
        Random ran = new Random();
        int a = 0;
        if (a != index) {
            list2.set(0, list1.get(a));
        } else {
            while (true) {
                a = ran.nextInt(3);
                if (a != index) {
                    list2.set(0, list1.get(a));
                    break;
                }
            }
        }
        int b = 0;
        while (true) {
            b = ran.nextInt(3);
            if (b != index && b != a) {
                list2.set(2, list1.get(b));
                break;
            }
        }
    }
    /**
     * 查找指定元素在大集合中的索引(0 1 2)
     *
     * @param list1
     * @param n
     * @return
     */
    private static int getNumInList(List<ArrayList<Integer>> list1, int n) {
        int flag = 0;
        for (int i = 0; i < list1.size(); i++) {
            for (int j = 0; j < list1.get(i).size(); j++) {
                if (n == list1.get(i).get(j)) {
                    flag = i;
                    break;
                }
            }
        }
        return flag;
    }
}
五、效果展示

 



















