玩家輸入猜的數字後會進入到這支程式,進行以下動作:
1.判斷是否已產生過正確答案(是否是第一次猜),若還未產生,呼叫judge的answer()來產生答案
2.判斷玩家輸入的數字是否符合格式(4位數),若不符合,會重刷頁面讓玩家再輸入一次
3.呼叫judge的check(),比對猜的數字與正解並生出線索後,將這些資料存進資料庫
4.若猜到正解,計算花費時間並跳轉到恭喜玩家猜中的頁面(correct.php)
guess.php
<?php
session_start();
include "db.php";
include "judge.php";
include "style.html";
$guess = $_POST["subject"];
$no = $_SESSION["no"] = $_POST["no"]; $sure = $_SESSION["sure"] = $_POST["sure"];
$reg1 = $_SESSION["reg1"] = $_POST["reg1"]; $reg2 = $_SESSION["reg2"] = $_POST["reg2"]; $reg3 = $_SESSION["reg3"] = $_POST["reg3"]; $reg4 = $_SESSION["reg4"] = $_POST["reg4"];
$i = 0;
while($i<10){
$i++;
}
$judge = new judge;
if(!$_SESSION["answer"]){
$ans = $_SESSION["answer"]= $judge->answer();
$_SESSION["startTime"] = $startTime = date("H")*3600+date("i")*60+date("s");
}else{
$ans = $_SESSION["answer"];
}
if(strlen($guess) < 4 ){
//若輸入數字少於4位數,回到主畫面再輸入一次
header("location:main.php");
}else{
$hint = $judge->check($guess,$ans);
$answer = implode($ans);
$sql1 = "INSERT guess(guess, hint) VALUES ('$guess', '$hint')";
if (!mysqli_query($db, $sql1)) {
echo "insert error";
}else if($hint == "Answer Correct"){
//遊戲結束,計算花費時間
$_SESSION["endTime"] = $endTime = date("H")*3600+date("i")*60+date("s");
header("location:correct.php");
}
else{
header("location:main.php");
}
}
implode()這個函式是用來把array轉成字串的,反過來要將字串拆解成array,可以用explode()。
產生答案和線索的程式:
judge.php
<?php
class judge
{
public $MAX_LENGTH = 4;
//產生答案
function answer()
{
$i = 0;
while ($i < $this->MAX_LENGTH) {
//隨機產生出0~9之間的數字
$ans[$i] = rand() % 10;
$i++;
}
return $ans;
}
//產生線索
function check($guessString, $ans){
$guess = str_split ( $guessString);
$A = 0;
$ans_appear_times[10] = array();
$guess_appear_times[10] = array();
//計算有幾個A
for($i=0; $i< $this->MAX_LENGTH; $i++) {
if($guess[$i] == $ans[$i]) {
$A++;
}
else {
$ans_appear_times[$ans[$i]]++;
$guess_appear_times[$guess[$i]]++;
}
}
//計算有幾個B(已排除計算過的A)
$B = 0;
for($i=0; $i<10; $i++) {
if($guess_appear_times[$i] >= $ans_appear_times[$i]) {
$B += $ans_appear_times[$i];
}
else {
$B += $guess_appear_times[$i];
}
}
//若4位數都對,回傳'Answer Correct'
if($A==$this->MAX_LENGTH && $B==0) {
return "Answer Correct";
}
$hint = $A."A".$B."B";
return $hint;
}
}
產出線索的部份會先開出數字0~9,每個分別記錄正解和玩家猜的數字出現的次數。
計算A的概念很直覺,猜的位數和正解位數一致就加一,若不一樣,則該位數中正解和玩家猜的數字出現的次數各加一;
例如:正解為1212,玩家猜2284,
迴圈跑第一次時,$ans_appear_times[1]加一,$guess_appear_times[2]也加一。
迴圈跑第二次時,A加一,依此類推,總共會跑4次迴圈。
而計算B的概念則是根據計算完A後,此時已經計算完0~9在正解和玩家猜的數字中出現(排除A)的次數,
因此只要從[0~9]各跑一次去取$ans_appear_times[]或$guess_appear_times[]比較小的那個為B,
累加上去最後的總數就是B的總數了。
舉剛才的例子:
正解為1212,玩家猜2284,計算A的迴圈跑完後,
因為第二位數的2是A,因此不會被計算到appear_times的array中:
$ans_appear_times[1] = 2,
$guess_appear_times[2] = 1,
其餘為零。
$guess_appear_times[2] = 1,
$guess_appear_times[4] = 1,
$guess_appear_times[8] = 1,
其餘為零。
計算B的時候,$guess_appear_times[2] 等於 $guess_appear_times[2] 等於 1,因此B加一,其餘都是零。