Added initial game logic

This commit is contained in:
2025-12-12 00:05:37 +00:00
parent af41990807
commit 7686aff546
7 changed files with 114 additions and 22 deletions
+71 -2
View File
@@ -59,10 +59,79 @@ class GameController extends Controller
*/ */
public function store(StoreGameRequest $request) public function store(StoreGameRequest $request)
{ {
$game = Game::create($request->validated()); $validated = $request->validated();
return response()->json($game, 201); $user = $request->user();
$type = $validated['variant'] === 'bisca-3' ? '3' : '9';
$initialState = $this->initializeGameState($type);
$game = Game::create([
'type' => $type,
'status' => 'in_progress',
'player1_user_id' => $user->id,
'player2_user_id' => $validated['mode'] === 'multiplayer'
? $validated['opponent_id']
: 1, // REPLACE 1 with your actual Bot User ID
'began_at' => now(),
'custom' => json_encode($initialState),
'player1_points' => 0,
'player2_points' => 0,
]);
return response()->json([
'message' => 'Game created successfully',
'game_id' => $game->id,
'game_state' => $initialState,
], 201);
} }
private function initializeGameState($type)
{
$handSize = $type === 'S' ? 3 : 9;
$suits = ['H', 'D', 'C', 'S'];
$ranks = ['2', '3', '4', '5', '6', '7', 'J', 'Q', 'K', 'A'];
$values = [
'2' => 0, '3' => 0, '4' => 0, '5' => 0, '6' => 0,
'7' => 10, 'J' => 3, 'Q' => 2, 'K' => 4, 'A' => 11
];
$deck = [];
foreach ($suits as $suit) {
foreach ($ranks as $rank) {
$deck[] = ['suit' => $suit, 'rank' => $rank, 'value' => $values[$rank]];
}
}
// Shuffle and deal
shuffle($deck);
$player1Hand = array_splice($deck, 0, $handSize);
$player2Hand = array_splice($deck, 0, $handSize);
// Trump is the suit of the last card in the remaining stock
$trumpCard = null;
if (count($deck) > 0) {
$trumpCard = $deck[count($deck) - 1]; // Bottom card
}
return [
'player1_hand' => $player1Hand,
'player2_hand' => $player2Hand,
'stock' => $deck,
'trump' => $trumpCard ? $trumpCard['suit'] : null,
'current_trick' => [],
'current_turn' => 'player1',
'score' => [
'player1' => 0,
'player2' => 0
],
'captured' => [
'player1' => [],
'player2' => []
]
];
}
/** /**
* Display the specified resource. * Display the specified resource.
*/ */
@@ -0,0 +1,11 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\StoreGameRequest;
class UserController extends Controller
{
}
+6 -2
View File
@@ -11,7 +11,7 @@ class StoreGameRequest extends FormRequest
*/ */
public function authorize(): bool public function authorize(): bool
{ {
return false; return true;
} }
/** /**
@@ -22,7 +22,11 @@ class StoreGameRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
// 'variant' => 'required|in:bisca-3,bisca-9',
'mode' => 'required|in:single-player,multiplayer',
'opponent_id' => $this->mode === 'multiplayer'
? 'required|exists:users,id'
: 'nullable',
]; ];
} }
} }
+1 -1
View File
@@ -17,7 +17,7 @@
"require-dev": { "require-dev": {
"fakerphp/faker": "^1.23", "fakerphp/faker": "^1.23",
"laravel/pail": "^1.2.2", "laravel/pail": "^1.2.2",
"laravel/pint": "^1.24", "laravel/pint": "^1.26",
"laravel/sail": "^1.48", "laravel/sail": "^1.48",
"mockery/mockery": "^1.6", "mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.6", "nunomaduro/collision": "^8.6",
+15 -14
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "6ad8f0aa2267878e2374cd4ba4042946", "content-hash": "353b4e6bf34bd12906db0059bb3a9207",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@@ -6575,16 +6575,16 @@
}, },
{ {
"name": "laravel/pint", "name": "laravel/pint",
"version": "v1.25.1", "version": "v1.26.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/pint.git", "url": "https://github.com/laravel/pint.git",
"reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9" "reference": "69dcca060ecb15e4b564af63d1f642c81a241d6f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/5016e263f95d97670d71b9a987bd8996ade6d8d9", "url": "https://api.github.com/repos/laravel/pint/zipball/69dcca060ecb15e4b564af63d1f642c81a241d6f",
"reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9", "reference": "69dcca060ecb15e4b564af63d1f642c81a241d6f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -6595,13 +6595,13 @@
"php": "^8.2.0" "php": "^8.2.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.87.2", "friendsofphp/php-cs-fixer": "^3.90.0",
"illuminate/view": "^11.46.0", "illuminate/view": "^12.40.1",
"larastan/larastan": "^3.7.1", "larastan/larastan": "^3.8.0",
"laravel-zero/framework": "^11.45.0", "laravel-zero/framework": "^12.0.4",
"mockery/mockery": "^1.6.12", "mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^2.3.1", "nunomaduro/termwind": "^2.3.3",
"pestphp/pest": "^2.36.0" "pestphp/pest": "^3.8.4"
}, },
"bin": [ "bin": [
"builds/pint" "builds/pint"
@@ -6627,6 +6627,7 @@
"description": "An opinionated code formatter for PHP.", "description": "An opinionated code formatter for PHP.",
"homepage": "https://laravel.com", "homepage": "https://laravel.com",
"keywords": [ "keywords": [
"dev",
"format", "format",
"formatter", "formatter",
"lint", "lint",
@@ -6637,7 +6638,7 @@
"issues": "https://github.com/laravel/pint/issues", "issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint" "source": "https://github.com/laravel/pint"
}, },
"time": "2025-09-19T02:57:12+00:00" "time": "2025-11-25T21:15:52+00:00"
}, },
{ {
"name": "laravel/sail", "name": "laravel/sail",
@@ -9380,12 +9381,12 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": {}, "stability-flags": [],
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.2" "php": "^8.2"
}, },
"platform-dev": {}, "platform-dev": [],
"plugin-api-version": "2.6.0" "plugin-api-version": "2.6.0"
} }
+8 -1
View File
@@ -2,11 +2,12 @@
use App\Http\Controllers\AuthController; use App\Http\Controllers\AuthController;
use App\Http\Controllers\GameController; use App\Http\Controllers\GameController;
use App\Http\Controllers\UserController;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
# Authentication Routes
Route::post('/login', [AuthController::class, 'login']); Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () { Route::middleware('auth:sanctum')->group(function () {
@@ -18,4 +19,10 @@ Route::middleware('auth:sanctum')->group(function () {
Route::post('/register', [AuthController::class, 'register']); Route::post('/register', [AuthController::class, 'register']);
# Game Routes - Protected
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('games', GameController::class); Route::apiResource('games', GameController::class);
Route::post('/games/{game}/resign', [GameController::class, 'resign']);
Route::post('/games/{game}/play-card', [GameController::class, 'playCard']);
Route::get('/users/{user}/matches', [UserController::class, 'getMatches']);
});
+1 -1
View File
@@ -38,7 +38,7 @@ export const useGameStore = defineStore('game', () => {
// Initialize deck // Initialize deck
const initializeDeck = () => { const initializeDeck = () => {
const suits = ['', '', '', ''] const suits = ['H', 'D', 'C', 'S']
const ranks = ['2', '3', '4', '5', '6', '7', 'J', 'Q', 'K', 'A'] const ranks = ['2', '3', '4', '5', '6', '7', 'J', 'Q', 'K', 'A']
const values = { '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 0, 'J': 2, 'Q': 3, 'K': 4, 'A': 11 } const values = { '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 0, 'J': 2, 'Q': 3, 'K': 4, 'A': 11 }