本文介紹了25個不錯PHP的游戲編程腳本代碼,包括簡單的擲骰器、隨機名稱生成器、場景生成器、牌組創建器(Deck builder)和裝備(shuffler)、簡單的撲克發牌器、Hangman游戲、縱橫字謎助手、米德裡比斯、樂透機等。希望能夠對你的工作有所幫助。
簡單的擲骰器
許多游戲和游戲系統都需要骰子。讓我們先從簡單的部分入手:擲一個六面骰子。實際上,滾動一個六面骰子就是從 1 到 6 之間選擇一個隨機數字。在 PHP 中,這十分簡單:echo rand(1,6);。
在許多情況下,這基本上很簡單。但是在處理機率游戲時,我們需要一些更好的實現。PHP 提供了更好的隨機數字生成器:mt_rand()。在不深入研究兩者差別的情況下,可以認為 mt_rand 是一個更快、更好的隨機數字生成器:echo mt_rand(1,6);。如果把該隨機數字生成器放入函數中,則效果會更好。
清單 1. 使用 mt_rand() 隨機數字生成器函數
function roll () {
return mt_rand(1,6);
}
echo roll();
然後可以把需要滾動的骰子類型作為參數傳遞給函數。
清單 2. 將骰子類型作為參數傳遞
function roll ($sides) {
return mt_rand(1,$sides);
}
echo roll(6); // roll a six-sided die
echo roll(10); // roll a ten-sided die
echo roll(20); // roll a twenty-sided die
從這裡開始,我們可以繼續根據需要一次滾動多個骰子,返回結果數組;也可以一次性滾動多個不同類型的骰子。但是大多數任務都可以使用這個簡單的腳本。
隨機名稱生成器
如果正在運行游戲、編寫故事或者一次性創建大批字符,有時會疲於應付不斷出現的新名字。讓我們看一看可用於解決此問題的一個簡單隨機名稱生成器。首先,讓我們創建兩個簡單數組 — 一個用於名字,一個用於姓氏。
清單 3. 名字和姓氏的兩個簡單數組
$male = array(
"William",
"Henry",
"Filbert",
"John",
"Pat",
);
$last = array(
"Smith",
"Jones",
"Winkler",
"Cooper",
"Cline",
);
然後就可以從每個數組中選擇一個隨機元素:echo $male[array_rand($male)] . . $last[array_rand($last)];。要一次性提取多個名稱,只需混合數組並根據需要提取。
清單 4. 混合名稱數組
shuffle($male);
shuffle($last);
for ($i = 0; $i <= 3; $i++) {
echo $male[$i] . . $last[$i];
}
基於此基本概念,我們可以創建保存名字和姓氏的文本文件。如果在文本文件的每一行中存放一個名字,則可以輕松地用換行符分隔文件內容以構建源代碼數組。
清單 5. 創建名稱的文本文件
$male = explode( , file_get_contents(names.female.txt));
$last = explode( , file_get_contents(names.last.txt));
構建或查找一些好的名字文件(代碼歸檔 中附帶了一些文件),此後我們絕不再需要為名字煩惱。
場景生成器
利用構建名字生成器使用的相同基本原理,我們可以構建場景生成器。此生成器不但在角色扮演游戲中十分有用,而且在需要用到偽隨機環境集合(可用於角 色扮演、即興創作、寫作等情況)的情況下也十分有用。我最喜歡的游戲之一,Paranoia 在其 GM Pack 中包括了 “任務混合器(mission blender)”。任務混合器可用於在快速滾動骰子時整合完整任務。讓我們整合自己的場景生成器。
考慮以下場景:您醒來後發現自己迷失於叢林中。您知道自己必須趕去紐約,但是不知道原因。您可以聽到附近的狗叫聲及清晰的敵方搜尋者的聲音。您渾身發冷、不住顫抖,而且沒有武器。該場景中的每一句話都介紹場景的特定方面:
“您醒來後發現自己迷失於叢林中” — 這句話將建立設置。
“您知道自己必須趕去紐約” — 這句話將描述目標。
“您可以聽到狗叫聲” — 這句話將介紹敵人。
“您渾身發冷、不住顫抖,而且沒有武器” — 這句話將添加復雜度。
就像創建名字和姓氏的文本文件一樣,首先分別創建設置、目標、敵人和復雜度的文本文件。代碼歸檔中附帶了樣例文件。在擁有這些文件後,生成場景的代碼與生成名稱的代碼基本相同。
清單 6. 生成場景
$settings = explode(" ", file_get_contents(scenario.settings.txt));
$objectives = explode(" ", file_get_contents(scenario.objectives.txt));
$antagonists = explode(" ", file_get_contents(scenario.antagonists.txt));
$complicati**** = explode(" ", file_get_contents(scenario.complicati****.txt));
shuffle($settings);
shuffle($objectives);
shuffle($antagonists);
shuffle($complicati****);
echo $settings[0] . . $objectives[0] . . $antagonists[0] .
. $complicati****[0] . " ";
我們可以通過添加新文本文件向場景中添加元素,也可能希望添加多重復雜度。添加到基本文本文件中的內容越多,場景隨時間的變化就越多。
牌組創建器(Deck builder)和裝備(shuffler)
如果您要玩紙牌並且要處理與紙牌相關的腳本,我們需要用裝備中的工具整合一副牌組構建器。首先,讓我們構建一副標准紙牌。需要構建兩個數組 — 一個用於保存同花色的組牌,而另一個用於保存牌面。如果稍後需要添加新組牌或牌類型,則這樣做將獲得很好的靈活性。
清單 7. 構建一副標准撲克牌
$suits = array (
"Spades", "Hearts", "Clubs", "Diamonds"
);
$faces = array (
"Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Jack", "Queen", "King", "Ace"
);
然後構建一副牌數組來保存所有紙牌值。只需使用一對 foreach 循環即可完成此操作。
清單 8. 構建一副牌數組
$deck = array();
foreach ($suits as $suit) {
foreach ($faces as $face) {
$deck[] = array ("face"=>$face, "suit"=>$suit);
}
}
在構建了一副撲克牌數組後,我們可以輕松地洗牌並隨機抽出一張牌。
清單 9. 洗牌並隨機抽出一張牌
shuffle($deck);
$card = array_shift($deck);
echo $card[face] . of . $card[suit];
現在,我們就獲得了抽取多副牌或構建多層牌盒(multideck shoe)的捷徑。
勝率計算器:發牌
由於構建撲克牌時會分別跟蹤每張牌的牌面和花色,因此可以通過編程方式利用這副牌來計算得到特定牌的幾率。首先每只手分別抽出五張牌。
清單 10. 每只手抽出五張牌
$hands = array(1 => array(), 2=>array());
for ($i = 0; $i < 5; $i++) {
$hands[1][] = implode(" of ", array_shift($deck));
$hands[2][] = implode(" of ", array_shift($deck));
}
然後可以查看這副牌,看看剩余多少張牌以及抽到特定牌的機率是多少。查看剩余的牌數十分簡單。只需要計算 $deck 數組中包含的元素數。要獲得抽到特定牌的機率,我們需要一個函數來遍歷整副牌並估算其余牌以查看是否匹配。
清單 11. 計算抽到特定牌的幾率
function calculate_odds($draw, $deck) {
$remaining = count($deck);
$odds = 0;
foreach ($deck as $card) {
if ( ($draw[face] == $card[face] && $draw[suit] ==
$card[suit] ) ||
($draw[face] == && $draw[suit] == $card[suit] ) ||
($draw[face] == $card[face] && $draw[suit] == ) ) {
$odds++;
}
}
return $odds . in $remaining;
}
現在可以選出嘗試抽出的牌。為了簡單起見,傳入看上去類似某張牌的數組。我們可以查找特定的一張牌。
清單 12. 查找指定的一張牌
$draw = array(face => Ace, suit => Spades);
echo implode(" of ", $draw) . : . calculate_odds($draw, $deck);
或者可以查找指定牌面或花色的牌。
清單 13. 查找指定牌面或花色的牌
$draw = array(face => , suit => Spad