From 9ffc92f1a651fbf723eae9a8753bc1ec3d3a8e91 Mon Sep 17 00:00:00 2001 From: Benedikt Galbavy Date: Mon, 22 Jan 2024 01:12:10 +0100 Subject: [PATCH] added crits ~30 min of work --- MonsterTradingCards.sh | 18 +++++++++--------- README.md | 4 ++++ setup.sql | 1 + .../nanopenguin/mtcg/application/Battle.java | 15 +++++++++++---- .../nanopenguin/mtcg/application/Package.java | 1 + .../mtcg/application/UserCards.java | 1 + .../mtcg/application/service/schemas/Card.java | 3 ++- .../mtcg/application/BattleTest.java | 2 +- 8 files changed, 30 insertions(+), 15 deletions(-) diff --git a/MonsterTradingCards.sh b/MonsterTradingCards.sh index 7e34f17..7b554fe 100755 --- a/MonsterTradingCards.sh +++ b/MonsterTradingCards.sh @@ -47,17 +47,17 @@ read -p "Press any key to resume ..." null # -------------------------------------------------- echo "3) create packages (done by admin)" -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"845f0dc7-37d0-426e-994e-43fc3ac83c08\", \"Name\":\"WaterGoblin\", \"Damage\": 10.0}, {\"Id\":\"99f8f8dc-e25e-4a95-aa2c-782823f36e2a\", \"Name\":\"Dragon\", \"Damage\": 50.0}, {\"Id\":\"e85e3976-7c86-4d06-9a80-641c2019a79f\", \"Name\":\"WaterSpell\", \"Damage\": 20.0}, {\"Id\":\"1cb6ab86-bdb2-47e5-b6e4-68c5ab389334\", \"Name\":\"Ork\", \"Damage\": 45.0}, {\"Id\":\"dfdd758f-649c-40f9-ba3a-8657f4b3439f\", \"Name\":\"FireSpell\", \"Damage\": 25.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"845f0dc7-37d0-426e-994e-43fc3ac83c08\", \"Name\":\"WaterGoblin\", \"Damage\": 10.0, \"Crit\":30}, {\"Id\":\"99f8f8dc-e25e-4a95-aa2c-782823f36e2a\", \"Name\":\"Dragon\", \"Damage\": 50.0, \"Crit\":10}, {\"Id\":\"e85e3976-7c86-4d06-9a80-641c2019a79f\", \"Name\":\"WaterSpell\", \"Damage\": 20.0, \"Crit\":null}, {\"Id\":\"1cb6ab86-bdb2-47e5-b6e4-68c5ab389334\", \"Name\":\"Ork\", \"Damage\": 45.0, \"Crit\":0}, {\"Id\":\"dfdd758f-649c-40f9-ba3a-8657f4b3439f\", \"Name\":\"FireSpell\", \"Damage\": 25.0, \"Crit\":null}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"644808c2-f87a-4600-b313-122b02322fd5\", \"Name\":\"WaterGoblin\", \"Damage\": 9.0}, {\"Id\":\"4a2757d6-b1c3-47ac-b9a3-91deab093531\", \"Name\":\"Dragon\", \"Damage\": 55.0}, {\"Id\":\"91a6471b-1426-43f6-ad65-6fc473e16f9f\", \"Name\":\"WaterSpell\", \"Damage\": 21.0}, {\"Id\":\"4ec8b269-0dfa-4f97-809a-2c63fe2a0025\", \"Name\":\"Ork\", \"Damage\": 55.0}, {\"Id\":\"f8043c23-1534-4487-b66b-238e0c3c39b5\", \"Name\":\"WaterSpell\", \"Damage\": 23.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"644808c2-f87a-4600-b313-122b02322fd5\", \"Name\":\"WaterGoblin\", \"Damage\": 9.0, \"Crit\":15}, {\"Id\":\"4a2757d6-b1c3-47ac-b9a3-91deab093531\", \"Name\":\"Dragon\", \"Damage\": 55.0, \"Crit\":15}, {\"Id\":\"91a6471b-1426-43f6-ad65-6fc473e16f9f\", \"Name\":\"WaterSpell\", \"Damage\": 21.0, \"Crit\":null}, {\"Id\":\"4ec8b269-0dfa-4f97-809a-2c63fe2a0025\", \"Name\":\"Ork\", \"Damage\": 55.0, \"Crit\":5}, {\"Id\":\"f8043c23-1534-4487-b66b-238e0c3c39b5\", \"Name\":\"WaterSpell\", \"Damage\": 23.0, \"Crit\":null}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"b017ee50-1c14-44e2-bfd6-2c0c5653a37c\", \"Name\":\"WaterGoblin\", \"Damage\": 11.0}, {\"Id\":\"d04b736a-e874-4137-b191-638e0ff3b4e7\", \"Name\":\"Dragon\", \"Damage\": 70.0}, {\"Id\":\"88221cfe-1f84-41b9-8152-8e36c6a354de\", \"Name\":\"WaterSpell\", \"Damage\": 22.0}, {\"Id\":\"1d3f175b-c067-4359-989d-96562bfa382c\", \"Name\":\"Ork\", \"Damage\": 40.0}, {\"Id\":\"171f6076-4eb5-4a7d-b3f2-2d650cc3d237\", \"Name\":\"RegularSpell\", \"Damage\": 28.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"b017ee50-1c14-44e2-bfd6-2c0c5653a37c\", \"Name\":\"WaterGoblin\", \"Damage\": 11.0, \"Crit\":45}, {\"Id\":\"d04b736a-e874-4137-b191-638e0ff3b4e7\", \"Name\":\"Dragon\", \"Damage\": 70.0, \"Crit\":20}, {\"Id\":\"88221cfe-1f84-41b9-8152-8e36c6a354de\", \"Name\":\"WaterSpell\", \"Damage\": 22.0, \"Crit\":null}, {\"Id\":\"1d3f175b-c067-4359-989d-96562bfa382c\", \"Name\":\"Ork\", \"Damage\": 40.0, \"Crit\":0}, {\"Id\":\"171f6076-4eb5-4a7d-b3f2-2d650cc3d237\", \"Name\":\"RegularSpell\", \"Damage\": 28.0, \"Crit\":null}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"ed1dc1bc-f0aa-4a0c-8d43-1402189b33c8\", \"Name\":\"WaterGoblin\", \"Damage\": 10.0}, {\"Id\":\"65ff5f23-1e70-4b79-b3bd-f6eb679dd3b5\", \"Name\":\"Dragon\", \"Damage\": 50.0}, {\"Id\":\"55ef46c4-016c-4168-bc43-6b9b1e86414f\", \"Name\":\"WaterSpell\", \"Damage\": 20.0}, {\"Id\":\"f3fad0f2-a1af-45df-b80d-2e48825773d9\", \"Name\":\"Ork\", \"Damage\": 45.0}, {\"Id\":\"8c20639d-6400-4534-bd0f-ae563f11f57a\", \"Name\":\"WaterSpell\", \"Damage\": 25.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"ed1dc1bc-f0aa-4a0c-8d43-1402189b33c8\", \"Name\":\"WaterGoblin\", \"Damage\": 10.0, \"Crit\":30}, {\"Id\":\"65ff5f23-1e70-4b79-b3bd-f6eb679dd3b5\", \"Name\":\"Dragon\", \"Damage\": 50.0, \"Crit\":20}, {\"Id\":\"55ef46c4-016c-4168-bc43-6b9b1e86414f\", \"Name\":\"WaterSpell\", \"Damage\": 20.0, \"Crit\":null}, {\"Id\":\"f3fad0f2-a1af-45df-b80d-2e48825773d9\", \"Name\":\"Ork\", \"Damage\": 45.0, \"Crit\":10}, {\"Id\":\"8c20639d-6400-4534-bd0f-ae563f11f57a\", \"Name\":\"WaterSpell\", \"Damage\": 25.0, \"Crit\":null}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"d7d0cb94-2cbf-4f97-8ccf-9933dc5354b8\", \"Name\":\"WaterGoblin\", \"Damage\": 9.0}, {\"Id\":\"44c82fbc-ef6d-44ab-8c7a-9fb19a0e7c6e\", \"Name\":\"Dragon\", \"Damage\": 55.0}, {\"Id\":\"2c98cd06-518b-464c-b911-8d787216cddd\", \"Name\":\"WaterSpell\", \"Damage\": 21.0}, {\"Id\":\"951e886a-0fbf-425d-8df5-af2ee4830d85\", \"Name\":\"Ork\", \"Damage\": 55.0}, {\"Id\":\"dcd93250-25a7-4dca-85da-cad2789f7198\", \"Name\":\"FireSpell\", \"Damage\": 23.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"d7d0cb94-2cbf-4f97-8ccf-9933dc5354b8\", \"Name\":\"WaterGoblin\", \"Damage\": 9.0, \"Crit\":30}, {\"Id\":\"44c82fbc-ef6d-44ab-8c7a-9fb19a0e7c6e\", \"Name\":\"Dragon\", \"Damage\": 55.0, \"Crit\":10}, {\"Id\":\"2c98cd06-518b-464c-b911-8d787216cddd\", \"Name\":\"WaterSpell\", \"Damage\": 21.0, \"Crit\":null}, {\"Id\":\"951e886a-0fbf-425d-8df5-af2ee4830d85\", \"Name\":\"Ork\", \"Damage\": 55.0, \"Crit\":15}, {\"Id\":\"dcd93250-25a7-4dca-85da-cad2789f7198\", \"Name\":\"FireSpell\", \"Damage\": 23.0, \"Crit\":null}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"b2237eca-0271-43bd-87f6-b22f70d42ca4\", \"Name\":\"WaterGoblin\", \"Damage\": 11.0}, {\"Id\":\"9e8238a4-8a7a-487f-9f7d-a8c97899eb48\", \"Name\":\"Dragon\", \"Damage\": 70.0}, {\"Id\":\"d60e23cf-2238-4d49-844f-c7589ee5342e\", \"Name\":\"WaterSpell\", \"Damage\": 22.0}, {\"Id\":\"fc305a7a-36f7-4d30-ad27-462ca0445649\", \"Name\":\"Ork\", \"Damage\": 40.0}, {\"Id\":\"84d276ee-21ec-4171-a509-c1b88162831c\", \"Name\":\"RegularSpell\", \"Damage\": 28.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"b2237eca-0271-43bd-87f6-b22f70d42ca4\", \"Name\":\"WaterGoblin\", \"Damage\": 11.0, \"Crit\":20}, {\"Id\":\"9e8238a4-8a7a-487f-9f7d-a8c97899eb48\", \"Name\":\"Dragon\", \"Damage\": 70.0, \"Crit\":5}, {\"Id\":\"d60e23cf-2238-4d49-844f-c7589ee5342e\", \"Name\":\"WaterSpell\", \"Damage\": 22.0, \"Crit\":null}, {\"Id\":\"fc305a7a-36f7-4d30-ad27-462ca0445649\", \"Name\":\"Ork\", \"Damage\": 40.0, \"Crit\":10}, {\"Id\":\"84d276ee-21ec-4171-a509-c1b88162831c\", \"Name\":\"RegularSpell\", \"Damage\": 28.0, \"Crit\":null}]" echo . echo . @@ -95,11 +95,11 @@ read -p "Press any key to resume ..." null # -------------------------------------------------- echo "6) add new packages" -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"67f9048f-99b8-4ae4-b866-d8008d00c53d\", \"Name\":\"WaterGoblin\", \"Damage\": 10.0}, {\"Id\":\"aa9999a0-734c-49c6-8f4a-651864b14e62\", \"Name\":\"RegularSpell\", \"Damage\": 50.0}, {\"Id\":\"d6e9c720-9b5a-40c7-a6b2-bc34752e3463\", \"Name\":\"Knight\", \"Damage\": 20.0}, {\"Id\":\"02a9c76e-b17d-427f-9240-2dd49b0d3bfd\", \"Name\":\"RegularSpell\", \"Damage\": 45.0}, {\"Id\":\"2508bf5c-20d7-43b4-8c77-bc677decadef\", \"Name\":\"FireElf\", \"Damage\": 25.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"67f9048f-99b8-4ae4-b866-d8008d00c53d\", \"Name\":\"WaterGoblin\", \"Damage\": 10.0, \"Crit\":50}, {\"Id\":\"aa9999a0-734c-49c6-8f4a-651864b14e62\", \"Name\":\"RegularSpell\", \"Damage\": 50.0, \"Crit\":null}, {\"Id\":\"d6e9c720-9b5a-40c7-a6b2-bc34752e3463\", \"Name\":\"Knight\", \"Damage\": 20.0}, {\"Id\":\"02a9c76e-b17d-427f-9240-2dd49b0d3bfd\", \"Name\":\"RegularSpell\", \"Damage\": 45.0, \"Crit\":null}, {\"Id\":\"2508bf5c-20d7-43b4-8c77-bc677decadef\", \"Name\":\"FireElf\", \"Damage\": 25.0, \"Crit\":70}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"70962948-2bf7-44a9-9ded-8c68eeac7793\", \"Name\":\"WaterGoblin\", \"Damage\": 9.0}, {\"Id\":\"74635fae-8ad3-4295-9139-320ab89c2844\", \"Name\":\"FireSpell\", \"Damage\": 55.0}, {\"Id\":\"ce6bcaee-47e1-4011-a49e-5a4d7d4245f3\", \"Name\":\"Knight\", \"Damage\": 21.0}, {\"Id\":\"a6fde738-c65a-4b10-b400-6fef0fdb28ba\", \"Name\":\"FireSpell\", \"Damage\": 55.0}, {\"Id\":\"a1618f1e-4f4c-4e09-9647-87e16f1edd2d\", \"Name\":\"FireElf\", \"Damage\": 23.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"70962948-2bf7-44a9-9ded-8c68eeac7793\", \"Name\":\"WaterGoblin\", \"Damage\": 9.0, \"Crit\":30}, {\"Id\":\"74635fae-8ad3-4295-9139-320ab89c2844\", \"Name\":\"FireSpell\", \"Damage\": 55.0, \"Crit\":null}, {\"Id\":\"ce6bcaee-47e1-4011-a49e-5a4d7d4245f3\", \"Name\":\"Knight\", \"Damage\": 21.0}, {\"Id\":\"a6fde738-c65a-4b10-b400-6fef0fdb28ba\", \"Name\":\"FireSpell\", \"Damage\": 55.0, \"Crit\":null}, {\"Id\":\"a1618f1e-4f4c-4e09-9647-87e16f1edd2d\", \"Name\":\"FireElf\", \"Damage\": 23.0, \"Crit\":60}]" echo . -curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"2272ba48-6662-404d-a9a1-41a9bed316d9\", \"Name\":\"WaterGoblin\", \"Damage\": 11.0}, {\"Id\":\"3871d45b-b630-4a0d-8bc6-a5fc56b6a043\", \"Name\":\"Dragon\", \"Damage\": 70.0}, {\"Id\":\"166c1fd5-4dcb-41a8-91cb-f45dcd57cef3\", \"Name\":\"Knight\", \"Damage\": 22.0}, {\"Id\":\"237dbaef-49e3-4c23-b64b-abf5c087b276\", \"Name\":\"WaterSpell\", \"Damage\": 40.0}, {\"Id\":\"27051a20-8580-43ff-a473-e986b52f297a\", \"Name\":\"FireElf\", \"Damage\": 28.0}]" +curl -i -X POST http://localhost:10001/packages --header "Content-Type: application/json" --header "Authorization: Bearer $token3" -d "[{\"Id\":\"2272ba48-6662-404d-a9a1-41a9bed316d9\", \"Name\":\"WaterGoblin\", \"Damage\": 11.0, \"Crit\":30}, {\"Id\":\"3871d45b-b630-4a0d-8bc6-a5fc56b6a043\", \"Name\":\"Dragon\", \"Damage\": 70.0, \"Crit\":20}, {\"Id\":\"166c1fd5-4dcb-41a8-91cb-f45dcd57cef3\", \"Name\":\"Knight\", \"Damage\": 22.0}, {\"Id\":\"237dbaef-49e3-4c23-b64b-abf5c087b276\", \"Name\":\"WaterSpell\", \"Damage\": 40.0, \"Crit\":null}, {\"Id\":\"27051a20-8580-43ff-a473-e986b52f297a\", \"Name\":\"FireElf\", \"Damage\": 28.0, \"Crit\":55}]" echo . echo . diff --git a/README.md b/README.md index 3e10d35..1ca1669 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,10 @@ There are two parts of the project which are tested through unit tests: the rout - Starting with the HTTP server made it quite easy testing the application with integration tests (manual using postman or automated using the provided curl script). - A separate db helper class would probably make sense for larger, more complex projects, but was overkill here. +## Unique feature + +My unique feature is the ability to crit: Whenever two monsters fight (i.e. no spells involved), they can critically strike for an increase in damage of 50%. Each card has a crit modifier, default to 0. + ## Further notes The curl script was modified to automatically store the authentication tokens in variables. diff --git a/setup.sql b/setup.sql index c62d237..df6c031 100644 --- a/setup.sql +++ b/setup.sql @@ -56,6 +56,7 @@ SET default_table_access_method = heap; CREATE TABLE public.cards ( uuid uuid DEFAULT gen_random_uuid() NOT NULL, damage double precision DEFAULT 0 NOT NULL, + crit integer DEFAULT 0, owner uuid, deck boolean DEFAULT false NOT NULL, trade boolean DEFAULT false NOT NULL, diff --git a/src/main/java/at/nanopenguin/mtcg/application/Battle.java b/src/main/java/at/nanopenguin/mtcg/application/Battle.java index bc6604f..861bbad 100644 --- a/src/main/java/at/nanopenguin/mtcg/application/Battle.java +++ b/src/main/java/at/nanopenguin/mtcg/application/Battle.java @@ -8,6 +8,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Random; public class Battle { @@ -57,7 +58,8 @@ public class Battle { this.combatants.left().getAndRemoveCard()), new FightDTO( this.combatants.right(), - this.combatants.right().getAndRemoveCard())); + this.combatants.right().getAndRemoveCard()), + true); this.log.add(this.createCombatString(round, result)); @@ -130,17 +132,22 @@ public class Battle { return returnMods; } - static RoundResult fight(FightDTO left, FightDTO right) { + static RoundResult fight(FightDTO left, FightDTO right, boolean allowCrit) { if (isImmune(left.card(), right.card())) return new RoundResult(left, right, false, ElementMod.NONE, ElementMod.NONE); if (isImmune(right.card(), left.card())) return new RoundResult(right, left, false, ElementMod.NONE, ElementMod.NONE); Pair dmgMods = getElementMod(left.card(), right.card()); - boolean leftWins = left.card().damage()*dmgMods.left().percentMod >= right.card().damage()*dmgMods.right().percentMod; + allowCrit = allowCrit && left.card().crit() != null && right.card().crit() != null; + + double leftCrit = allowCrit && new Random().nextInt() % 100 < left.card().crit() ? 1.5 : 1; + double rightCrit = allowCrit && new Random().nextInt() % 100 < right.card().crit() ? 1.5 : 1; + + boolean leftWins = left.card().damage() * dmgMods.left().percentMod * leftCrit >= right.card().damage() * dmgMods.right().percentMod * rightCrit; return new RoundResult( leftWins ? left : right, leftWins ? right : left, - left.card().damage()*dmgMods.left().percentMod == right.card().damage()*dmgMods.right().percentMod, + left.card().damage() * dmgMods.left().percentMod * leftCrit == right.card().damage() * dmgMods.right().percentMod * rightCrit, leftWins ? dmgMods.left() : dmgMods.right(), leftWins ? dmgMods.right() : dmgMods.left()); } diff --git a/src/main/java/at/nanopenguin/mtcg/application/Package.java b/src/main/java/at/nanopenguin/mtcg/application/Package.java index 8cc4dd5..cfa0a64 100644 --- a/src/main/java/at/nanopenguin/mtcg/application/Package.java +++ b/src/main/java/at/nanopenguin/mtcg/application/Package.java @@ -34,6 +34,7 @@ public class Package { .table(Table.CARDS); if (card.id() != null) query.parameter("uuid", card.id()); if (query.parameter("damage", card.damage()) + .parameter("crit", card.crit()) .parameter("name", card.name()) .parameter("package", packageUuid) .executeUpdate() != 1){ diff --git a/src/main/java/at/nanopenguin/mtcg/application/UserCards.java b/src/main/java/at/nanopenguin/mtcg/application/UserCards.java index fd302a7..59747b4 100644 --- a/src/main/java/at/nanopenguin/mtcg/application/UserCards.java +++ b/src/main/java/at/nanopenguin/mtcg/application/UserCards.java @@ -20,6 +20,7 @@ public class UserCards extends User { .column("uuid AS id") .column("name") .column("damage") + .column("crit") .condition("owner", userUuid); if (deckOnly) dbQueryBuilder.condition("deck", true); ArrayList cards = new ArrayList<>(); diff --git a/src/main/java/at/nanopenguin/mtcg/application/service/schemas/Card.java b/src/main/java/at/nanopenguin/mtcg/application/service/schemas/Card.java index 528b4e4..9039ed0 100644 --- a/src/main/java/at/nanopenguin/mtcg/application/service/schemas/Card.java +++ b/src/main/java/at/nanopenguin/mtcg/application/service/schemas/Card.java @@ -10,5 +10,6 @@ import java.util.UUID; public record Card( UUID id, String name, - Float damage) { + Float damage, + Integer crit) { } diff --git a/src/test/java/at/nanopenguin/mtcg/application/BattleTest.java b/src/test/java/at/nanopenguin/mtcg/application/BattleTest.java index 72cf13c..f510e79 100644 --- a/src/test/java/at/nanopenguin/mtcg/application/BattleTest.java +++ b/src/test/java/at/nanopenguin/mtcg/application/BattleTest.java @@ -93,7 +93,7 @@ public class BattleTest { Battle.FightDTO fightDTO1 = getFightDTO(card1, dmg1); Battle.FightDTO fightDTO2 = getFightDTO(card2, dmg2); - Battle.RoundResult result = Battle.fight(fightDTO1, fightDTO2); + Battle.RoundResult result = Battle.fight(fightDTO1, fightDTO2, false); switch (outcome) { case LEFT_WINS -> {