Skip to content

Commit

Permalink
Allow players to choose game configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
marein committed Jan 24, 2025
1 parent 7aced33 commit 929c7bc
Show file tree
Hide file tree
Showing 33 changed files with 420 additions and 305 deletions.
8 changes: 8 additions & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,11 @@ notification-list {
[data-bs-theme=dark] .gp-game__field {
border-color: var(--tblr-blue);
}

/** Fix specificity for checked buttons on hover */
.btn-check:checked + .btn:hover {
color: var(--tblr-btn-active-color);
background-color: var(--tblr-btn-active-bg);
border-color: var(--tblr-btn-active-border-color);
box-shadow: var(--tblr-btn-active-shadow)
}
63 changes: 0 additions & 63 deletions assets/js/ConnectFour/OpenButton.js

This file was deleted.

1 change: 0 additions & 1 deletion config/connect-four/importmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
'connect-four-running-games' => ['path' => 'js/ConnectFour/RunningGames.js'],
'connect-four-game-list' => ['path' => 'js/ConnectFour/GameList.js'],
'connect-four-game' => ['path' => 'js/ConnectFour/Game.js'],
'connect-four-open-button' => ['path' => 'js/ConnectFour/OpenButton.js'],
'connect-four-abort-button' => ['path' => 'js/ConnectFour/AbortButton.js'],
'connect-four-resign-button' => ['path' => 'js/ConnectFour/ResignButton.js']
];
2 changes: 1 addition & 1 deletion config/web-interface/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ framework:
csrf_protection: false # CSRF protection is handled by marein/symfony-standard-headers-csrf-bundle.

twig:
form_themes: ['bootstrap_5_layout.html.twig']
form_themes: ['@web-interface/layout/forms.html.twig']
paths: { '%kernel.project_dir%/src/WebInterface/Presentation/Http/View': web-interface }

security:
Expand Down
12 changes: 11 additions & 1 deletion config/web-interface/routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ game:
methods: [GET]
controller: web-interface.page-controller::gameAction

challenge:
path: /challenge/{id}
methods: [GET]
controller: web-interface.page-controller::challengeAction

signup:
path: /signup
methods: [GET, POST]
Expand Down Expand Up @@ -73,7 +78,6 @@ open:
path: /api/connect-four/games/open
methods: [POST]
controller: web-interface.connect-four-controller::openAction
defaults: { _format: json }

abort:
path: /api/connect-four/games/{gameId}/abort
Expand All @@ -98,3 +102,9 @@ move:
methods: [POST]
controller: web-interface.connect-four-controller::moveAction
defaults: { _format: json }

challenge_abort:
path: /api/connect-four/challenges/{gameId}/abort
methods: [POST]
controller: web-interface.connect-four-controller::abortChallengeAction
defaults: { _format: json }
8 changes: 5 additions & 3 deletions config/web-interface/services/controller.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
services:
web-interface.page-controller:
class: Gaming\WebInterface\Presentation\Http\PageController
arguments: ['@twig', '@connect-four.query-bus', '@web-interface.security']
tags: ['controller.service_arguments']
arguments: ['@connect-four.query-bus', '@web-interface.security']
calls: [[setContainer, ['@Psr\Container\ContainerInterface']]]
tags: ['controller.service_arguments', 'container.service_subscriber']

web-interface.signup-controller:
class: Gaming\WebInterface\Presentation\Http\SignupController
Expand Down Expand Up @@ -34,4 +35,5 @@ services:
web-interface.connect-four-controller:
class: Gaming\WebInterface\Presentation\Http\ConnectFourController
arguments: ['@connect-four.command-bus', '@web-interface.security']
tags: ['controller.service_arguments']
calls: [[setContainer, ['@Psr\Container\ContainerInterface']]]
tags: ['controller.service_arguments', 'container.service_subscriber']
7 changes: 6 additions & 1 deletion deploy/load-test/scenario/play-connect-four.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ export default function () {

function open(jar) {
let url = `${baseUrl}/api/connect-four/games/open`;
return http.post(url, {}, {jar, headers}).json().gameId;
let response = http.post(
url,
{'open[size]': '7x6', 'open[variant]': 'standard', 'open[color]': '1'},
{jar, headers}
);
return response.url.match(/\/challenge\/(.*)$/)[1];
}

function join(jar, gameId) {
Expand Down
10 changes: 4 additions & 6 deletions src/ConnectFour/Application/Game/Command/OpenCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@
final class OpenCommand implements Request
{
public function __construct(
private readonly string $playerId
public readonly string $playerId,
public readonly int $width,
public readonly int $height,
public readonly int $stone
) {
}

public function playerId(): string
{
return $this->playerId;
}
}
11 changes: 9 additions & 2 deletions src/ConnectFour/Application/Game/Command/OpenHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

namespace Gaming\ConnectFour\Application\Game\Command;

use Gaming\ConnectFour\Domain\Game\Board\Size;
use Gaming\ConnectFour\Domain\Game\Board\Stone;
use Gaming\ConnectFour\Domain\Game\Configuration;
use Gaming\ConnectFour\Domain\Game\Game;
use Gaming\ConnectFour\Domain\Game\Games;
use Gaming\ConnectFour\Domain\Game\WinningRule\WinningRules;

final class OpenHandler
{
Expand All @@ -21,8 +24,12 @@ public function __invoke(OpenCommand $command): string
{
$game = Game::open(
$this->games->nextIdentity(),
Configuration::common(),
$command->playerId()
new Configuration(
new Size($command->width, $command->height),
WinningRules::standard(),
Stone::tryFrom($command->stone)
),
$command->playerId
);

$this->games->add($game);
Expand Down
74 changes: 19 additions & 55 deletions src/ConnectFour/Application/Game/Query/Model/Game/Game.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Gaming\ConnectFour\Domain\Game\Event\PlayerJoined;
use Gaming\ConnectFour\Domain\Game\Event\PlayerMoved;
use Gaming\ConnectFour\Domain\Game\WinningRule\WinningSequence;
use JsonSerializable;
use RuntimeException;

/**
Expand All @@ -24,60 +23,24 @@
* we send the user the latest projection from the event store. This way, the domain model
* itself stays clean and gets not inflated by a bunch of getters.
*/
final class Game implements JsonSerializable
final class Game
{
private string $gameId = '';

private string $chatId = '';

/**
* @var string[]
*/
private array $players = [];

private int $width = 0;

private int $height = 0;

private bool $finished = false;

/**
* @var WinningSequence[]
*/
private array $winningSequences = [];

/**
* @var Move[]
* @param string[] $players
* @param WinningSequence[] $winningSequences
* @param Move[] $moves
*/
private array $moves = [];

public function id(): string
{
return $this->gameId;
}

public function chatId(): string
{
return $this->chatId;
}

public function finished(): bool
{
return $this->finished;
}

public function jsonSerialize(): mixed
{
return [
'gameId' => $this->gameId,
'chatId' => $this->chatId,
'players' => $this->players,
'finished' => $this->finished,
'height' => $this->height,
'width' => $this->width,
'moves' => $this->moves,
'winningSequences' => $this->winningSequences
];
public function __construct(
public private(set) string $gameId = '',
public private(set) string $chatId = '',
public private(set) array $players = [],
public private(set) bool $finished = false,
public private(set) int $height = 0,
public private(set) int $width = 0,
public private(set) ?int $preferredStone = null,
public private(set) array $moves = [],
public private(set) array $winningSequences = []
) {
}

/**
Expand All @@ -102,9 +65,10 @@ public function apply(object $domainEvent): void
private function handleGameOpened(GameOpened $gameOpened): void
{
$this->gameId = $gameOpened->aggregateId();
$this->width = $gameOpened->width();
$this->height = $gameOpened->height();
$this->addPlayer($gameOpened->playerId());
$this->width = $gameOpened->width;
$this->height = $gameOpened->height;
$this->preferredStone = $gameOpened->preferredStone;
$this->addPlayer($gameOpened->playerId);
}

private function handlePlayerJoined(PlayerJoined $playerJoined): void
Expand Down
29 changes: 6 additions & 23 deletions src/ConnectFour/Application/Game/Query/Model/Game/Move.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,12 @@

namespace Gaming\ConnectFour\Application\Game\Query\Model\Game;

use JsonSerializable;

final class Move implements JsonSerializable
final class Move
{
private int $x;

private int $y;

private int $color;

public function __construct(int $x, int $y, int $color)
{
$this->x = $x;
$this->y = $y;
$this->color = $color;
}

public function jsonSerialize(): mixed
{
return [
'x' => $this->x,
'y' => $this->y,
'color' => $this->color
];
public function __construct(
public readonly int $x,
public readonly int $y,
public readonly int $color
) {
}
}
23 changes: 10 additions & 13 deletions src/ConnectFour/Domain/Game/Board/Size.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,29 @@

final class Size
{
private int $width;

private int $height;

/**
* @throws InvalidSizeException
*/
public function __construct(int $width, int $height)
{
public function __construct(
public readonly int $width,
public readonly int $height
) {
if ($width < 2 || $height < 2) {
throw new InvalidSizeException('Width and height must be greater then 1.');
}

if (($width * $height) % 2 !== 0) {
throw new InvalidSizeException('Product of width and height must be an even number.');
}

$this->height = $height;
$this->width = $width;
}

/**
* @deprecated Use property instead.
*/
public function width(): int
{
return $this->width;
}

/**
* @deprecated Use property instead.
*/
public function height(): int
{
return $this->height;
Expand Down
5 changes: 5 additions & 0 deletions src/ConnectFour/Domain/Game/Board/Stone.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ enum Stone: int
case None = 0;
case Red = 1;
case Yellow = 2;

public static function random(): self
{
return self::from(rand(1, 2));
}
}
Loading

0 comments on commit 929c7bc

Please sign in to comment.