猜數位遊戲(偽亂數對猜數位遊戲的影響)

2020-10-19 16:00:25

猜數位遊戲的實現 

   由系統隨機產生一個100內的數位,要求使用者猜測這個整數。輸入一個猜測想的整數,判斷是否與產生的亂數相等,由螢幕顯示判斷結果。如果猜得不對,給出「大了」或「小了」的提示,直到猜出這個數為止。

猜數位遊戲的邏輯:

     1.程式自動生成一個隨機的1-100的整數。
     2.使用者來輸入一個整數。
     3.系統會根據輸入情況來提示使用者,是猜高了,還是低了,還是猜對了。


首先,我們需要一個選單來實現和使用者的互動:

我們通過menu()這個函數來實現和使用者的互動,函數的返回值為choice的值,輸入1表示開始遊戲,輸入0表示退出遊戲。

int menu() {
	printf("=============================\n");
	printf(" 1. 開始遊戲\n");
	printf(" 0. 退出遊戲\n");
	printf("=============================\n");
	printf(" 請輸入您的選擇: ");
	int choice = 0;
	scanf("%d", &choice);
	return choice;
}

 


其次我們需要來完成這個遊戲函數:

猜數位的邏輯:

1. 程式自動生成一個 1-100 的隨機整數。

2. 從控制檯讀取使用者的輸入。

3. 比較使用者輸入的數位和系統生成的數位之間的關係,並給使用者提示。

void game() {
	// 1. 程式自動生成一個 1-100 的隨機整數. 
	int toGuess = rand() % 100 + 1;
	while (1) {
		// 2. 從控制檯讀取使用者的輸入. 
		printf("請輸入要猜的數位: ");
		int input = 0;
		scanf("%d", &input);
		// 3. 比較使用者輸入的數位和系統生成的數位之間的關係, 並給使用者提示. 
		if (input < toGuess) {
			printf("低了!\n");
		} else if (input > toGuess) {
			printf("高了!\n");
		} else {
			printf("猜對了!\n");
			break;
		}
	}
}

下面我們在主函數中呼叫他們,實現猜數位遊戲:

int main() {

	while (1) {
		// 呼叫選單函數, 和使用者進行互動
		int choice = menu();
		if (choice == 1) {
			game();
		} else if (choice == 0) {
			printf("程式退出, 再見!\n");
			break;
		} else {
			// 寫程式得考慮到使用者的非法輸入的情況.
			printf("您的輸入有誤, 請重新輸入!\n");
		}
	}

	system("pause");
	return 0;
}

到此這個猜數位遊戲已經基本實現,下面我們來測試一下:

我們可以看到三次進行遊戲得到的結果是:第一次42,第二次68,第三次35。


退出程式,我們再來玩一次猜數位:

我們可以看出:得到的

第一個元素始終是42,第二個元素始終是68,第三個元素始終是35……

 

由此我們可以知道當前的猜數位遊戲還是存在問題的,這個問題是什麼呢?

經過多次重複執行程式後,得到的亂數序列是固定序列。

為什麼會出現這個問題呢?

通過查閱一些資料瞭解到:

計算機不可能產生真正的亂數。在這裡,我們使用的亂數是將亂數種子(srand函數介紹的引數)作為初始條件,經過一定的計算產生的。

這麼說可能會有一點難以理解,我們來舉個遊戲中的例子:

比如LOL就有一套獨立的偽隨機機制,以25%暴擊舉例,如果蠻王第一刀沒暴擊,第二刀也沒暴擊,第三刀還是沒暴擊,那麼第四刀暴擊的機率就會大大的提升(不是25%),相信很多玩遊戲的同學都會有這種體會,這裡的暴擊就是一個偽亂數。

那麼怎麼解決這個問題讓偽隨機變成真隨機呢?

上面我們知道了:亂數是將亂數種子(srand函數介紹的引數)作為初始條件,經過一定的計算產生的。

亂數種子相同,得到的亂數序列就是相同的。

亂數種子不同,得到的亂數序列就是不同的。

所以,我們只需要設定不同的亂數種子就能解決這個問題,在這裡我們使用時間(計算機中用整數表示時間)作為亂數種子.


使用srand(time(0))調整亂數種子。讓我們執行兩次,來看下程式碼的執行結果:

第一次

結果是27,66。


第二次

結果是44,85。

可以看出調整亂數種子後,亂數序列就不同了,猜數位遊戲也就實現了。


完整的程式碼:

VS2013

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int menu() {
	printf("=============================\n");
	printf(" 1. 開始遊戲\n");
	printf(" 0. 退出遊戲\n");
	printf("=============================\n");
	printf(" 請輸入您的選擇: ");
	int choice = 0;
	scanf("%d", &choice);
	return choice;
}
void game() {
	int toGuess = rand() % 100 + 1;
	while (1) {
		printf("請輸入要猜的數位: ");
		int input = 0;
		scanf("%d", &input);
		if (input < toGuess) {
			printf("低了!\n");
		}
		else if (input > toGuess) {
			printf("高了!\n");
		}
		else {
			printf("猜對了!\n");
			break;
		}
	}
}
int main() {
	srand(time(0)); 
	while (1) {
		int choice = menu();
		if (choice == 1) {
			game();
		}
		else if (choice == 0) {
			printf("程式退出, 再見!\n");
			break;
		}
		else {
			printf("您的輸入有誤, 請重新輸入!\n");
		}
	}
	system("pause");
	return 0;
}