魔术游戏
- 一、问题描述
- 二、基本流程
- 三、具体步骤
- 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;}
}
五、效果展示