AdventureController   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Test Coverage

Coverage 71.93%

Importance

Changes 8
Bugs 0 Features 2
Metric Value
eloc 56
c 8
b 0
f 2
dl 0
loc 119
ccs 41
cts 57
cp 0.7193
rs 10
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 29 1
A performAction() 0 47 4
A start() 0 19 2
A renderLocation() 0 14 1
1
<?php
2
3
namespace App\Controller;
4
5
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Component\HttpFoundation\Response;
8
use Symfony\Component\Routing\Annotation\Route;
9
use Symfony\Component\HttpFoundation\Session\SessionInterface;
10
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
11
use Doctrine\Persistence\ManagerRegistry;
12
use App\Adventure\Utils\GameSetupManager;
13
use App\Adventure\Utils\Unpacker;
14
use App\Adventure\Log;
15
use App\Adventure\Inventory;
16
use App\Adventure\Location;
17
use App\Adventure\Game;
18
19
class AdventureController extends AbstractController
20
{
21 1
    #[Route('/proj/game', name: 'start_game')]
22
    public function start(SessionInterface $session, Request $request): Response
23
    {
24 1
        $session->invalidate(); // Make sure session is cleared before attempting to start a new game
25
26
        // Check if the player has been directed here with a message
27 1
        $message = $request->query->get('message', null);
28
29 1
        if ($message === null) {
30
            // Show default message otherwise
31 1
            $message =
32 1
                "Welcome! You are about to embark on an epic adventure.\n" .
33 1
                "To begin, type 'start' (or 'restart'). You can use this action during the game to start over from the beginning.\n\n" .
34 1
                "Remember, at any time during the game, you can type 'help' for assistance. Good luck!\n";
35
        }
36
37 1
        return $this->render('proj/location.html.twig', [
38 1
            'entries' => [$message],
39 1
            'inputs' => [],
40 1
        ]);
41
    }
42
43
    #[Route('/proj/game/init', name: 'setup_game')]
44
    public function init(SessionInterface $session, ManagerRegistry $doctrine): Response
45
    {
46
        // Set up game from database
47
        $entityManager = $doctrine->getManager('game');
48
        $gameManager = new GameSetupManager($entityManager);
49
        $game = $gameManager->setupGameFromDatabase();
50
51
        // Set the player's inventory
52
        $inventory = new Inventory();
53
        $game->setInventory($inventory);
54
55
        $session->set('game', $game); // Save the configured game instance
56
57
        // Create a new log
58
        $log = new Log();
59
60
        /** @var Location */
61
        $startingLocation = $game->getCurrentLocation(); // Get the starting location
62
63
        // Add some instructions after the first location's description to help the player get started
64
        $message = Unpacker::unpackLocationDescriptions($startingLocation) . "\n";
65
        $message .= "You can have a closer look at objects in the scene by typing 'examine' followed by the name of the object. Interactable objects are enclosed in brackets [name].";
66
67
        $log->addEntry($message); // Save to log
68
69
        $session->set('game_log', $log);
70
71
        return $this->redirectToRoute('render_location');
72
    }
73
74 2
    #[Route('/proj/game/location', name: 'render_location')]
75
    public function renderLocation(SessionInterface $session): Response
76
    {
77
        /** @var Log */
78 2
        $log = $session->get('game_log', new Log()); // Get all logged entries
79 2
        $entries = $log->getEntries();
80
81
        /** @var Log */
82 2
        $inputLog = $session->get('input_log', new Log()); // Get logged inputs separately
83 2
        $inputs = $inputLog->getEntries();
84
85 2
        return $this->render('proj/location.html.twig', [
86 2
            'entries' => $entries,
87 2
            'inputs' => $inputs,
88 2
        ]);
89
    }
90
91 2
    #[Route('/proj/game/action', name: 'perform_action', methods: ['POST'])]
92
    public function performAction(SessionInterface $session, Request $request): Response
93
    {
94
        /** @var string */
95 2
        $userInput = $request->get('input');
96
97
        // Split the input into action and target
98 2
        $parts = explode(' ', $userInput, 2);
99
100 2
        $action = $parts[0] ?? ''; // Get the first part as action, e.g. 'go'
101 2
        $target = $parts[1] ?? ''; // Get the second part as target, e.g. 'south'
102
103
        // Restart the game
104 2
        if ($action === 'start' || $action === 'restart') {
105 1
            $session->invalidate();
106
107 1
            return $this->redirectToRoute('setup_game');
108
        }
109
110
        /** @var Game|null */
111 1
        $game = $session->get('game', null); // Retrieve game object
112
113
        // Check game before attempting to process action, redirect if not found
114 1
        if ($game === null) {
115
            $message = "Please start a new game by typing 'start'.";
116
117
            return $this->redirectToRoute('start_game', ['message' => $message]);
118
        }
119
120
        /** @var Log */
121 1
        $inputLog = $session->get('input_log', new Log()); // Only for logging user input
122
123
        /** @var Log */
124 1
        $log = $session->get('game_log', new Log());
125
126 1
        $inputLog->addEntry($userInput); // Save input
127 1
        $session->set('input_log', $inputLog);
128
129 1
        $log->addEntry($userInput); // Save input to the main log too
130
131 1
        $result = $game->processAction($action, $target);
132 1
        $log->addEntry($result); // Save response to the main log
133
134 1
        $session->set('game', $game);
135 1
        $session->set('game_log', $log);
136
137 1
        return $this->redirectToRoute('render_location');
138
    }
139
}
140