关于杀人游戏传说中的位置学。
这几天一直玩多多游戏里的<杀人游戏警匪版>。有人认为这个游戏是有位置学的。就是说,根据警察的位置,可以定出匪徒的位置。反之亦然。并给出了一个位置关系表。我到目前为止玩了600多局。发现这个表确实准确率较高。所以我觉得这个多多游戏的位置分配方法应该不是很好。我设计了一个。如下:
首先是随机抽取算法。这个算法要做的是从1-N中随机抽取M个整数。并且有两个要求:
1.M个整数彼此不重复。
2.N个整数中每个数被抽中的概率相同。
下面给出这个算法的伪代码。(这个算法不是我想的,是<编程珠玑>第12章取样问题中给出的一个解决方案)
(PS:这个方案已经被证明每个数被抽中的概率相同了。我就不证明了哈哈)
selete = M
remaining = N
for i = [1,N]
if( rand() % remaining < selete )
print i
selete--
remaining--
模拟程序如下:(以标准局16人4V4为例。代码只是测试用的,所以各种硬编码各位莫拍啊)
void GetLocation1(){
int select = 4;
int number = 16;
srand((unsigned)time(NULL));
for(int i = 1; i <= 16; i++){
if( (rand() % number) < select ){
printf("%d/n", i);
select--;
}
number--;
}
}
生成的几组数据如下:
_____
1
5
8
14
_____
_____
1
3
10
16
_____
_____
3
12
13
16
_____
_____
2
5
12
16
_____
_____
7
8
10
12
_____
_____
1
3
10
13
_____
_____
2
3
4
15
_____
这样既可产生一个非平民角色的位置。把他们做为杀手。这样就剩下12个位置。这12个位置将产生4名警察。我们把上面程序中的number变量变为12.再把循环中的16变为12.既可在12个位置中产生警察。但是这里要做一个小处理。才能把产生的四个警察位置正确映射到他们应该的位置。
先把警察位的函数写下来:
void GetLocation2(){
int select = 4;
int number = 12;
srand((unsigned)time(NULL));
for(int i = 1; i <= 12; i++){
if( (rand() % number) < select ){
printf("%d/n", i);
select--;
}
number--;
}
}
然后是映射到真正位置的方法:(其中Table1[4]记录匪徒的位置。也就是第一次生成的4个数。Table2[4]记录警察位置,也就是第二次生成的四个数。警察位置需要做这个处理才能正确映射到真正位置。而且由于需要记录。那么之前GetLocation中的输出就要改正赋值了。)
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if(Table2[j] >= Table1[i]){
Table2[j]++;
}
}
}
最终的完整测试程序如下:需要说明的是。这个程序只是为了证明这个随机方法是可行的。没有考虑设计上的问题。所以这个程序只模拟了16人4V4的情况。其实GetLocation完全可以多带几个参数以适应各种情况。
GetLocation1(int *Table1){
int select = 4;
int number = 16;
srand((unsigned)time(NULL));
for(int i = 1; i <= 16; i++){
if( (rand() % number) < select ){
Table1[4 - select] = i;
select--;
}
number--;
}
}
void GetLocation2(int *Table2){
int select = 4;
int number = 12;
srand((unsigned)time(NULL));
for(int i = 1; i <= 12; i++){
if( (rand() % number) < select ){
Table2[4 - select] = i;
select--;
}
number--;
}
}
int main(int argc, char *argv[])
{
int Table1[4];
int Table2[4];
while(1){
GetLocation1(Table1);
GetLocation2(Table2);
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if(Table2[j] >= Table1[i]){
Table2[j]++;
}
}
}
printf("_____/n");
printf("F, J:/n");
for(int i = 0; i < 4; i++){
printf("%d, %d/n",Table1[i], Table2[i]);
}
printf("_____/n");
_sleep(1000);
}
system("PAUSE");
return EXIT_SUCCESS;
}
最后附上生成数据:
_____
F, J:
4, 2
5, 6
14, 9
15, 12
_____
_____
F, J:
2, 1
7, 3
9, 4
16, 6
_____
_____
F, J:
2, 7
4, 13
9, 14
10, 16
_____
_____
F, J:
1, 6
4, 11
5, 12
8, 16
_____
_____
F, J:
2, 1
7, 5
9, 6
16, 12
_____
_____
F, J:
7, 3
9, 4
12, 11
16, 13
_____
如果使用这种随机方案。就没有所谓的位置学这一说法了。