清单 1. 简略的掷骰器
许多游戏和游戏零碎都须要骰子。让咱们先从简略的局部动手:掷一个六面骰子。实际上,滚动一个六面骰子就是从 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(‘n’, file_get_contents(‘names.female.txt’));
$last = explode(‘n’, file_get_contents(‘names.last.txt’));
构建或查找一些好的名字文件(代码归档 中附带了一些文件),尔后咱们绝不再须要为名字懊恼。
场景生成器
利用构建名字生成器应用的雷同基本原理,咱们能够构建场景生成器。此生成器岂但在角色扮演游戏中非常有用,而且在须要用到伪随机环境汇合 (可用于角色扮演、即兴创作、写作等状况) 的状况下也非常有用。我最喜爱的游戏之一,Paranoia 在其 GM Pack 中包含了“工作混合器(mission blender)”。工作混合器可用于在疾速滚动骰子时整合残缺工作。让咱们整合本人的场景生成器。
思考以下场景:您醒来后发现自己迷失于丛林中。您晓得本人必须赶去纽约,然而不晓得起因。您能够听到左近的狗叫声及清晰的敌方搜查者的声音。您浑身发冷、不住颤动,而且没有武器。该场景中的每一句话都介绍场景的特定方面:
“您醒来后发现自己迷失于丛林中”— 这句话将建设设置。
“您晓得本人必须赶去纽约”— 这句话将形容指标。
“您能够听到狗叫声”— 这句话将介绍敌人。
“您浑身发冷、不住颤动,而且没有武器”— 这句话将增加复杂度。
就像创立名字和姓氏的文本文件一样,首先别离创立设置、指标、敌人和复杂度的文本文件。代码归档中附带了样例文件。在领有这些文件后,生成场景的代码与生成名称的代码基本相同。
清单 6. 生成场景
$settings = explode(“n”, file_get_contents(‘scenario.settings.txt’));
$objectives = explode(“n”, file_get_contents(‘scenario.objectives.txt’));
$antagonists = explode(“n”, file_get_contents(‘scenario.antagonists.txt’));
$complicati = explode(“n”, file_get_contents(‘scenario.complicati.txt’));
shuffle($settings);
shuffle($objectives);
shuffle($antagonists);
shuffle($complicati**);
echo $settings[0] . ‘ ‘ . $objectives[0] . ‘ ‘ . $antagonists[0] . ‘ ‘
. $complicati**[0] . “
n”;
咱们能够通过增加新文本文件向场景中增加元素,也可能心愿增加多重复杂度。增加到根本文本文件中的内容越多,场景随工夫的变动就越多。
牌组创立器 (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’ => ”);
简略的扑克发牌器
当初曾经失去牌组构建器和一些工具,能够帮忙计算出抽出特定卡的机率,咱们能够整合一个真正简略的发牌器来进行发牌。出于本例的目标,咱们将构建一个能够抽出五张牌的发牌器。发牌器将从整副牌中提供五张牌。应用数字指定须要放弃哪些牌,并且发牌器将用一副牌中的其余牌替换这些牌。咱们无需指定发牌限度或非凡规定,然而您可能会发现这些是十分无益的集体教训。
如上一节所示,生成并洗牌,而后每只手五张牌。按数组索引显示这些牌,以便能够指定返回哪些牌。您能够应用示意要替换哪些牌的复选框来实现此操作
。
清单 14. 应用复选框示意要替换的牌
foreach ($hand as $index =>$card) {
echo “
” . $card[‘face’] . ‘ of ‘ . $card[‘suit’] . “
“;
}
而后,计算输出 array $_POST[‘card’],查看哪些牌已被抉择用于替换。
清单 15. 计算输出
$i = 0;
while ($i < 5) {
if (isset($_POST[‘card’][$i])) {
$hand[$i] = array_shift($deck);
}
}
应用此脚本,您能够尝试找到解决特定一组牌的最佳办法。
Hangman 游戏
Hangman 本质上是一款猜字游戏。给定单词的长度,咱们应用无限的几次机会猜这个单词。如果猜出了呈现在该单词中的一个字母,则填充该字母呈现的所有地位。在猜错若干次 (通常为六次) 后,您就输了较量。要构建一个简陋的 hangman 游戏,咱们须要从单词列表开始。当初,让咱们把单词列表制作成一个简略的数组。
清单 16. 创立单词列表
$words = array (
“giants”,
“triangle”,
“particle”,
“birdhouse”,
“minimum”,
“flood”
);
应用后面介绍的技术,咱们能够把这些单词挪动到内部单词列表文本文件中,而后依据须要导入。
在失去单词列表后,须要随机选出一个单词,将每个字母显示为空,而后开始猜想。咱们须要在每次进行猜想时跟踪正确和谬误的猜想。只需序列化猜想数组并在每次猜想时传递它们,就可实现跟踪目标。如果须要阻止人们通过查看页面源代码幸运猜对,则须要执行一些更平安的操作。
构建数组以保留字母和正确 / 谬误的猜想。对于正确的猜想,咱们将用字母作为键并用句点作为值填充数组。清单 17. 构建保留字母和猜想后果的数组
$letters = array(‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’,’i’,’j’,’k’,’l’,’m’,’n’,’o’,
‘p’,’q’,’r’,’s’,’t’,’u’,’v’,’w’,’x’,’y’,’z’);
$right = array_fill_keys($letters, ‘.’);
$wrong = array();
当初须要一些代码来评估猜想并在实现猜字游戏的过程中显示该单词。
清单 18. 评估猜想并显示进度
if (stristr($word, $guess)) {
$show = ”;
$right[$guess] = $guess;
$wordletters = str_split($word);
foreach ($wordletters as $letter) {
$show .= $right[$letter];
}
} else {
$show = ”;
$wrong[$guess] = $guess;
if (count($wrong) == 6) {
$show = $word;
} else {
foreach ($wordletters as $letter) {
$show .= $right[$letter];
}
}
}
在源代码归档 中,能够看到如何序列化猜想数组并将该数组从一次猜想传递到另一次猜想中。
纵横字谜助手
我晓得这样做不适合,然而有时在玩纵横拼字谜时,您不得不吃力地找出以 C 结尾并以 T 结尾、蕴含五个字母的单词。应用为 Hangman 游戏构建的雷同单词列表,咱们能够轻松地搜寻合乎某个模式的单词。首先,找到一种传输单词的办法。为了简略起见,用句点替换短少的字母:$guess = “c…t”;。因为正则表达式将把句点解决为单个字符,因而咱们能够轻松地遍历单词列表以查找匹配。
清单 19. 遍历单词列表
foreach ($words as $word) {
if (preg_match(“/^” . $_POST[‘guess’] . “$/”,$word)) {
echo $word . “
n”;
}
}
依据单词列表的品质及猜想的准确度,咱们该当可能失去正当的单词列表以用于可能的匹配。您必须本人决定“示意‘不按规定玩 ’ 的由五个字母组成的单词”的谜底是“chest”还是“cheat”。
米德里比斯
米德里比斯是一款文字游戏,玩家在游戏中失去一个简短的故事并用同一类型的不同单词替换次要类型的单词,从而创立同一个故事的更无聊的新版本。浏览以下文本:“I was walking in the park when I found a lake. I jumped in and swallowed too much water. I had to go to the hospital.”开始用其余单词标记替换单词类型。开始和完结标记带有下划线用于阻止意外的字符串匹配。
清单 20. 用单词标记替换单词类型
$text = “I was VERB_ing in the _PLACE when I found a _NOUN_.
I _VERB_ed in, and _VERB_ed too much _NOUN_. I had to go to the _PLACE_.”;
接下来,创立几个根本单词列表。对于本例,咱们也不会做得太简单。
清单 21. 创立几个根本单词列表
$verbs = array(‘pump’, ‘jump’, ‘walk’, ‘swallow’, ‘crawl’, ‘wail’, ‘roll’);
$places = array(‘park’, ‘hospital’, ‘arctic’, ‘ocean’, ‘grocery’, ‘basement’,
‘attic’, ‘sewer’);
$nouns = array(‘water’, ‘lake’, ‘spit’, ‘foot’, ‘worm’,
‘dirt’, ‘river’, ‘wankel rotary engine’);
当初能够反复地评估文原本依据须要替换标记。
清单 22. 评估文本
while (preg_match(“/(_VERB_)|(_PLACE_)|(_NOUN_)/”, $text, $matches)) {
switch ($matches[0]) {
case ‘_VERB_’ :
shuffle($verbs);
$text = preg_replace($matches[0], current($verbs), $text, 1);
break;
case ‘_PLACE_’ :
shuffle($places);
$text = preg_replace($matches[0], current($places), $text, 1);
break;
case ‘_NOUN_’ :
shuffle($nouns);
$text = preg_replace($matches[0], current($nouns), $text, 1);
break;
}
}
echo $text;
很显著,这是一个简略而毛糙的示例。单词列表越准确,并且花在根本文本上的工夫越多,后果就越好。咱们曾经应用了文本文件创立名称列表及根本单词列表。应用雷同准则,咱们能够创立按类型划分的单词列表并应用这些单词列表创立更加变化多端的米德里比斯游戏。乐透机
全副选中乐透的六个正确号码 —— 退一步说 —— 在统计学上是不可能的。不过,许多人依然花钱去玩,而且如果您喜爱号码,则查看趋势图可能很乏味。让咱们构建一个脚本,该脚本将容许跟踪赢奖号码并在列表中提供抉择次数起码的 6 个号码。
(免责申明:这不会帮忙您中乐透奖,因而请不要花钱购买奖券。这只是为了娱乐)。
把赢奖的乐透抉择保留到文本文件中。用逗号分隔各个号码并把每组号码放在独自一行中。应用换行符分隔文件内容并应用逗号分隔行后,能够失去相似清单 23 的内容。
清单 23. 把抉择的赢奖乐透保留到文本文件中
$picks = array(
array(‘6′, ’10’, ’18’, ’21’, ’34’, ’40’),
array(‘2’, ‘8’, ’13’, ’22’, ’30’, ’39’),
array(‘3’, ‘9’, ’14’, ’25’, ’31’, ’35’),
array(’11’, ’12’, ’16’, ’24’, ’36’, ’37’),
array(‘4’, ‘7’, ’17’, ’26’, ’32’, ’33’)
);
很显著,这不足以成为绘制统计数据的根本文件。然而它是一个开始,并且足以演示基本原理。
设置一个根本数组以保留抉择范畴。例如,如果抉择 1 到 40 之间 (例如,$numbers = array_fill(1,40,0);) 的号码,则遍历咱们的抉择,递增相应的匹配值。
清单 24. 遍历抉择
foreach ($picks as $pick) {
foreach ($pick as $number) {
$numbers[$number]++;
}
}
最初,依据值将号码排序。此操作该当会把起码抉择的号码放在数组的前部。
清单 25. 依据值将号码排序
asort($numbers);
$pick = array_slice($numbers,0,6,true);
echo implode(‘,’, array_keys($pick));
通过有法则地向蕴含中奖号码列表的文本文件增加理论的乐透中奖号码,能够发现选号的长期趋势。查看某些号码的呈现频率非常乏味。
文章起源:http://www.diuxie.com/ 游戏