最近看到一个小游戏倒水瓶很火, 就想用java来实现一下
实现思路
- 先确定瓶子和颜色的数量, 比如5种颜色, 那么就需要5+1个瓶子, 然后前5个瓶子每个瓶子倒满一种颜色, 每种颜色各5块, 最后一个是空瓶
- 然后就是随机打乱瓶中色块
- 最后将最后一个瓶子中的色块匀到其他瓶中, 一个关卡就生成了
- 水瓶色块复原可以使用暴力破解, 就是随机倒色块, 只要两个色块颜色相同, 就把他们绑死, 永不分离, 但有时会遇到无法破解的关卡, 比如色块不能再倒入其他瓶中, 这时可以重新生成关卡
- 将关卡打印结果复制到excel中, 就可以愉快的玩耍了
代码
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;
/**
* 倒水瓶游戏
* 黄色 绿色 绿色 黄色 蓝色 橙色 蓝色
* 绿色 橙色 紫色 橙色 红色 靛色 靛色
* 橙色 黄色 橙色 绿色 红色 靛色 红色
* 紫色 绿色 黄色 黄色 蓝色 紫色 紫色
* 靛色 绿色 橙色 紫色 紫色 绿色 红色
* 蓝色 靛色 紫色 红色 红色 黄色 靛色
* 红色 黄色 蓝色 蓝色 橙色 蓝色 靛色
*/
public class WaterBottle {
@Test
public void test0927() {
// 混乱次数
int num = 10000;
// 色块可以随意加减
Stack<String> e = new Stack<>();
e.add("红色");
e.add("橙色");
e.add("黄色");
e.add("绿色");
e.add("蓝色");
e.add("靛色");
e.add("紫色");
// 颜色数量
int colorCount = e.size();
// 保存所有的水瓶, 以及水瓶中的颜色
List<Stack<String>> list = new ArrayList<>();
for (int i=0; i<colorCount; i++) {
Stack<String> a = new Stack<>();
String color = e.pop();
for (int j=0; j<colorCount; j++) {
a.add(color);
}
list.add(a);
}
// 空水瓶
Stack<String> a = new Stack<>();
list.add(a);
// 1.打乱颜色
Random random = new Random();
while (num > 0) {
// 被倒入瓶子
int index = random.nextInt(colorCount+1);
while (list.get(index).size() == colorCount) {
index = random.nextInt(colorCount+1);
}
// 倒出瓶子
int index2 = random.nextInt(colorCount+1);
while (list.get(index2).isEmpty() || index2 == index) {
index2 = random.nextInt(colorCount+1);
}
// 倒出个数
int count = random.nextInt(Math.min(list.get(index2).size(),colorCount - list.get(index).size()) + 1);
for (int j=0; j<count; j++) {
list.get(index).add(list.get(index2).pop());
}
num--;
}
// 将最后一个瓶子置空
if (!list.get(colorCount).isEmpty()) {
for (int i=0; i<list.size()-1; i++) {
int temp = colorCount-list.get(i).size();
for (int j=0; j<temp; j++) {
list.get(i).add(list.get(colorCount).pop());
}
}
}
// 打印结果
/*for (int i=0; i<colorCount; i++) {
StringBuilder sb = new StringBuilder();
for (int j=0; j<list.size()-1; j++) {
sb.append(list.get(j).pop()).append("\t");
}
System.out.println(sb);
}*/
// 2.恢复颜色
// 方法一, 随机倒, 但一旦两个相同颜色靠在一起,就永远不分开
num = 100000;
while (num > 0) {
// 倒出瓶子
int index2 = random.nextInt(colorCount+1);
if (list.get(index2).isEmpty()) {
continue;
}
// 倒出个数
int count = 0;
String outColor = list.get(index2).peek();
for (int i=list.get(index2).size()-1; i>-1; i--) {
if (outColor.equals(list.get(index2).get(i))) {
count++;
} else {
break;
}
}
// 被倒入瓶子
int index = random.nextInt(colorCount+1);
if (list.get(index).size() + count > colorCount || index2 == index) {
continue;
}
for (int j=0; j<count; j++) {
list.get(index).add(list.get(index2).pop());
}
num--;
}
System.out.println("dd");
}
}
示例
黄色 绿色 绿色 黄色 蓝色 橙色 蓝色
绿色 橙色 紫色 橙色 红色 靛色 靛色
橙色 黄色 橙色 绿色 红色 靛色 红色
紫色 绿色 黄色 黄色 蓝色 紫色 紫色
靛色 绿色 橙色 紫色 紫色 绿色 红色
蓝色 靛色 紫色 红色 红色 黄色 靛色
红色 黄色 蓝色 蓝色 橙色 蓝色 靛色