斗地主之洗牌(shuffle)程序的测试程序

        在博文http://coolshell.cn/articles/8593.html中, 皓哥已经详细讨论了各种shuffle程序, 并给出了测试的结果, 但博文中没有提供测试代码。 其实, 测试代码也很简单, 在本文中, 我来写一下测试代码。


        在之前的博文http://blog.csdn.net/stpeace/article/details/46583277中, 我已经给出了自己写的一个简单的shuffle程序, 现摘录如下:

#include 
#include 
#define N 10
using namespace std;

void initArr(int a[], int n)
{
	int i = 0;
	for(i = 0; i < n; i++)
	{
		a[i] = i + 1;
	}
}

void shuffleArr(int a[], int n)
{
	int i = 0;
	int tmp = 0;

	for(i = 0; i < n; i++)
	{
		int r1 = rand() % n;
		int r2 = rand() % n;
		tmp = a[r1];
		a[r1] = a[r2];
		a[r2] = tmp;
	}
}

void printArr(const int a[], int n)
{
	int i = 0;
	for(i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}

	cout << endl;
}

int main()
{
	srand(time(NULL));

	int i = 0;
	for(i = 0; i < 20; i++)
	{
		int a[N] = {0};
		initArr(a, N);
		shuffleArr(a, N);
		printArr(a, N);
	}

	return 0;
}
       这个shuffle程序的随机程度如何呢? 我来写个测试程序玩玩:

#include 
#include 
#define N 10 // 共有10张牌,标号为:1, 2, 3, 4, 5, 6, 7, 8, 9, 10
using namespace std;

// 记录最终测试结果, 其中shuffleTestArr[i][j]表示标号为i+1的牌出现在j+1位置的次数
int shuffleTestArr[N][N] = {0};

// poker初始化
void initArr(int a[], int n)
{
	int i = 0;
	for(i = 0; i < n; i++)
	{
		a[i] = i + 1;
	}
}

// 洗一洗poker, 洗刷刷洗刷刷
void shuffleArr(int a[], int n)
{
	int i = 0;
	int tmp = 0;

	for(i = 0; i < n; i++)
	{
		// 随机交换
		int r1 = rand() % n;
		int r2 = rand() % n;
		tmp = a[r1];
		a[r1] = a[r2];
		a[r2] = tmp;
	}
}

// 打印最终结果:
void printTwoDimenArr(const int x[][N], int n)
{
	int i = 0;
	int j = 0;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < N; j++)
		{
			if(0 == j)
			{
				printf("%2d|", i + 1);
			}

			printf("%8d", x[i][j]);
		}

		cout << endl;
	}

	cout << endl;
}

int main()
{
	srand(time(NULL));

	int i = 0;
	int j = 0;
	int k = 0;
	for(i = 0; i < 1000000; i++)  // 测试100万次
	{
		int a[N] = {0};
		initArr(a, N);
		shuffleArr(a, N); // 洗刷刷, 洗刷刷, 咚咚

		for(j = 0; j < N; j++) // 列,  j+1表示位置
		{
			for(k = 0; k < N; k++) // k+1 = 1, 2, 3, 4, 5, 6, 7, 8, 9,10,表示牌的标号
			{
				if(k + 1 == a[j])
				{
					shuffleTestArr[k][j]++;
				}
			}
		}
	}

	cout << endl;

	for(i = 0; i < N; i++)
	{
		if(0 == i)
		{
			cout << "   ";
		}

		printf("%8d", i + 1);
	}
	
	cout << endl;
	cout << "    --------------------------------------"
	"-----------------------------------------" << endl;

	printTwoDimenArr(shuffleTestArr, N);

	return 0;
}
        结果为:

斗地主之洗牌(shuffle)程序的测试程序_第1张图片

        我们看看这是个什么意思(看第一列):

        196905表示牌1出现在1的位置的次数

        88891表示牌2出现在1的位置的次数

        依次类推。


        测试100万次, 按理说, 每个位置最后的统计数字应该接近:(10*1000000)/(10*10) = 100000,  看看上图, 大多数位置接近9万, 但是, 主对角线的值却很大, 都快20万了。 这说明什么呢? 说明很多情况下, 牌x放在x位置后, 不容易被置换走, 所以, 我之前写的洗牌算法并不太随机, 有待提高。 皓哥的博客给了很多shuffle程序, 大家可以参考:http://coolshell.cn/articles/8593.html


       OK, 本文的主要目的是写一下shuffle程序的测试程序, 玩poker就到此为止吧。





      

你可能感兴趣的:(S1:,C/C++,S3:,趣味思路)