diff --git a/composer.json b/composer.json index 2194ca0..9da9fe8 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "phpstan/phpdoc-parser": "^1.14", "symfony/asset": "6.1.*", "symfony/console": "6.1.*", - "symfony/doctrine-messenger": "6.1.*", "symfony/dotenv": "6.1.*", "symfony/expression-language": "6.1.*", "symfony/flex": "^2", @@ -32,7 +31,7 @@ "symfony/process": "6.1.*", "symfony/property-access": "6.1.*", "symfony/property-info": "6.1.*", - "symfony/runtime": "6.1.*", + "symfony/runtime": "^6.3.2", "symfony/security-bundle": "6.1.*", "symfony/serializer": "6.1.*", "symfony/string": "6.1.*", diff --git a/composer.lock b/composer.lock index e61e046..44b1046 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d0596df364527b4a2e7e00a9d7213e87", + "content-hash": "a904471bc7e1136f2c1810044504fcc9", "packages": [ { "name": "doctrine/cache", @@ -2558,78 +2558,6 @@ ], "time": "2023-01-10T18:53:01+00:00" }, - { - "name": "symfony/doctrine-messenger", - "version": "v6.1.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "e4b775d2dadcc801d2404c701555c2638690811e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/e4b775d2dadcc801d2404c701555c2638690811e", - "reference": "e4b775d2dadcc801d2404c701555c2638690811e", - "shasum": "" - }, - "require": { - "doctrine/dbal": "^2.13|^3.0", - "php": ">=8.1", - "symfony/messenger": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3" - }, - "conflict": { - "doctrine/persistence": "<1.3" - }, - "require-dev": { - "doctrine/persistence": "^1.3|^2|^3", - "symfony/property-access": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" - }, - "type": "symfony-messenger-bridge", - "autoload": { - "psr-4": { - "Symfony\\Component\\Messenger\\Bridge\\Doctrine\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Doctrine Messenger Bridge", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v6.1.11" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-01T08:36:55+00:00" - }, { "name": "symfony/dotenv", "version": "v6.1.11", @@ -3945,92 +3873,6 @@ ], "time": "2023-01-10T18:53:01+00:00" }, - { - "name": "symfony/messenger", - "version": "v6.1.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/messenger.git", - "reference": "e3b7323b1d59fc77f5870735809bf39ce1596aee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/e3b7323b1d59fc77f5870735809bf39ce1596aee", - "reference": "e3b7323b1d59fc77f5870735809bf39ce1596aee", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/log": "^1|^2|^3" - }, - "conflict": { - "symfony/event-dispatcher": "<5.4", - "symfony/event-dispatcher-contracts": "<2", - "symfony/framework-bundle": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/serializer": "<5.4" - }, - "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0" - }, - "suggest": { - "enqueue/messenger-adapter": "For using the php-enqueue library as a transport." - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Messenger\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Samuel Roze", - "email": "samuel.roze@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Helps applications send and receive messages to/from other applications or via message queues", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/messenger/tree/v6.1.11" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-20T17:44:30+00:00" - }, { "name": "symfony/mime", "version": "v6.1.11", @@ -5293,16 +5135,16 @@ }, { "name": "symfony/runtime", - "version": "v6.1.11", + "version": "v6.4.22", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "717cb91d66893a27a4607f227e28eb74ff007fde" + "reference": "832c3ce3b810509815050434ccb7ead68d06395b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/717cb91d66893a27a4607f227e28eb74ff007fde", - "reference": "717cb91d66893a27a4607f227e28eb74ff007fde", + "url": "https://api.github.com/repos/symfony/runtime/zipball/832c3ce3b810509815050434ccb7ead68d06395b", + "reference": "832c3ce3b810509815050434ccb7ead68d06395b", "shasum": "" }, "require": { @@ -5314,10 +5156,10 @@ }, "require-dev": { "composer/composer": "^1.0.2|^2.0", - "symfony/console": "^5.4|^6.0", - "symfony/dotenv": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0" + "symfony/console": "^5.4.9|^6.0.9|^7.0", + "symfony/dotenv": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0" }, "type": "composer-plugin", "extra": { @@ -5348,8 +5190,11 @@ ], "description": "Enables decoupling PHP applications from global state", "homepage": "https://symfony.com", + "keywords": [ + "runtime" + ], "support": { - "source": "https://github.com/symfony/runtime/tree/v6.1.11" + "source": "https://github.com/symfony/runtime/tree/v6.4.22" }, "funding": [ { @@ -5365,7 +5210,7 @@ "type": "tidelift" } ], - "time": "2023-01-20T17:44:30+00:00" + "time": "2025-05-07T21:15:03+00:00" }, { "name": "symfony/security-bundle", diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml deleted file mode 100644 index 270f3c7..0000000 --- a/config/packages/messenger.yaml +++ /dev/null @@ -1,29 +0,0 @@ -framework: - messenger: - failure_transport: failed - - transports: - # https://symfony.com/doc/current/messenger.html#transport-configuration - async: - dsn: '%env(MESSENGER_TRANSPORT_DSN)%' - options: - use_notify: true - check_delayed_interval: 60000 - retry_strategy: - max_retries: 3 - multiplier: 2 - failed: 'doctrine://default?queue_name=failed' - # sync: 'sync://' - - default_bus: messenger.bus.default - - buses: - messenger.bus.default: [] - - routing: - Symfony\Component\Mailer\Messenger\SendEmailMessage: async - Symfony\Component\Notifier\Message\ChatMessage: async - Symfony\Component\Notifier\Message\SmsMessage: async - - # Route your messages to the transports - # 'App\Message\YourMessage': async diff --git a/docs/commandeDebugProjet.md b/docs/commandeDebugProjet.md new file mode 100644 index 0000000..7c14f92 --- /dev/null +++ b/docs/commandeDebugProjet.md @@ -0,0 +1,48 @@ +création entity : + +php bin/console make:entity Emoji + +Réinstaller orm + doctrine_bundle : + +composer require doctrine/orm doctrine/doctrine-bundle + +Recompiler l'autoload (utile si ça persiste) + +- composer dump-autoload + + Vérifie ensuite que l’entité est bien reconnue : + +- php bin/console doctrine:mapping:info +'''Found 1 mapped entity: +[OK] App\Entity\Emoji''' + + +php bin/console make:migration +php bin/console doctrine:migrations:migrate + +------- + +Récréation BDD quand pb migrations : + +php bin/console doctrine:database:drop --force +php bin/console doctrine:database:create +php bin/console doctrine:migrations:migrate + + +------- + +Solution : Forcer la mise à jour de phpstan/phpdoc-parser + +- composer require phpstan/phpdoc-parser:^1.26 + +Cree la BDD : + +''' Modification .env (pour retirer URL_BDD) + Ajout .env.local (pour ajouter URL_BDD)''' + +- symfony console doctrine:database:create + +ok j'ai creer ma BDD avec symfony console doctrine:database:create comment j'applique mon entity dans la BDD que j'avais créer précedement avec symfony console + + + diff --git a/public/css/home.css b/public/css/home.css new file mode 100644 index 0000000..d8e65e7 --- /dev/null +++ b/public/css/home.css @@ -0,0 +1,248 @@ +body { + background-color: #314e57; + font-family: 'Georgia', serif; + text-align: center; +} + +h1 { + font-size: 3rem; + margin-bottom: 30px; + text-shadow: 2px 2px 4px #000; + color: #f8b435; +} + +.emoji-container { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 30px; + margin-bottom: 10rem; +} + +.emoji-card { + background: #f2e6c9; + width: 180px; + height: 220px; + border: 4px solid #000; + border-radius: 12px; + box-shadow: 0 0 20px rgba(0,0,0,0.5); + padding: 20px; + text-align: center; + font-family: 'Georgia', serif; + position: relative; + transition: transform 0.2s ease, box-shadow 0.2s ease; + cursor: pointer; +} + +.emoji-card:hover { + transform: translateY(-8px) scale(1.03); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5); + z-index: 2; +} + +/* Animation brillance pour rareté légendaire */ +@keyframes shine { + 0% { background-position: 0px; } + 100% { background-position: 177px; } +} + +.emoji-card.gold { + position: relative; + z-index: 1; +} + +.emoji-card.gold::before { + content: ''; + position: absolute; + top: 0; + left: 1%; + width: 98%; + height: 100%; + background: linear-gradient( + 120deg, + rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.5) 50%, + rgba(255, 255, 255, 0) 100% + ); + animation: shine 5s infinite; + pointer-events: none; + z-index: -1; +} + +.emoji-card > * { + position: relative; + z-index: 1; +} + +/*---------------------------*/ + +.emoji-card.gray { border-color: gray; } + +@keyframes auraGlow { + 0% { box-shadow: 0 0 10px 0 rgba(0,0,0,0.3); } + 50% { box-shadow: 0 0 25px 8px currentColor; } + 100% { box-shadow: 0 0 10px 0 rgba(0,0,0,0.3); } +} + +/* Applique une animation d'aura par rareté */ +.emoji-card.green { + color: darkgreen; + animation: auraGlow 3s infinite ease-in-out; +} + +.emoji-card.purple { + color: purple; + animation: auraGlow 3s infinite ease-in-out; +} + +.emoji-card.red { + color: darkred; + animation: auraGlow 3s infinite ease-in-out; +} + +.emoji-card.gold { + color: goldenrod; + animation: auraGlow 3s infinite ease-in-out; +} + + +/* Couleurs des noms selon rareté */ +.emoji-name.green { color: darkgreen; } +.emoji-name.purple { color: purple; } +.emoji-name.red { color: darkred; } +.emoji-name.gold { color: goldenrod; } +.emoji-name.gray { color: gray; } + +.emoji-card .emoji { + font-size: 50px; + margin-bottom: 10px; +} + +.emoji-name { + font-weight: bold; + font-size: 1.2rem; + margin-top: 5px; + color: purple; +} + +.emoji-level { + font-size: 1rem; + font-weight: bold; + color: #3c2f2f; + margin-bottom: 10px; +} + +.action-buttons { + display: flex; + justify-content: center; + gap: 60px; + margin-top: 20px; +} + +.btn { + background: #f2e6c9; + border: 3px solid #000; + padding: 10px 25px; + font-size: 1.2rem; + font-weight: bold; + border-radius: 8px; + cursor: pointer; + transition: transform 0.2s ease; + box-shadow: 3px 3px 0 #000; +} + +.btn:hover { + transform: scale(1.05); + background-color: #e5d6b8; +} + +.detail-icon { +position: absolute; +top: 8px; +right: 10px; +cursor: pointer; +font-size: 18px; +color: #555; +} + +.popup { + position: absolute; + top: 110%; + left: 50%; + transform: translateX(-50%); + background: #fff8e1; + color: #000; + padding: 10px; + border: 2px solid #000; + border-radius: 8px; + box-shadow: 0 0 10px rgba(0,0,0,0.3); + display: none; + z-index: 10; + width: 180px; + font-size: 14px; +} + +/* Filtre et Tri*/ +.filter-bar { + margin-bottom: 30px; + color: #f8f5e0; + font-size: 1rem; +} + +.filter-bar select { + margin: 0 10px; + padding: 5px 10px; + border-radius: 6px; + border: 2px solid #000; + background: #f2e6c9; + font-family: 'Georgia', serif; +} + +/* Champs de Recherche */ +.filter-bar input[type="text"] { + padding: 5px 10px; + border-radius: 6px; + border: 2px solid #000; + background: #f2e6c9; + font-family: 'Georgia', serif; + margin-right: 10px; +} + +/* Style séléction créature pour combat / accouplement */ + +/* Etat séléctionné */ +.emoji-card.selected { + outline: 4px solid #f8b435; + outline-offset: -4px; + box-shadow: 0 0 30px 10px rgba(248, 180, 53, 0.6); +} + +#selection-status { + font-size: 1.1rem; + margin-bottom: 20px; + font-weight: bold; + color: #f9e8c0; +} + +.selection-visual { + display: flex; + justify-content: center; + align-items: center; + gap: 15px; + margin-bottom: 30px; +} + +.creature-tag { + padding: 8px 15px; + background: #f2e6c9; + border: 2px solid #000; + border-radius: 8px; + font-weight: bold; + font-size: 1.1rem; + box-shadow: 2px 2px 0 #000; +} + +.vs-text { + font-size: 1.5rem; + font-weight: bold; +} \ No newline at end of file diff --git a/public/js/home.js b/public/js/home.js new file mode 100644 index 0000000..fa7b9d6 --- /dev/null +++ b/public/js/home.js @@ -0,0 +1,141 @@ +document.addEventListener('DOMContentLoaded', () => { + // Copie tout ici + let selectedCards = []; + + function toggleSelection(card) { + const id = card.dataset.id; + + if (card.classList.contains('selected')) { + card.classList.remove('selected'); + selectedCards = selectedCards.filter(c => c.dataset.id !== id); + } else { + if (selectedCards.length < 2) { + card.classList.add('selected'); + selectedCards.push(card); + } else { + alert("Tu ne peux sélectionner que 2 créatures à la fois."); + } + } + + updateSelectionDisplay(); + } + + function updateSelectionDisplay() { + const status = document.getElementById("selection-status"); + const visual = document.getElementById("selection-visual"); + + if (selectedCards.length === 0) { + status.textContent = "Sélectionnez 2 créatures..."; + visual.innerHTML = ""; + } else if (selectedCards.length === 1) { + status.textContent = `1ère sélection : ${selectedCards[0].dataset.name}`; + visual.innerHTML = ""; + } else { + status.textContent = "2 créatures sélectionnées !"; + visual.innerHTML = ` +
${selectedCards[0].dataset.name}
+ et +
${selectedCards[1].dataset.name}
+ `; + } + } + + function handleAction(type) { + if (selectedCards.length !== 2) { + alert("Tu dois sélectionner 2 créatures."); + return; + } + + const name1 = selectedCards[0].dataset.name; + const name2 = selectedCards[1].dataset.name; + + if (type === 'combat') { + console.log(`Combat : ${name1} contre ${name2}`); + } else if (type === 'reproduction') { + console.log(`Accouplement : ${name1} et ${name2}`); + } + + // Réinitialiser après l'action + selectedCards.forEach(card => card.classList.remove('selected')); + selectedCards = []; + updateSelectionDisplay(); + } + + // Ouvre / Ferme la popup d'information + function togglePopup(id) { + const popup = document.getElementById('popup-' + id); + popup.style.display = (popup.style.display === 'block') ? 'none' : 'block'; + } + + // Fermer les autres popups en cliquant ailleurs + document.addEventListener('click', function(e) { + document.querySelectorAll('.popup').forEach(p => { + if (!p.contains(e.target) && !p.previousElementSibling.contains(e.target)) { + p.style.display = 'none'; + } + }); + }); + + // Fonction pour appliquer la recherche, les filtres et le tri + function applyFilters() { + const selectedColor = document.getElementById('rarete-filter').value; + const sortBy = document.getElementById('sort-select').value; + const searchTerm = document.getElementById('search-input').value.toLowerCase(); + + const cards = Array.from(document.querySelectorAll('.emoji-card')); + + cards.forEach(card => { + const color = card.dataset.color; + const name = card.querySelector('.emoji-name')?.textContent.toLowerCase() ?? ""; + + const matchColor = !selectedColor || color === selectedColor; + const matchName = !searchTerm || name.includes(searchTerm); + + if (matchColor && matchName) { + card.style.display = 'block'; + } else { + card.style.display = 'none'; + } + }); + + if (sortBy !== 'none') { + const container = document.querySelector('.emoji-container'); + const visibleCards = cards.filter(c => c.style.display !== 'none'); + + visibleCards.sort((a, b) => { + const aVal = parseFloat(a.dataset[sortBy]); + const bVal = parseFloat(b.dataset[sortBy]); + return bVal - aVal; + }); + + visibleCards.forEach(card => container.appendChild(card)); + } + } + + // Appel Fonctionnalité de popup d'information + document.querySelectorAll('.detail-icon').forEach(icon => { + icon.addEventListener('click', (e) => { + const id = icon.parentElement.dataset.id; + togglePopup(id); + e.stopPropagation(); // empêche le clic d’aller à la carte + }); + }); + + // Appel Fonctionnalité de sélection des cartes + document.querySelectorAll('.emoji-card').forEach(card => { + card.addEventListener('click', () => toggleSelection(card)); + }); + + // Appel Fonctionnalité de combat et reproduction + document.querySelectorAll('.btn').forEach(button => { + button.addEventListener('click', () => { + const type = button.textContent.includes('Combattre') ? 'combat' : 'reproduction'; + handleAction(type); + }); + }); + + // Appel Fonctionnalité de recherche et filtres + document.getElementById('search-input').addEventListener('input', applyFilters); + document.getElementById('rarete-filter').addEventListener('change', applyFilters); + document.getElementById('sort-select').addEventListener('change', applyFilters); +}); \ No newline at end of file diff --git a/src/Controller/EmojiController.php b/src/Controller/EmojiController.php index bc4359d..3b3bac2 100644 --- a/src/Controller/EmojiController.php +++ b/src/Controller/EmojiController.php @@ -2,13 +2,21 @@ namespace App\Controller; use App\Entity\Emoji; +use App\Entity\Rarity; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use App\Repository\RarityRepository; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\HttpFoundation\Request; +use App\Repository\EmojiRepository; +#[Route('/emoji', name: 'emoji')] class EmojiController extends AbstractController { - #[Route('/emoji', name: 'app_emoji')] + #[Route('/emoji', name: 'app_emoji')] public function index(): Response { return $this->render('emoji/index.html.twig', [ @@ -16,7 +24,114 @@ class EmojiController extends AbstractController ]); } - public function reproduceEmoji(Emoji $emoji1, Emoji $emoji2): Emoji { - return new Emoji(); + private function getRarity(): Rarity { + $rarity = $this->rarityRepository->findAll(); + $rand = mt_rand() / mt_getrandmax(); + + $sum = 0.0; + foreach($rarity as $r) { + $sum += $r->getDropRate(); + if($sum > $rand) { + return $r; + } + } + + return $rarity[0]; + } + + // Renvoi l'url de l'image issue de la fusion de deux emojis. Fonctionne avec un code et un emoji directement + private function getFusionUrl(string $emoji1, string $emoji2): string + { + $baseUrl = 'https://emojik.vercel.app/s/'; + $size = 256; + + // On encode les string pour l'url + $encodedEmoji1 = urlencode($emoji1); + $encodedEmoji2 = urlencode($emoji2); + + return sprintf('%s%s_%s?size=%d', $baseUrl, $encodedEmoji1, $encodedEmoji2, $size); + } + + #[Route('/fusion/{emoji1_id}/{emoji2_id}', name: 'fusion')] + public function reproduceEmoji(int $emoji1_id, int $emoji2_id, EntityManagerInterface $entityManager, EmojiRepository $emojiRepository): JsonResponse { + $emoji1 = $emojiRepository->find($emoji1_id); + $emoji2 = $emojiRepository->find($emoji2_id); + + if (!$emoji1 || !$emoji2) { + return new JsonResponse(['error' => 'One or both emojis not found'], 404); + } + + $child = new Emoji(); + + $child->setName("Testenfant"); + + // Chance de fusion + $fusionRand = mt_rand() / mt_getrandmax(); + if($fusionRand > 0.8) { + // Si les emoji parents sont des fusions on remonte l'arbre généalogique jusqu'à trouver un smiley normal + // On ne peut pas fusionner un smiley déjà fusionné + $temp1 = $emoji1; + while(str_contains($temp1->getCode(), "vercel")) { + $temp1 = $temp1->getParent1(); + } + + $temp2 = $emoji2; + while(str_contains($temp2->getCode(), "vercel")) { + $temp2 = $temp2->getParent2(); + } + + $child->setCode($this->getFusionUrl($temp1->getCode(), $temp2->getCode())); + } else { + $rand = mt_rand() / mt_getrandmax(); + if($rand > 0.5) { + $child->setCode($emoji1->getCode()); + } else { + $child->setCode($emoji2->getCode()); + } + } + + // Lors d'une fusion un emoji récupère chaque stat d'un de ces deux parents de manière aléatoire + $rand = mt_rand() / mt_getrandmax(); + if($rand > 0.5) { + $child->setStrength($emoji1->getStrength()); + } else { + $child->setStrength($emoji2->getStrength()); + } + + $rand = mt_rand() / mt_getrandmax(); + if($rand > 0.5) { + $child->setToughness($emoji1->getToughness()); + } else { + $child->setToughness($emoji2->getToughness()); + } + + $rand = mt_rand() / mt_getrandmax(); + if($rand > 0.5) { + $child->setIntelligence($emoji1->getIntelligence()); + } else { + $child->setIntelligence($emoji2->getIntelligence()); + } + + $rand = mt_rand() / mt_getrandmax(); + if($rand > 0.5) { + $child->setSpeed($emoji1->getSpeed()); + } else { + $child->setSpeed($emoji2->getSpeed()); + } + + $child->setFightsWon(0); + + $child->setRarity($this->getRarity()); + + $child->setParent1($emoji1); + $child->setParent2($emoji2); + + $entityManager->persist($child); + $entityManager->flush(); + + return new JsonResponse([ + 'message' => 'Child created', + 'childId' => $child->getId() + ]); } -} +} \ No newline at end of file diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php new file mode 100644 index 0000000..f5df842 --- /dev/null +++ b/src/Controller/HomeController.php @@ -0,0 +1,66 @@ + 1, + 'nom' => 'Bob', + 'code' => '😊', + 'force' => 12.5, + 'robustesse' => 9.3, + 'intelligence' => 7.8, + 'vitesse' => 10.0, + 'nbCombatGagne' => 3, + 'rarete' => 2, // épique + ], + [ + 'id' => 2, + 'nom' => 'John', + 'code' => '😭', + 'force' => 5.1, + 'robustesse' => 4.2, + 'intelligence' => 3.3, + 'vitesse' => 6.0, + 'nbCombatGagne' => 1, + 'rarete' => 1, // commun + ], + [ + 'id' => 3, + 'nom' => 'Rodolph', + 'code' => '😁', + 'force' => 20.0, + 'robustesse' => 15.0, + 'intelligence' => 18.0, + 'vitesse' => 17.0, + 'nbCombatGagne' => 10, + 'rarete' => 4, // légendaire + ] + ]; + + // Ajout de la couleur selon la rareté + foreach ($emojis as &$emoji) { + + $emoji['color'] = match ($emoji['rarete']) { + 1 => 'green', // commun + 2 => 'purple', // épique + 3 => 'red', // mythique + 4 => 'gold', // légendaire + default => 'gray' + }; + } + + return $this->render('home/index.html.twig', [ + 'emojis' => $emojis, + ]); + } +} diff --git a/src/Entity/Emoji.php b/src/Entity/Emoji.php index 1820873..f3bb04a 100644 --- a/src/Entity/Emoji.php +++ b/src/Entity/Emoji.php @@ -14,42 +14,73 @@ class Emoji private ?int $id = null; #[ORM\Column(length: 255)] - private ?string $nom = null; + private ?string $name = null; #[ORM\Column(length: 255)] private ?string $code = null; #[ORM\Column] - private ?float $force = null; + private ?float $strength = null; #[ORM\Column] - private ?float $robustesse = null; + private ?float $toughness = null; #[ORM\Column] private ?float $intelligence = null; #[ORM\Column] - private ?float $vitesse = null; + private ?float $speed = null; #[ORM\Column] - private ?int $nbCombatGagne = null; + private ?int $fightsWon = null; - #[ORM\Column] - private ?int $rarete = null; + #[ORM\ManyToOne(targetEntity: Rarity::class)] + #[ORM\JoinColumn(nullable: false)] + private ?Rarity $rarity = null; + + #[ORM\ManyToOne(targetEntity: self::class)] + #[ORM\JoinColumn(nullable: true)] + private ?Emoji $parent1 = null; + + #[ORM\ManyToOne(targetEntity: self::class)] + #[ORM\JoinColumn(nullable: true)] + private ?Emoji $parent2 = null; + + public function getParent1(): ?self + { + return $this->parent1; + } + + public function setParent1(?self $parent1): self + { + $this->parent1 = $parent1; + return $this; + } + + public function getParent2(): ?self + { + return $this->parent2; + } + + public function setParent2(?self $parent2): self + { + $this->parent2 = $parent2; + return $this; + } public function getId(): ?int { return $this->id; } - public function getNom(): ?string + public function getName(): ?string { - return $this->nom; + return $this->name; } - public function setNom(string $nom): self + public function setName(string $name): self { - $this->nom = $nom; + $this->name = $name; return $this; } @@ -64,25 +95,25 @@ class Emoji return $this; } - public function getForce(): ?float + public function getStrength(): ?float { - return $this->force; + return $this->strength; } - public function setForce(float $force): self + public function setStrength(float $strength): self { - $this->force = $force; + $this->strength = $strength; return $this; } - public function getRobustesse(): ?float + public function getToughness(): ?float { - return $this->robustesse; + return $this->toughness; } - public function setRobustesse(float $robustesse): self + public function setToughness(float $toughness): self { - $this->robustesse = $robustesse; + $this->toughness = $toughness; return $this; } @@ -97,36 +128,36 @@ class Emoji return $this; } - public function getVitesse(): ?float + public function getSpeed(): ?float { - return $this->vitesse; + return $this->speed; } - public function setVitesse(float $vitesse): self + public function setSpeed(float $speed): self { - $this->vitesse = $vitesse; + $this->speed = $speed; return $this; } - public function getNbCombatGagne(): ?int + public function getFightsWon(): ?int { - return $this->nbCombatGagne; + return $this->fightsWon; } - public function setNbCombatGagne(int $nbCombatGagne): self + public function setFightsWon(int $fightsWon): self { - $this->nbCombatGagne = $nbCombatGagne; + $this->fightsWon = $fightsWon; return $this; } - public function getRarete(): ?int + public function getRarity(): ?Rarity { - return $this->rarete; + return $this->rarity; } - public function setRarete(int $rarete): self + public function setRarity(Rarity $rarity): self { - $this->rarete = $rarete; + $this->rarity = $rarity; return $this; } } diff --git a/src/Entity/Rarity.php b/src/Entity/Rarity.php new file mode 100644 index 0000000..0df259d --- /dev/null +++ b/src/Entity/Rarity.php @@ -0,0 +1,48 @@ +id; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + return $this; + } + + public function getDropRate(): float + { + return $this->dropRate; + } + + public function setDropRate(float $dropRate): self + { + $this->dropRate = $dropRate; + return $this; + } +} diff --git a/src/Repository/RarityRepository.php b/src/Repository/RarityRepository.php new file mode 100644 index 0000000..5cea1ee --- /dev/null +++ b/src/Repository/RarityRepository.php @@ -0,0 +1,48 @@ + + * + * @method Rarity|null find($id, $lockMode = null, $lockVersion = null) + * @method Rarity|null findOneBy(array $criteria, array $orderBy = null) + * @method Rarity[] findAll() + * @method Rarity[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class RarityRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Rarity::class); + } + +// /** +// * @return Rarity[] Returns an array of Rarity objects +// */ +// public function findByExampleField($value): array +// { +// return $this->createQueryBuilder('r') +// ->andWhere('r.exampleField = :val') +// ->setParameter('val', $value) +// ->orderBy('r.id', 'ASC') +// ->setMaxResults(10) +// ->getQuery() +// ->getResult() +// ; +// } + +// public function findOneBySomeField($value): ?Rarity +// { +// return $this->createQueryBuilder('r') +// ->andWhere('r.exampleField = :val') +// ->setParameter('val', $value) +// ->getQuery() +// ->getOneOrNullResult() +// ; +// } +} diff --git a/symfony.lock b/symfony.lock index 4a0d895..7c52ef7 100644 --- a/symfony.lock +++ b/symfony.lock @@ -126,18 +126,6 @@ "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" } }, - "symfony/messenger": { - "version": "6.1", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.0", - "ref": "ba1ac4e919baba5644d31b57a3284d6ba12d52ee" - }, - "files": [ - "./config/packages/messenger.yaml" - ] - }, "symfony/monolog-bundle": { "version": "3.10", "recipe": { diff --git a/templates/base.html.twig b/templates/base.html.twig index d4f83f7..5d567e4 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -3,6 +3,7 @@ {% block title %}Welcome!{% endblock %} + {# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #} {% block stylesheets %} diff --git a/templates/home/index.html.twig b/templates/home/index.html.twig new file mode 100644 index 0000000..d48c919 --- /dev/null +++ b/templates/home/index.html.twig @@ -0,0 +1,69 @@ +{% extends 'base.html.twig' %} + +{% block title %}Accueil - Ma collection de créatures{% endblock %} + +{% block stylesheets %} + +{% endblock %} + +{% block body %} + +

🧬 Ma collection de créatures 🐾

+ +
+ + + + + + + + +
+ +
Sélectionnez 2 créatures...
+ +
+ {% for emoji in emojis %} +
+ +
Level {{ emoji.nbCombatGagne }}
+
{{ emoji.code }}
+
{{ emoji.nom }}
+
ℹ️
+ + +
+ {% endfor %} +
+ +
+ +
+ + +
+{% endblock %} + +{% block javascripts %} + +{% endblock %} \ No newline at end of file