Files
Days-In-Fortuna/game.php

358 lines
12 KiB
PHP

<?php
/**
* Days In Fortuna Game Logic
*
* PHP version: 8.0+
*
* This file contains the main game logic for the Days In Fortuna simulation.
* Handles session state, game actions, and JSON responses.
*
* @category API
* @package DaysInFortuna
* @author Keith Solomon <keith@keithsolomon.net>
* @license MIT License
* @version GIT: <git_id>
* @link https://git.keithsolomon.net/keith/Days-In-Fortuna
*/
session_start();
header('Content-Type: application/json');
/**
* Initializes the game state.
*
* This function sets up the initial state for the game, preparing any necessary
* variables, data structures, or configurations required to start gameplay.
*
* @return void
*/
function initState() {
$_SESSION['game'] = [
'day' => 1,
'hours_left' => 26,
'meals' => 0,
'earned' => 0,
'earned_total' => 0,
'debt' => 127000,
'mods' => 0,
'wage' => 800,
'interest' => 0.20,
'eff' => 100.0,
'game_over' => false,
];
}
/**
* Checks and returns the current status of the game.
*
* @param array $g Reference to the game state array.
*
* @return array Status messages describing the current game state.
*/
function statusCheck(&$g) {
$s = [];
$hours_str = ($g['hours_left'] == 1) ? 'is 1 hour' : ('are ' . $g['hours_left'] . ' hours');
$s[] = "------------\nIt is day {$g['day']}. There {$hours_str} left today. ";
$s[] = 'You have earned ' . $g['earned'] . ' credits today and ' . $g['earned_total'] . ' total. ' . 'This brings your total debt to ' . $g['debt'] . ' credits, with an interest rate of ' . ((int)($g['interest']*100)) . "%.\n------------";
return $s;
}
/**
* Increases the debt value in the provided game state array.
*
* @param array $g Reference to the game state array.
*
* @return int The updated debt value.
*/
function debtIncrease(&$g) {
$fltDebt = (float)$g['debt'];
$fltDebt = ($fltDebt + ($fltDebt * $g['interest']));
$g['debt'] = (int)$fltDebt;
return $g['debt'];
}
/**
* Checks if a new day has started in the game and performs necessary updates.
*
* This function examines the game state and determines if a new day should begin.
* If a new day is detected, it updates relevant game variables and appends messages
* to the provided messages array.
*
* @param array $g Reference to the game state array.
* @param array $messages Reference to the array of messages to be updated.
*
* @return void
*/
function newDayCheck(&$g, &$messages) {
if ($g['hours_left'] <= 0) {
$g['day'] += 1;
$g['hours_left'] = 26 + $g['hours_left'];
$g['debt'] -= $g['earned'];
debtIncrease($g);
$g['earned'] = 0;
$g['eff'] -= 50;
if ($g['eff'] < 0) {
$g['eff'] = 0;
}
$g['meals'] = 0;
$messages[] = 'A new day has begun.';
}
}
/**
* Checks the repository status and updates the game state and messages accordingly.
*
* @param array $g Reference to the game state array.
* @param array $messages Reference to the array of messages to be updated.
*
* @return void
*/
function repoCheck(&$g, &$messages) {
if ($g['debt'] >= 300000) {
if ($g['mods'] < 4) {
$messages[] = 'Your debt has grown too high. A Corpus Repossession Team has been waiting outside to arrest you.';
$g['mods'] += 1;
$g['hours_left'] -= 6;
switch ($g['mods']) {
case 1:
$messages[] = "Your legs have been replaced with robotic enhancements. You can now stand longer and lift more weight, increasing your productivity.\n\nThe Corpus have been generous enough to reduce your debt as a token of thanks. Your legs were worth enough credits to significantly reduce your debt. To ensure you remain motivated to work hard, your interest rate has been raised.\n------------";
$g['interest'] = 0.23;
$g['wage'] = 1150;
$g['debt'] = 170000;
break;
case 2:
$messages[] = "Your arms have been replaced with robotic prosthetics, allowing you to work harder and more accurately.\n\nThe Corpus have been generous enough to reduce your debt as a token of thanks. Your arms were worth enough credits to significantly reduce your debt. To ensure you remain motivated to work hard, your interest rate has been raised.\n------------";
$g['interest'] = 0.28;
$g['wage'] = 1300;
$g['debt'] = 160000;
break;
case 3:
$messages[] = "Your internal organs, apart from your head, have been replaced with enhanced prosthetics. You are much more durable, and need no breaks during work hours.\n\nThe Corpus have been generous enough to reduce your debt as a token of thanks. Your organs were worth enough credits to significantly reduce your debt. To ensure you remain motivated to work hard, your interest rate has been raised.\n";
$g['interest'] = 0.30;
$g['wage'] = 1600;
$g['debt'] = 150000;
break;
case 4:
$messages[] = "Your head has been replaced with a robotic apparatus. You will no longer feel tired, or pain, or anything at all.\n\nThe Corpus have been generous enough to reduce your debt as a token of thanks. Your head was worth enough credits to significantly reduce your debt. To ensure you remain motivated to work hard, your interest rate has been raised.\n";
$g['interest'] = 0.34;
$g['wage'] = 1800;
$g['debt'] = 140000;
break;
}
$tmp = [];
newDayCheck($g, $tmp); // may add day rollover message
foreach ($tmp as $m) {
$messages[] = $m;
}
} else {
$messages[] = "You are entirely comprised of robotic parts owned by the Corpus. As none of you is human anymore, and you cannot repay what you owe, you will be regarded as any other robot.\nYou are now the property of the Corpus, and will work until you break and then be melted down for scrap. Your debt will be passed to any heirs you may have.\n";
$g['game_over'] = true;
}
}
}
/**
* Serializes the current game state.
*
* @param mixed $g The game state object or array to be serialized.
*
* @return string The serialized representation of the game state.
*/
function serializeState($g) {
return [
'day' => $g['day'],
'hours_left' => $g['hours_left'],
'meals' => $g['meals'],
'earned' => $g['earned'],
'earned_total' => $g['earned_total'],
'debt' => $g['debt'],
'mods' => $g['mods'],
'wage' => $g['wage'],
'interest' => $g['interest'],
'eff' => $g['eff'],
];
}
$input = json_decode(file_get_contents('php://input'), true) ?? [];
$action = $input['action'] ?? 'start';
$value = $input['value'] ?? null;
if (!isset($_SESSION['game'])) {
initState();
}
$g =& $_SESSION['game'];
$messages = [];
$can_install = false;
$final_summary = null;
switch ($action) {
case 'start':
// Re-init if game over or user explicitly starts
if (!empty($input['reset']) || $g['day'] === 1 && $g['earned_total'] === 0) {
initState();
$g =& $_SESSION['game'];
}
$messages[] = "Days in Fortuna\n------------------------";
break;
case 'reset':
initState();
$g =& $_SESSION['game'];
$messages[] = 'Game reset.';
break;
case 'status':
foreach (statusCheck($g) as $m) {
$messages[] = $m;
}
break;
case 'work':
$hours = (int)$value;
if ($hours < 1) {
$messages[] = 'Invalid entry.';
break;
}
if ($hours > 26) {
$messages[] = 'You cannot work more than one full day at a time.';
break;
}
$g['earned'] += (int)round($hours * $g['wage'] * ($g['eff'] / 100.0));
$g['earned_total'] += $g['earned'];
$g['hours_left'] -= $hours;
$messages[] = 'You earned ' . $g['earned'] . ' credits. Well done!';
$messages[] = "\n------------";
newDayCheck($g, $messages);
repoCheck($g, $messages);
break;
case 'sleep':
$hours = (int)$value;
if ($hours < 1) {
$messages[] = 'Invalid entry.';
break;
}
$g['hours_left'] -= $hours;
newDayCheck($g, $messages);
if ($hours <= 7) {
$g['eff'] += ((50.0 * $hours) / 8.0);
} else {
$g['eff'] += 50.0;
}
if ($g['eff'] > 100.0) {
$g['eff'] = 100.0;
}
$messages[] = 'You wake up feeling refreshed. Your efficiency has been restored.';
repoCheck($g, $messages);
break;
case 'eat':
if ($g['meals'] < 2) {
$g['eff'] += 20.0;
if ($g['eff'] > 100.0) {
$g['eff'] = 100.0;
}
$messages[] = 'You feel satisfied. Your efficiency has been restored.';
} else {
$messages[] = "You finish eating, but don't feel any better.";
}
$g['hours_left'] -= 1;
$g['meals'] += 1;
newDayCheck($g, $messages);
repoCheck($g, $messages);
break;
case 'enhance':
if ($g['mods'] >= 4) {
$messages[] = "No available enhancements were found...\n";
} else {
$messages[] = "You found a shop with modifications and enhancements you can install. Would you like to install one?";
$can_install = true;
}
break;
case 'install_enhancement':
if ($g['mods'] < 4) {
$g['mods'] += 1;
$g['hours_left'] -= 6;
switch ($g['mods']) {
case 1:
$messages[] = "You have replaced your legs with robotic enhancements. You can now stand longer and lift more weight, increasing your productivity.\n\nThe Corpus have been generous enough to offer this for no cost, apart from an increased interest rate.\n";
$g['interest'] = 0.26;
$g['wage'] = 1150;
break;
case 2:
$messages[] = "You have replaced your arms with robotic prosthetics, allowing you to work harder and more accurately.\n\nThe Corpus have been generous enough to offer this for no cost, apart from an increased interest rate.\n";
$g['interest'] = 0.30;
$g['wage'] = 1400;
break;
case 3:
$messages[] = "You have replaced your internal organs, apart from your head, with enhanced prosthetics. You are much more durable, and need no breaks during work hours.\n\nThe Corpus have been generous enough to offer this for no cost, apart from an increased interest rate.\n";
$g['interest'] = 0.35;
$g['wage'] = 1600;
break;
case 4:
$messages[] = "You have replaced your head with a robotic apparatus. You will no longer feel tired, or pain, or anything at all.\n\nThe Corpus have been generous enough to offer this for no cost, apart from an increased interest rate.\n";
$g['interest'] = 0.38;
$g['wage'] = 1800;
break;
}
newDayCheck($g, $messages);
repoCheck($g, $messages);
}
break;
case 'quit':
$g['game_over'] = true;
$final_summary = 'You made it to day ' . $g['day'] . ', and earned ' . $g['earned_total'] . ' credits total. Your final debt was ' . $g['debt'] . ' credits, with an interest rate of ' . ((int)($g['interest']*100)) . '%.';
break;
default:
$messages[] = 'Invalid input. Please try again';
}
echo json_encode(
[
'messages' => $messages,
'state' => serializeState($g),
'game_over' => $g['game_over'],
'final_summary' => $final_summary,
'can_install' => $can_install,
]
);