Skip to content

Instantly share code, notes, and snippets.

@stungeye
Last active November 21, 2015 02:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stungeye/10480314 to your computer and use it in GitHub Desktop.
Save stungeye/10480314 to your computer and use it in GitHub Desktop.
PHP Guessing Game - Attempt At Self-Documenting Code
<?php
/* This code implements a simple higher/lower guessing game.
The computer picks a random number and the user guesses by way of an HTML form.
The user is given hints if they guess incorrectly with the ability to try again.
Upon winning the game the user can add their name to a session-based leaderboard. */
require('session_game_functions.php');
session_start();
$message_for_user = "I've picked a random number between " .
SECRET_NUMBER_MINIMUM_VALUE . " and " .
SECRET_NUMBER_MAXIMUM_VALUE . ". Can you guess it?";
$user_has_guessed_correctly = user_has_guessed_correctly($_POST, $_SESSION);
if (user_has_submitted_a_guess($_POST)) {
increase_the_user_guess_count($_SESSION);
if ($user_has_guessed_correctly) {
$message_for_user = "You got it in {$_SESSION['guess_count']} guesses!";
} else if (user_has_guessed_too_low($_POST, $_SESSION)) {
$message_for_user = 'Incorrect Guess! Try a larger number.';
} else if (user_has_guessed_too_high($_POST, $_SESSION)) {
$message_for_user = 'Incorrect Guess! Try a smaller number.';
}
}
if (user_has_submitted_their_name_for_leaderboard($_POST)) {
add_user_name_to_leaderboard($_POST, $_SESSION);
reset_secret_number_and_guess_count($_SESSION);
}
if ( secret_number_has_not_yet_been_set($_POST, $_SESSION)
|| user_has_requested_a_reset($_POST)) {
reset_secret_number_and_guess_count($_SESSION);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Guessing Game</title>
</head>
<body>
<h1>Guessing Game</h1>
<p><?= $message_for_user ?></p>
<?php if ($user_has_guessed_correctly): ?>
<form method="post">
<label for="user_name">Your Name For The Highscore Leaderboard:</label>
<input id="user_name" name="user_name">
<input type="submit" value="Submit Name" name="button">
</form>
<?php else: ?>
<form method="post">
<label for="user_guess">Your Guess</label>
<input id="user_guess" name="user_guess">
<input type="submit" value="Guess" name="button">
<input type="submit" value="Reset" name="button">
</form>
<?php endif; ?>
<h2>Leader Board</h2>
<?php if (leaderboard_does_not_exist($_SESSION)): ?>
<p>No highscores yet!</p>
<?php else: ?>
<ul>
<?php foreach($_SESSION['leaderboard'] as $highscore): ?>
<li><?= $highscore['guess_count'] ?> - <?= $highscore['user_name'] ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</body>
</html>
<?php
/* Constants to specific the numeric bounds for the guessing name. */
define('SECRET_NUMBER_MINIMUM_VALUE', 1);
define('SECRET_NUMBER_MAXIMUM_VALUE', 10);
/* Functions for dealing with user POSTed forms. */
function user_has_submitted_a_guess($post) {
return isset($post['button']) && $post['button'] == 'Guess';
}
function user_has_requested_a_reset($post) {
return isset($post['button']) && $post['button'] == 'Reset';
}
function user_has_submitted_their_name_for_leaderboard($post) {
return isset($post['button']) && $post['button'] == 'Submit Name';
}
/* These functions deal with the state of our game. */
function secret_number_has_not_yet_been_set($post, $session) {
return !isset($session['secret_number']) // Secret number doesn't get exist.
|| !$post; // OR the user is visiting via a GET request only.
}
function leaderboard_does_not_exist($session) {
return !isset($session['leaderboard'])
|| count($session['leaderboard']) == 0;
}
/* These functions deal with a user's guess. */
function user_has_guessed_correctly($post, $session) {
return isset($post['user_guess'])
&& $post['user_guess'] == $session['secret_number'];
}
function user_has_guessed_too_high($post, $session) {
return $post['user_guess'] > $session['secret_number'];
}
function user_has_guessed_too_low($post, $session) {
return $post['user_guess'] < $session['secret_number'];
}
/* In the following three functions & here makes the function argument 'pass by reference'.
i.e. The $_SESSION variable being passed in will be modified.
I could have just used $_SESSION directly in the function to avoid using a & paramter, but I
felt that my intentions were better communicated when the function params included the session.
I've since made a version where I don't pass $_SESSION around:
https://gist.github.com/stungeye/d6c0f179a9295dfe54e8
These functions all deal with setting the guess count or the leader board in session. */
function reset_secret_number_and_guess_count(&$session) {
$session['secret_number'] = rand(SECRET_NUMBER_MINIMUM_VALUE, SECRET_NUMBER_MAXIMUM_VALUE);
$session['guess_count'] = 0;
}
function increase_the_user_guess_count(&$session) {
$session['guess_count']++;
}
function add_user_name_to_leaderboard($post, &$session) {
if (!isset($session['leaderboard'])) {
$session['leaderboard'] = [];
}
$session['leaderboard'][] = ['user_name' => $post['user_name'],
'guess_count' => $session['guess_count']];
usort($session['leaderboard'], "compare_by_guess_count");
}
/* This function is used by the previous one as a custom comparator for usort. */
function compare_by_guess_count($a, $b) {
if ($a['guess_count'] == $b['guess_count']) {
return 0;
}
return ($a['guess_count'] < $b['guess_count']) ? -1 : 1;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment