2010-03-01

关于杀人游戏传说中的位置学。

这几天一直玩多多游戏里的<杀人游戏警匪版>。有人认为这个游戏是有位置学的。就是说,根据警察的位置,可以定出匪徒的位置。反之亦然。并给出了一个位置关系表。我到目前为止玩了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
_____

如果使用这种随机方案。就没有所谓的位置学这一说法了。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值