diff --git a/README.md b/README.md
index f192a75..3af9b41 100644
--- a/README.md
+++ b/README.md
@@ -10,22 +10,30 @@ Each turn, you roll the dice to see what happens in the city. The events will af
You can also try to assassinate the emperor. This is a risky move, but if you succeed, you win the game (though you die a martyr).
+## Configuration
+
+This project uses a SQLite database to store game data and configuration.
+
+You can modify the game's configuration by clicking on the "Configuration" button on the main page. This will take you to a page where you can edit the score thresholds, win conditions, and event descriptions.
+
## Technical Details
This project is built using:
* **Frontend:** HTML, CSS, JavaScript
* **Backend:** PHP
+* **Database:** SQLite
## How to Run Locally
-To run this project locally, you need a PHP server. You can use a local development environment like XAMPP or MAMP, or you can use the built-in PHP server.
+To run this project locally, you need a PHP server with the `pdo_sqlite` extension enabled. You can use a local development environment like XAMPP or MAMP, or you can use the built-in PHP server.
1. Clone this repository.
-2. Start a PHP server in the project directory. For example, you can run the following command:
+2. Make sure the `pdo_sqlite` extension is enabled in your `php.ini` file.
+3. Start a PHP server in the project directory. For example, you can run the following command:
```bash
php -S localhost:8000
```
-3. Open your web browser and go to `http://localhost:8000`.
+4. Open your web browser and go to `http://localhost:8000`.
diff --git a/config.css b/config.css
new file mode 100644
index 0000000..07fd860
--- /dev/null
+++ b/config.css
@@ -0,0 +1,24 @@
+.form-group {
+ margin-bottom: 1rem;
+}
+
+.form-group label {
+ display: block;
+ margin-bottom: 0.5rem;
+}
+
+.form-group input,
+.form-group textarea {
+ width: 100%;
+ padding: 0.5rem;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+
+.form-group textarea {
+ height: 100px;
+}
+
+button[type="submit"] {
+ margin-top: 1rem;
+}
diff --git a/config.php b/config.php
new file mode 100644
index 0000000..dbe14c8
--- /dev/null
+++ b/config.php
@@ -0,0 +1,44 @@
+ $value) {
+ $stmt = $db->prepare('UPDATE configuration SET value = ? WHERE name = ?');
+ $stmt->execute([$value, $name]);
+ }
+ header('Location: config.php');
+ exit;
+}
+
+$stmt = $db->query('SELECT * FROM configuration');
+$config = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
+?>
+
+
+
+
+
+ Configuration - Last Days of Rome
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/database.php b/database.php
new file mode 100644
index 0000000..c784d8c
--- /dev/null
+++ b/database.php
@@ -0,0 +1,51 @@
+setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+// Create tables if they don't exist
+$db->exec('CREATE TABLE IF NOT EXISTS game_logs (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ date_played DATETIME,
+ flames_score INTEGER,
+ desolation_score INTEGER,
+ relocation_score INTEGER,
+ end_condition TEXT
+)');
+
+$db->exec('CREATE TABLE IF NOT EXISTS configuration (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ value TEXT
+)');
+
+// Check if configuration is already seeded
+$stmt = $db->query('SELECT COUNT(*) FROM configuration');
+$count = $stmt->fetchColumn();
+
+if ($count === 0) {
+ // Seed the configuration table
+ $config = [
+ ['flames_win', '10'],
+ ['desolation_win', '10'],
+ ['relocation_win', '10'],
+ ['assassination_win', '20'],
+ ['imperial_palace_event_1', 'The emperor fiddles with manic glee. +1 Flames.'],
+ ['imperial_palace_event_2', 'The emperor raises another horse to the position of senator. +1 Desolation, +1 Relocation.'],
+ ['imperial_palace_event_3', 'It\'s execution night at the palace. +1 Relocation.'],
+ ['imperial_palace_event_4', 'The emperor screams like a baby. +1 Desolation.'],
+ ['imperial_palace_event_5', 'The emperor sits in front of the flame and commands it to obey. It does not. +1 Flames, +1 Relocation.'],
+ ['imperial_palace_event_6', 'Work continues on a house made of pure gold. It keeps melting. +1 Flames.'],
+ ['relative_unrest_event_1', 'People complain - this is unacceptable. Then they go about their business. +1 Relocation.'],
+ ['relative_unrest_event_2', 'There are no goods at market. +1 Desolation.'],
+ ['relative_unrest_event_3', 'You receive a letter asking you to reassert your faith in the emperor. In writing. +1 Relocation.'],
+ ['relative_unrest_event_4', 'Lions are released onto the streets. +1 Desolation, +1 Flames.'],
+ ['relative_unrest_event_5', 'Is Rome really over? +1 Desolation.'],
+ ['relative_unrest_event_6', 'The burnings will continue until morale improves. +1 Flames.'],
+ ];
+
+ $stmt = $db->prepare('INSERT INTO configuration (name, value) VALUES (?, ?)');
+ foreach ($config as $item) {
+ $stmt->execute($item);
+ }
+}
+?>
\ No newline at end of file
diff --git a/game.php b/game.php
index c6033bb..df87f4c 100644
--- a/game.php
+++ b/game.php
@@ -1,5 +1,10 @@
query('SELECT * FROM configuration');
+$config = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
if (!isset($_SESSION['scores'])) {
$_SESSION['scores'] = [
@@ -12,15 +17,21 @@ if (!isset($_SESSION['scores'])) {
$action = $_GET['action'] ?? '';
if ($action === 'roll_dice') {
- $event = roll_dice();
- $gameState = check_game_state();
+ $event = roll_dice($config);
+ $gameState = check_game_state($config);
+ if ($gameState !== 'ongoing') {
+ log_game($gameState);
+ }
echo json_encode([
'scores' => $_SESSION['scores'],
'event' => $event,
'gameState' => $gameState,
]);
} elseif ($action === 'assassinate') {
- $assassinationResult = assassinate();
+ $assassinationResult = assassinate($config);
+ if ($assassinationResult['gameState'] !== 'ongoing') {
+ log_game($assassinationResult['gameState']);
+ }
echo json_encode([
'event' => $assassinationResult['event'],
'gameState' => $assassinationResult['gameState'],
@@ -36,14 +47,14 @@ if ($action === 'roll_dice') {
]);
}
-function roll_dice() {
+function roll_dice($config) {
$roll = rand(1, 6);
$event = '';
if ($roll <= 3) {
- $event = 'In the Imperial Palace: ' . imperial_palace_event();
+ $event = 'In the Imperial Palace: ' . imperial_palace_event($config);
} elseif ($roll <= 5) {
- $event = 'Relative Unrest: ' . relative_unrest_event();
+ $event = 'Relative Unrest: ' . relative_unrest_event($config);
} else {
$_SESSION['scores']['flames']++;
$event = 'The fires spread. +1 Flames.';
@@ -51,96 +62,102 @@ function roll_dice() {
return $event;
}
-function imperial_palace_event() {
+function imperial_palace_event($config) {
$roll = rand(1, 6);
$event = '';
switch ($roll) {
case 1:
$_SESSION['scores']['flames']++;
- $event = 'The emperor fiddles with manic glee. +1 Flames.';
+ $event = $config['imperial_palace_event_1'];
break;
case 2:
$_SESSION['scores']['desolation']++;
$_SESSION['scores']['relocation']++;
- $event = 'The emperor raises another horse to the position of senator. +1 Desolation, +1 Relocation.';
+ $event = $config['imperial_palace_event_2'];
break;
case 3:
$_SESSION['scores']['relocation']++;
- $event = 'It\'s execution night at the palace. +1 Relocation.';
+ $event = $config['imperial_palace_event_3'];
break;
case 4:
$_SESSION['scores']['desolation']++;
- $event = 'The emperor screams like a baby. +1 Desolation.';
+ $event = $config['imperial_palace_event_4'];
break;
case 5:
$_SESSION['scores']['flames']++;
$_SESSION['scores']['relocation']++;
- $event = 'The emperor sits in front of the flame and commands it to obey. It does not. +1 Flames, +1 Relocation.';
+ $event = $config['imperial_palace_event_5'];
break;
case 6:
$_SESSION['scores']['flames']++;
- $event = 'Work continues on a house made of pure gold. It keeps melting. +1 Flames.';
+ $event = $config['imperial_palace_event_6'];
break;
}
return $event;
}
-function relative_unrest_event() {
+function relative_unrest_event($config) {
$roll = rand(1, 6);
$event = '';
switch ($roll) {
case 1:
$_SESSION['scores']['relocation']++;
- $event = 'People complain - this is unacceptable. Then they go about their business. +1 Relocation.';
+ $event = $config['relative_unrest_event_1'];
break;
case 2:
$_SESSION['scores']['desolation']++;
- $event = 'There are no goods at market. +1 Desolation.';
+ $event = $config['relative_unrest_event_2'];
break;
case 3:
$_SESSION['scores']['relocation']++;
- $event = 'You receive a letter asking you to reassert your faith in the emperor. In writing. +1 Relocation.';
+ $event = $config['relative_unrest_event_3'];
break;
case 4:
$_SESSION['scores']['desolation']++;
$_SESSION['scores']['flames']++;
- $event = 'Lions are released onto the streets. +1 Desolation, +1 Flames.';
+ $event = $config['relative_unrest_event_4'];
break;
case 5:
$_SESSION['scores']['desolation']++;
- $event = 'Is Rome really over? +1 Desolation.';
+ $event = $config['relative_unrest_event_5'];
break;
case 6:
$_SESSION['scores']['flames']++;
- $event = 'The burnings will continue until morale improves. +1 Flames.';
+ $event = $config['relative_unrest_event_6'];
break;
}
return $event;
}
-function assassinate() {
+function assassinate($config) {
$desolation = $_SESSION['scores']['desolation'];
$total = 0;
for ($i = 0; $i < $desolation; $i++) {
$total += rand(1, 6);
}
- if ($total >= 20) {
+ if ($total >= $config['assassination_win']) {
return ['event' => 'You have assassinated the emperor! You die a martyr.', 'gameState' => 'win_assassination'];
} else {
return ['event' => 'Your attempt to assassinate the emperor has failed. You are executed.', 'gameState' => 'loss_assassination'];
}
}
-function check_game_state() {
- if ($_SESSION['scores']['flames'] >= 10) {
+function check_game_state($config) {
+ if ($_SESSION['scores']['flames'] >= $config['flames_win']) {
return 'loss_flames';
}
- if ($_SESSION['scores']['desolation'] >= 10) {
+ if ($_SESSION['scores']['desolation'] >= $config['desolation_win']) {
return 'loss_desolation';
}
- if ($_SESSION['scores']['relocation'] >= 10) {
+ if ($_SESSION['scores']['relocation'] >= $config['relocation_win']) {
return 'win';
}
return 'ongoing';
}
+
+function log_game($end_condition) {
+ global $db;
+ $stmt = $db->prepare('INSERT INTO game_logs (date_played, flames_score, desolation_score, relocation_score, end_condition) VALUES (?, ?, ?, ?, ?)');
+ $stmt->execute([date('Y-m-d H:i:s'), $_SESSION['scores']['flames'], $_SESSION['scores']['desolation'], $_SESSION['scores']['relocation'], $end_condition]);
+}
diff --git a/gemini.md b/gemini.md
new file mode 100644
index 0000000..d2ce797
--- /dev/null
+++ b/gemini.md
@@ -0,0 +1,8 @@
+Make the following updates to the project and update the readme file as needed for documentation.
+
+Add a sqlite backend for the following:
+- Game logs: Track date and time played, final scores, and end condition (escape, loss, assassination outcome, etc).
+- Configuration: Score thresholds, win conditions, event descriptions, etc.
+ - Default configuration should be provided using current hardcoded values.
+ - Allow user to modify configuration via a simple web form.
+ - Store configuration changes in the database.
diff --git a/index.php b/index.php
index 774ac69..cbf7ebe 100644
--- a/index.php
+++ b/index.php
@@ -19,6 +19,7 @@
Roll the Dice
Try to Assassinate the Emperor
New Game
+ Configuration
diff --git a/style.css b/style.css
index 34ad60b..02b5802 100644
--- a/style.css
+++ b/style.css
@@ -77,6 +77,23 @@ h1 { color: var(--h1-color-light); }
&:hover { background-color: var(--button-hover-background-color); }
}
+.actions a.button {
+ background-color: var(--button-background-color);
+ border: none;
+ color: var(--button-text-color);
+ cursor: pointer;
+ display: inline-block;
+ font-size: 1em;
+ margin: 0 .5rem 1.5rem;
+ padding: .5rem 1.5rem;
+ text-decoration: none;
+ transition: background-color 0.3s;
+}
+
+.actions a.button:hover {
+ background-color: var(--button-hover-background-color);
+}
+
.intro {
font-size: 1.1rem;
line-height: 1.4;