feature/game-endpoints #62
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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
@@ -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",
|
||||||
|
|||||||
Generated
+15
-14
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -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']);
|
||||||
|
|
||||||
Route::apiResource('games', GameController::class);
|
# Game Routes - Protected
|
||||||
|
Route::middleware('auth:sanctum')->group(function () {
|
||||||
|
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']);
|
||||||
|
});
|
||||||
@@ -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 }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user