25個PHP遊戲編程腳本代碼

本文介紹的腳本易於理解、使用簡單並可以快速掌握。
簡單的擲骰器
許多遊戲和遊戲系統都需要骰子。讓我們先從簡單的部分入手:擲一個六面骰子。實際上,滾動一個六面骰子就是從 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] . "<br />
";

我們可以通過添加新文本文件向場景中添加元素,也可能希望添加多重復雜度。添加到基本文本文件中的內容越多,場景隨時間的變化就越多。
牌組創建器(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 => Spades);
  $draw = array(face => Ace, suit => );

簡單的撲克發牌器
現在已經得到牌組構建器和一些工具,可以幫助計算出抽出特定卡的機率,我們可以整合一個真正簡單的發牌器來進行發牌。出於本例的目的,我們將構建一個可以抽出五張牌的發牌器。發牌器將從整副牌中提供五張牌。使用數字指定需要放棄哪些牌,並且發牌器將用一副牌中

發佈留言