消極的自殺の記録

暁月分明 (tube_worm) が人生という消極的な自殺をしていくにあたっての記録です。

プログラミング初心者が書く神経衰弱シミュレーション

[Background]

 友達が神経衰弱の手数の確率分布を手計算で求めていたのでなんとなくシミュレーションプログラムを書いてしまいました。

 

 

[Code]

軽い気持ちでC++で書き始めてしまったのですが、結果Cの関数しか使いませんでした。勢いでパパッと書いてしまったので不要な部分や回り道をしている部分があるかも知れません。さらっと美しいコードが書けるように精進したいです……。

 

#include <iostream>

using namespace std;

void shuffle(int *ar, int size)
{
	for (int i = 0; i<size; i++)
	{
		int j = rand() % size;
		int t = ar[i];
		ar[i] = ar[j];
		ar[j] = t;
	}
}

int main()
{

	int tekazu[30];
	for (int i = 0; i < 30; i++)
		tekazu[i] = 0;

	int seed;
	for (seed = 0; seed < 100000; seed++)
	{

		srand(seed);


		//0~9が二枚ずつ存在
		int *field = (int*)malloc(sizeof(int)* 20);
		for (int i = 0; i < 20; i++)
		{
			field[i] = i % 10;
		}
		//場に存在するカード

		int flag = -1;	//二枚目が既知のカードの時に使用
		int size = 20;
		int *memory = (int *)malloc(sizeof(int)* 10);
		int count = 0;
		for (int i = 0; i<10; i++)
		{
			memory[i] = 0;
		}

		while (1)
		{
			int drawcardindex = rand() % size;
			int drawcard = field[drawcardindex];
			count ++;
			if (size == 2)	//場に存在するカードが二枚になったところで終了
				break;
			int temp = field[size - 1];
			field[drawcardindex] = temp;
			field[size - 1] = drawcard;
			shuffle(field, size - 1);
			if (memory[drawcard] || flag != -1) //一枚目にひいたカードが前にひいたことのあるカードのとき
			{
				if (flag != -1)
					drawcard = flag;
				int i = 0;
				int j = -1;
				while (1)
				{
					if (field[i] == drawcard)
					{
						if (j != -1)
							break;
						else
							j = i;
					}
					else
						i++;
				}

				int temp1 = field[size - 1];
				int temp2 = field[size - 2];
				field[i] = temp1;
				field[j] = temp2;
				field[size - 1] = drawcard;
				field[size - 2] = drawcard;
				shuffle(field, size-2);
				size = size - 2;
				flag = -1;
			}
			else
			{
				int nextdrawcardindex = rand() % (size - 1);
				int nextdrawcard = field[nextdrawcardindex];	//二枚目をひく
				if (nextdrawcard == drawcard)	//二枚目が一枚目と同じカードのとき
				{
					int temp1 = field[size - 2];
					field[nextdrawcardindex] = temp1;
					field[size - 2] = nextdrawcard;
					size = size - 2;
					shuffle(field, size);
				}
				else if (memory[nextdrawcard])	//二枚目が既知のときは、次の一枚目にそのカードをひく
				{
					memory[drawcard] ++;
					flag = nextdrawcard;
				}
				else
				{
					memory[drawcard] ++;
					memory[nextdrawcard] ++;
				}
			}
		}

		tekazu[count]++;

		free(memory);
		free(field);

	}

	for (int i = 0; i < 30; i++)
	{
		cout << i<<"\t"<<tekazu[i] << endl;
	}
	return 0;
}

[Result]

結果です。
f:id:tube_worm:20150616040713p:plain
16手が最大のように見えますが、なんだか最悪でも15手という噂を聞いてしまったので不安です。

※追記

mallocした意味ないですね。デバッグの時に血迷ってmallocしちゃいました。あとコード埋め込みをCとして行っていたのでC++に変更しました。