九王(9Kings)与组合样本生成算法
《九王》,又名《9Kings》是一款深受博主青睐的游戏,其玩法围绕打牌构筑各种类型地块,与前来进犯的敌军战斗展开,其中,各种地块摆放的位置产生的效果相异,长期影响构筑策略。

博主寻思编写程序生成全部的位置组合。确定待摆放地块数量和地块总数后,全部的摆放位置组合也确定了,

上图摆放位置组合[1,2,3]

上图摆放位置组合[1,3,4]
其组合数量等于公式
for 循环或递归搭配迭代器算法组合均可生成摆放位置组合样本,下面介绍两种算法原理。
for 循环
for 循环嵌套层数和摆放地块数目相等。
摆放地块数目等一时
for(i = 1,2...总地块数目)
创建数组[i]存入二维数组[[i],[i]....]
摆放地块数目等二时
for(i = 1,2...总地块数目-1)
for(j = i+1,i+2...总地块数目)
创建数组[i,j]存入二维数组[[i,j],[i,j]....]
摆放地块数目等三时
for(i = 1,2...总地块数目-2)
for(j = i+1,i+2...总地块数目-1)
for(k = j+1,j+2...总地块数目)
创建数组[i,j,k]存入二维数组[[i,j,k],[i,j,k]....]
摆放地块数目等n时
for(i = 1,2...总地块数目-(n-1))
for(j = i+1,i+2...总地块数目-(n-2))
for(k = j+1,j+2...总地块数目-(n-3))
....
for(l....总地块-(n-n))
创建数组[i,j,k,l...]存入二维数组[[i,j,k,l...],[i,j,k,l...]....]
递归搭配迭代器
示例中,递归嵌套层数和摆放地块数目加一相等。
此处省略数组迭代器、数组迭代器的迭代器与业务类源码,源码请见末尾的附录标题处
void getSamples(int lvl, int init) {
if(lvl == 摆放地块数) {
数组的迭代器的迭代器中存入新创建的数组迭代器
} else {
for(int i=init;i<总地块数-摆放地块数+递归层数+1;i++) {
int beforeIndex = 一维数组迭代器的迭代器取当前索引;
getSamples(1+lvl,i+1);//递归
int afterIndex = 一维数组迭代器的迭代器取当前索引;
for (遍历小于等于 afterIndex 至大于 beforeIndex 的数) {
取数组迭代器的迭代器当前的索引标记的数组迭代器,向其存入i
}
}
}
}
该递归函数的 else 分支部分是精华,下面将该精华的的执行情形分成两种,一种是 else 分支开始,从递归位置进入下一个递归的 if 分支再返回该递归位置向下执行至 for 遍历小于等于 afterIndex 至大于 beforeIndex 的数结束。一种是 else 分支开始,从递归位置进入下一个递归的 else 分支再返回该递归位置向下执行至 for 遍历小于等于 afterIndex 至大于 beforeIndex 的数结束。
下图展示第一种情形的数据结构变化

下图展示第二种情形的数据结构变化

附录
数组迭代器
import java.util.Iterator;
public class ArrIterator implements Iterable<Integer>/* ,Cloneable*/{
Integer[] store;
private int index = -1;
public ArrIterator(int numOfOneSample) {
super();
store= new Integer[numOfOneSample];
}
@Override
public Iterator<Integer> iterator() {
return new Itr();
}
public void append(Integer e) {
store[++index] = e;
if(index == store.length - 1)
index = -1;
}
private class Itr implements Iterator<Integer> {
int cursor = index==-1?store.length-1:index;
int count = store.length;
@Override
public boolean hasNext() {
return count>0;
}
@Override
public Integer next() {
count--;
Integer e = store[cursor];
cursor = cursor == 0?store.length-1:cursor-1;
return e;
}
}
}
数组迭代器的迭代器
import java.util.Iterator;
public class ItrsIterator implements Iterable<ArrIterator> {
private ArrIterator[] store;
private int index = -1;
public int getIndex() {
return index;
}
public ArrIterator getArrItr(int index) {
return store[index];
}
public ItrsIterator(int numOfSamples) {
super();
store= new ArrIterator[numOfSamples];
System.out.println("numOfSamples="+numOfSamples);
}
@Override
public Iterator<ArrIterator> iterator() {
return new Itr();
}
public void append(ArrIterator e) {
store[++index] = e;
if(index == store.length - 1)
index = -1;
}
private class Itr implements Iterator<ArrIterator> {
int cursor = index==-1?store.length-1:index;
int count = store.length;
@Override
public boolean hasNext() {
return count>0;
}
@Override
public ArrIterator next() {
count--;
ArrIterator e = store[cursor];
cursor = cursor == 0?store.length-1:cursor-1;
return e;
}
}
}
业务层
package test9;
import java.util.Arrays;
import java.util.Iterator;
public class Assembler {
private ItrsIterator itrsIterator;
private final int NUM_OF_GRIDS;
private final int NUM_OF_ONE_SAMPLE;
private int numOfSamples;
public Assembler(int numOfGrids,int numOfOneSample) {
this.NUM_OF_ONE_SAMPLE = numOfOneSample;
this.NUM_OF_GRIDS = numOfGrids;
this.calNumOfSamples(0, 0);
this.itrsIterator = new ItrsIterator(this.numOfSamples);
}
//计算数组迭代器的迭代器中容器的长度
private void calNumOfSamples(int lvl,int init) {
if(lvl == this.NUM_OF_ONE_SAMPLE) {
this.numOfSamples++;
} else {
for(int i=init;i<NUM_OF_GRIDS-NUM_OF_ONE_SAMPLE+lvl+1;i++) {
calNumOfSamples(1+lvl,i+1);
}
}
}
//获取组合样本的递归方法
void getSamples(int lvl, int init) {
if(lvl == this.NUM_OF_ONE_SAMPLE) {
this.itrsIterator.append(new ArrIterator(this.NUM_OF_ONE_SAMPLE));
} else {
for(int i=init;i<NUM_OF_GRIDS-NUM_OF_ONE_SAMPLE+lvl+1;i++) {
int beforeIndex = this.itrsIterator.getIndex();
System.out.println("before callback,index="+beforeIndex);
getSamples(1+lvl,i+1);
int afterIndex = this.itrsIterator.getIndex();
System.out.println("after callback,afterIndex="+afterIndex);
for (int j = afterIndex == -1 ? this.numOfSamples-1:afterIndex; j > beforeIndex; j--) {
this.itrsIterator.getArrItr(j).append(i);
}
}
}
}
//遍历数组迭代器的迭代器和数组迭代器
void iterateItrs() {
Iterator<ArrIterator> iterators = this.itrsIterator.iterator();
while(iterators.hasNext()) {
ArrIterator arrItr = iterators.next();
Iterator<Integer> iterator = arrItr.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next()+" ");
}
System.out.println();
}
}
}
浙公网安备 33010602011771号