You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
562 lines
19 KiB
562 lines
19 KiB
<?php namespace App\Controllers;
|
|
/******************************************************************************************************************
|
|
* RPSLS - Rock, Paper, Scissors, Lizard, Spock Game
|
|
*
|
|
* @file app/Controllers/GameController.php
|
|
* @package App\Controllers
|
|
* @description
|
|
* Main Controller for Game.
|
|
* @author Rick Hays
|
|
* @date 11/15/2019
|
|
* @license MIT
|
|
* @copyright Copyright © 2019 - Rick Hays, All Rights Reserved.
|
|
*
|
|
* Revisions:
|
|
* YYYY-MM-DD XX Description
|
|
******************************************************************************************************************/
|
|
use App\Libraries\Location;
|
|
use App\Models\UserModel;
|
|
use App\Models\PlayModel;
|
|
use App\Models\LogModel;
|
|
|
|
class GameController extends BaseController
|
|
{
|
|
private $session;
|
|
|
|
/***************************************************************************************************************
|
|
* GameController constructor.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->session = session();
|
|
if (empty($this->session->get('ip')) && empty($this->session->get('UserID')))
|
|
{
|
|
$this->CreateSession();
|
|
$this->CreateLogRecord();
|
|
return redirect()->route('/');
|
|
}
|
|
else
|
|
{
|
|
return redirect()->route('play');
|
|
}
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method index
|
|
* @description
|
|
* Main page for game, Start/Home Page.
|
|
*/
|
|
public function index()
|
|
{
|
|
$HeaderData = $this->getHeaderData();
|
|
echo view('inc/head');
|
|
echo view('inc/header', $HeaderData);
|
|
echo view('game');
|
|
echo view('inc/footer');
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method createUser
|
|
* @description
|
|
* Creates user for game play.
|
|
* @param $UserName
|
|
* @param $UserID
|
|
*
|
|
* @return \CodeIgniter\HTTP\RedirectResponse
|
|
* @throws \ReflectionException
|
|
*/
|
|
public function createUser($UserName, $UserID)
|
|
{
|
|
$UserName = esc($UserName);
|
|
$UserID = esc($UserID);
|
|
$dbUsers = new UserModel();
|
|
|
|
// Validate User Name
|
|
if (!$this->validateUserName($UserName)) return redirect()->to(base_url() . '/getUser');
|
|
$UserID = $this->saveUserData($UserID, $UserName);
|
|
$UserData = $dbUsers->find($UserID);
|
|
// Add user to the Session
|
|
$data =
|
|
[
|
|
'UserID' => $UserID,
|
|
'UserName' => $UserName,
|
|
'Wins' => $UserData['Wins'],
|
|
'Loses' => $UserData['Loses'],
|
|
'Ties' => $UserData['Ties']
|
|
];
|
|
$this->session->set($data);
|
|
// Pass off to PLAY()
|
|
return redirect()->route('play');
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method endGame
|
|
* @description
|
|
* Destroys Session and sends them back to Home Page.
|
|
* @return \CodeIgniter\HTTP\RedirectResponse
|
|
*/
|
|
public function endGame()
|
|
{
|
|
// Close Session
|
|
$this->session->destroy();
|
|
// Goto Index page
|
|
return redirect()->route('/');
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method getUser
|
|
* @description
|
|
* Prompt Screen to get user name for game play.
|
|
*/
|
|
public function getUser()
|
|
{
|
|
$getUserData = ['UserName' => $this->session->getFlashdata('UserName'), 'ErrorCode' => $this->session->getFlashdata('ErrorCode')];
|
|
$HeaderData = $this->getHeaderData();
|
|
echo view('inc/head');
|
|
echo view('inc/header', $HeaderData);
|
|
echo view('getUser', $getUserData);
|
|
echo view('inc/footer');
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method play
|
|
* @description
|
|
* Main Play Page/Function Logic.
|
|
*
|
|
* @param null $PlayerPick
|
|
* @todo REFACTOR GAME PLAY!!
|
|
*
|
|
* @return \CodeIgniter\HTTP\RedirectResponse|false|string
|
|
* @throws \ReflectionException
|
|
*/
|
|
public function play($PlayerPick = null)
|
|
{
|
|
$UserID = $this->session->UserID;
|
|
|
|
if ($PlayerPick)
|
|
{
|
|
$W = 0; // Win
|
|
$L = 0; // Lose
|
|
$T = 0; // Tie
|
|
$ComputerPick = $this->ComputerPick();
|
|
$textResult = '';
|
|
$TextResults =
|
|
[
|
|
'RL' => 'Rock Crushes Lizard!',
|
|
'RS' => 'Rock Crushes Scissors!',
|
|
'PR' => 'Paper Covers Rock!',
|
|
'PS' => 'Paper Disproves Spock!',
|
|
'SP' => 'Scissors Cuts Paper!',
|
|
'SL' => 'Scissors Decapitates Lizard!',
|
|
'LS' => 'Lizard Poisons Spock!',
|
|
'LP' => 'Lizard Eats Paper!',
|
|
'SS' => 'Spock Smashes Scissors!',
|
|
'SR' => 'Spock Vaporizes Rock!',
|
|
'TIE' => 'No One Wins This Time.',
|
|
'DRAW' => 'Danger, Danger Will Robinson, that does not compute!',
|
|
];
|
|
|
|
/** GAME LOGIC */
|
|
switch(strtoupper($PlayerPick))
|
|
{
|
|
case 'ROCK':
|
|
switch(strtoupper($ComputerPick))
|
|
{
|
|
case 'ROCK': $textResult = 'TIE'; $W = 0; $L = 0; $T = 1; break;
|
|
case 'PAPER': $textResult = 'PR'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'SCISSORS': $textResult = 'RS'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'LIZARD': $textResult = 'RL'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'SPOCK': $textResult = 'SR'; $W = 0; $L = 1; $T = 0; break;
|
|
default: $textResult = 'DRAW'; $W = 0; $L = 0; $T = 0;
|
|
}
|
|
break;
|
|
case 'PAPER':
|
|
switch(strtoupper($ComputerPick))
|
|
{
|
|
case 'ROCK': $textResult = 'PR'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'PAPER': $textResult = 'TIE'; $W = 0; $L = 0; $T = 1; break;
|
|
case 'SCISSORS': $textResult = 'SP'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'LIZARD': $textResult = 'LP'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'SPOCK': $textResult = 'PS'; $W = 1; $L = 0; $T = 0; break;
|
|
default: $textResult = 'DRAW'; $W = 0; $L = 0; $T = 0;
|
|
}
|
|
break;
|
|
case 'SCISSORS':
|
|
switch(strtoupper($ComputerPick))
|
|
{
|
|
case 'ROCK': $textResult = 'RS'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'PAPER': $textResult = 'SP'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'SCISSORS': $textResult = 'TIE'; $W = 0; $L = 0; $T = 1; break;
|
|
case 'LIZARD': $textResult = 'SL'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'SPOCK': $textResult = 'SS'; $W = 0; $L = 1; $T = 0; break;
|
|
default: $textResult = 'DRAW'; $W = 0; $L = 0; $T = 0;
|
|
}
|
|
break;
|
|
case 'LIZARD':
|
|
switch(strtoupper($ComputerPick))
|
|
{
|
|
case 'ROCK': $textResult = 'RL'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'PAPER': $textResult = 'LP'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'SCISSORS': $textResult = 'SL'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'LIZARD': $textResult = 'TIE'; $W = 0; $L = 0; $T = 1; break;
|
|
case 'SPOCK': $textResult = 'LS'; $W = 1; $L = 0; $T = 0; break;
|
|
default: $textResult = 'DRAW'; $W = 0; $L = 0; $T = 0;
|
|
}
|
|
break;
|
|
case 'SPOCK':
|
|
switch(strtoupper($ComputerPick))
|
|
{
|
|
case 'ROCK': $textResult = 'SR'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'PAPER': $textResult = 'PS'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'SCISSORS': $textResult = 'SS'; $W = 1; $L = 0; $T = 0; break;
|
|
case 'LIZARD': $textResult = 'LS'; $W = 0; $L = 1; $T = 0; break;
|
|
case 'SPOCK': $textResult = 'TIE'; $W = 0; $L = 0; $T = 1; break;
|
|
default: $textResult = 'DRAW'; $W = 0; $L = 0; $T = 0;
|
|
}
|
|
break;
|
|
default:
|
|
// TODO: SOME RETURN ERROR GOES HERE
|
|
// AS WE SHOULD NEVER GET HERE...
|
|
}
|
|
|
|
// Text for Play Result of who Won, Lost or Tied.
|
|
if ($W === 1 && $L === 0 && $T === 0) $PlayResult = 'WINNER';
|
|
elseif ($W === 0 && $L === 1 && $T === 0) $PlayResult = 'LOSER';
|
|
elseif ($W === 0 && $L === 0 && $T === 1) $PlayResult = 'TIE';
|
|
else $PlayResult = 'DRAW';
|
|
|
|
$this->addPlay( $this->session->UserID, $this->session->UserName, $this->session->ip, $PlayerPick, $ComputerPick, $PlayResult);
|
|
|
|
$data =
|
|
[
|
|
'Wins' => $this->session->Wins + $W,
|
|
'Loses' => $this->session->Loses + $L,
|
|
'Ties' => $this->session->Ties + $T,
|
|
];
|
|
$this->session->set($data);
|
|
$this->updateDBCounts($this->session->UserID, $this->session->Wins, $this->session->Loses, $this->session->Ties);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
$data =
|
|
[
|
|
'PlayerPick' => $PlayerPick,
|
|
'ComputerPick' => $ComputerPick,
|
|
'Result' => $PlayResult,
|
|
'ResultText' => $TextResults[$textResult],
|
|
'Wins' => $this->session->Wins,
|
|
'Loses' => $this->session->Loses,
|
|
'Ties' => $this->session->Ties,
|
|
];
|
|
return json_encode($data);
|
|
}
|
|
else
|
|
{
|
|
$playData =
|
|
[
|
|
'UserID' => $this->session->UserID,
|
|
'UserName' => $this->session->UserName,
|
|
'Wins' => $this->session->Wins,
|
|
'Loses' => $this->session->Loses,
|
|
'Ties' => $this->session->Ties,
|
|
];
|
|
|
|
if (empty($UserID))
|
|
{
|
|
return redirect()->to(base_url() . '/getUser');
|
|
}
|
|
else
|
|
{
|
|
$HeaderData = $this->getHeaderData();
|
|
echo view('inc/head');
|
|
echo view('inc/header', $HeaderData);
|
|
echo view('play', $playData);
|
|
echo view('inc/footer');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*************************************************************************************************************
|
|
* @method testUser
|
|
* @description
|
|
* Returns UserID from User Name if one exists else it will return a 0.
|
|
*
|
|
* @param $UserName
|
|
*
|
|
* @return string
|
|
*/
|
|
public function testUser($UserName)
|
|
{
|
|
// TODO: Have it compare more then name to equal the same
|
|
// if not the same country and city then its a new user
|
|
// and they should pick a different name, as this one
|
|
// belongs to someone else. This will keep stats correct!
|
|
return $this->getIDfromUserName($UserName);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method top10
|
|
* @description
|
|
* Logic for the Top10 page.
|
|
*/
|
|
public function top10()
|
|
{
|
|
//Table Models
|
|
$dbUsers = new UserModel();
|
|
$dbPlay = new PlayModel();
|
|
// Queries
|
|
$TotalPlays = $dbPlay->query("SELECT COUNT(Result) AS Total FROM plays")->getRow();
|
|
$TotalWinsPlayer = $dbPlay->query("SELECT COUNT(Result) AS Total FROM plays WHERE Result = 'WINNER'")->getRow();
|
|
$TotalLosesPlayer = $dbPlay->query("SELECT COUNT(Result) AS Total FROM plays WHERE Result = 'LOSER'")->getRow();
|
|
$TotalTiesPlayer = $dbPlay->query("SELECT COUNT(Result) AS Total FROM plays WHERE Result = 'TIE'")->getRow();
|
|
// echo '##### RESULT: ' . $TotalsWinsPlayer->Total . ' #####';
|
|
$Win10 = $dbUsers->select('UserName, Wins')->OrderBy('Wins', 'DESC')->findAll(10);
|
|
$Lose10 = $dbUsers->select('UserName, Loses')->OrderBy('Loses', 'DESC')->findAll(10);
|
|
$Tie10 = $dbUsers->select('UserName, Ties')->OrderBy('Ties', 'DESC')->findAll(10);
|
|
$PlayerPicks = $dbPlay->select('PlayerPick, COUNT(PlayerPick) AS Total')->groupBy('PlayerPick')->OrderBy('Total', 'DESC')->findAll(5);
|
|
$ComputerPicks = $dbPlay->select('ComputerPick, COUNT(PlayerPick) AS Total')->groupBy('ComputerPick')->OrderBy('Total', 'DESC')->findAll(5);
|
|
// Combine Results for View
|
|
$PageData =
|
|
[
|
|
'Win10' => $Win10,
|
|
'Lose10' => $Lose10,
|
|
'Tie10' => $Tie10,
|
|
'PlayerPicks' => $PlayerPicks,
|
|
'ComputerPicks' => $ComputerPicks,
|
|
'TotalWinsPlayer' => $TotalWinsPlayer,
|
|
'TotalLosesPlayer' => $TotalLosesPlayer,
|
|
'TotalTiesPlayer' => $TotalTiesPlayer,
|
|
'TotalPlays' => $TotalPlays
|
|
];
|
|
|
|
$HeaderData = $this->getHeaderData();
|
|
echo view('inc/head');
|
|
echo view('inc/header', $HeaderData);
|
|
echo view('top10', $PageData);
|
|
echo view('inc/footer');
|
|
}
|
|
|
|
// #############################################################################################################
|
|
// ### START OF PRIVATE FUNCTIONS
|
|
// #############################################################################################################
|
|
|
|
/***************************************************************************************************************
|
|
* @method addPlay
|
|
* @description
|
|
* Adds (Inserts) Game Play Results to the DB.
|
|
*
|
|
* @param $UserID
|
|
* @param $UserName
|
|
* @param $IP
|
|
* @param $PlayerPick
|
|
* @param $ComputerPick
|
|
* @param $Result
|
|
*
|
|
* @throws \ReflectionException
|
|
*/
|
|
private function addPlay($UserID, $UserName, $IP, $PlayerPick, $ComputerPick, $Result)
|
|
{
|
|
$dbPlay = new PlayModel();
|
|
$data =
|
|
[
|
|
'UserID' => $UserID,
|
|
'UserName' => $UserName,
|
|
'IP' => $IP,
|
|
'PlayerPick' => $PlayerPick,
|
|
'ComputerPick' => $ComputerPick,
|
|
'Result' => $Result
|
|
];
|
|
$dbPlay->insert($data);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method ComputerPick
|
|
* @description
|
|
* Returns the Computers Pick/Choice.
|
|
* @return string
|
|
*/
|
|
private function ComputerPick()
|
|
{
|
|
mt_srand(crc32(microtime()));
|
|
$pick = mt_rand(0,4);
|
|
$ComputerPicks = array('Rock', 'Paper', 'Scissors', 'Lizard', 'Spock');
|
|
return $ComputerPicks[$pick];
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method CreateLogRecord
|
|
* @description
|
|
* Inserts a Log Record at start of New Session.
|
|
* @throws \ReflectionException
|
|
*/
|
|
private function CreateLogRecord()
|
|
{
|
|
$dbLog = new LogModel();
|
|
$data =
|
|
[
|
|
'IP' => $this->session->get('ip'),
|
|
'City' => $this->session->get('city'),
|
|
'State' => $this->session->get('region_name'),
|
|
'Country' => $this->session->get('country_name'),
|
|
];
|
|
$dbLog->insert($data);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method CreateSession
|
|
* @description
|
|
* Creates a new session for start of Game Play.
|
|
*/
|
|
private function CreateSession()
|
|
{
|
|
$Location = new Location();
|
|
$this->session->set($Location->Data);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method getPageName
|
|
* @description
|
|
* Returns the current page name, used for menu to show active page.
|
|
* @return string
|
|
*/
|
|
private function getPageName()
|
|
{
|
|
return $this->request->uri->getSegment(1);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method getHeaderData
|
|
* @description
|
|
* Creates array of header page data to pass into view.
|
|
* @return array
|
|
*/
|
|
private function getHeaderData()
|
|
{
|
|
$page = $this->getPageName();
|
|
$data =
|
|
[
|
|
'page' => $page,
|
|
];
|
|
return $data;
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method getIDfromUserName
|
|
* @description
|
|
* Returns UserID from User Name if one exists else it will return a 0.
|
|
*
|
|
* @param $UserName
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getIDfromUserName($UserName)
|
|
{
|
|
$UserName = esc($UserName);
|
|
$dbUsers = new UserModel();
|
|
$row = $dbUsers->select('id')->where('UserName', $UserName)->findAll(1);
|
|
return (empty($row['0']['id'])) ? '0' : strval($row['0']['id']);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method saveUserData
|
|
* @description
|
|
* Either saves (Inserts) the new user, or it will save (Update) a current user in the DB.
|
|
* This will return the UserID once Updated/Inserted into the DB.
|
|
*
|
|
* @param $UserID
|
|
* @param $UserName
|
|
*
|
|
* @return string
|
|
* @throws \ReflectionException
|
|
*/
|
|
private function saveUserData($UserID, $UserName)
|
|
{
|
|
$dbUsers = new UserModel();
|
|
if ($UserID !== '0')
|
|
{
|
|
// UPDATE
|
|
$data =
|
|
[
|
|
'id' => $UserID,
|
|
'IP' => $this->session->get('ip'),
|
|
];
|
|
}
|
|
else
|
|
{
|
|
// ADD (Create)
|
|
$data =
|
|
[
|
|
'UserName' => $UserName,
|
|
'Wins' => 0,
|
|
'Loses' => 0,
|
|
'Ties' => 0,
|
|
'IP' => $this->session->get('ip'),
|
|
'City' => $this->session->get('city'),
|
|
'State' => $this->session->get('region_name'),
|
|
'Country' => $this->session->get('country_name'),
|
|
'CountryCode' => $this->session->get('country_code'),
|
|
'FlagURL' => $this->session->get('flagUrl'),
|
|
];
|
|
}
|
|
$dbUsers->save($data);
|
|
return $this->getIDfromUserName($UserName);
|
|
}
|
|
|
|
/***************************************************************************************************************
|
|
* @method updateDBCounts
|
|
* @description
|
|
* This will update user scores from game play.
|
|
*
|
|
* @param $UserID
|
|
* @param $Wins
|
|
* @param $Loses
|
|
* @param $Ties
|
|
*
|
|
* @throws \ReflectionException
|
|
*/
|
|
private function updateDBCounts($UserID, $Wins, $Loses, $Ties)
|
|
{
|
|
$dbUsers = new UserModel();
|
|
$UserID = esc($UserID);
|
|
$Wins = esc($Wins);
|
|
$Loses = esc($Loses);
|
|
$Ties = esc($Ties);
|
|
|
|
$data =
|
|
[
|
|
'id' => $UserID,
|
|
'Wins' => $Wins,
|
|
'Loses' => $Loses,
|
|
'Ties' => $Ties,
|
|
];
|
|
$dbUsers->save($data);
|
|
}
|
|
|
|
/**
|
|
*************************************************************************************************************
|
|
* @method validateUserName
|
|
* @description
|
|
* Backend user name validation.
|
|
*
|
|
* @param $UserName
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function validateUserName($UserName)
|
|
{
|
|
$Valid = TRUE;
|
|
$validation = \Config\Services::validation();
|
|
if (!$validation->check($UserName, 'required|regex_match[/^([0-9a-zA-Z-_@\.]*)$/]'))
|
|
{
|
|
$data =
|
|
[
|
|
'UserName' => $UserName,
|
|
'ErrorCode' => 'User Name can only contain characters: (a-z, A-Z, 0-9, - _ @ .) Only.'
|
|
];
|
|
$this->session->setFlashdata($data);
|
|
$Valid = FALSE;
|
|
}
|
|
return $Valid;
|
|
}
|
|
}
|
|
|