一、问题描述
这是一个魔术游戏,将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;
}
}
五、效果展示