From d3fad196e1b6eb8e3fcc057c06f0803a2bebf40e Mon Sep 17 00:00:00 2001 From: Micah Stairs Date: Sun, 8 Sep 2024 15:38:01 -0400 Subject: [PATCH] Continue migrating base cards --- innovation.game.php | 257 +----------------- modules/Innovation/Cards/AbstractCard.php | 5 + modules/Innovation/Cards/Base/Card74_3E.php | 31 +++ modules/Innovation/Cards/Base/Card74_4E.php | 34 +++ modules/Innovation/Cards/Base/Card75.php | 32 +++ modules/Innovation/Cards/Base/Card76.php | 31 ++- modules/Innovation/Cards/Base/Card77.php | 37 +++ modules/Innovation/Cards/Base/Card78.php | 14 +- modules/Innovation/Cards/Base/Card79.php | 10 +- modules/Innovation/Cards/Base/Card80.php | 48 ++++ modules/Innovation/Cards/Base/Card81.php | 53 ++++ modules/Innovation/Cards/Base/Card82.php | 16 +- .../Innovation/Cards/InteractionBuilder.php | 28 ++ 13 files changed, 292 insertions(+), 304 deletions(-) create mode 100644 modules/Innovation/Cards/Base/Card74_3E.php create mode 100644 modules/Innovation/Cards/Base/Card74_4E.php create mode 100644 modules/Innovation/Cards/Base/Card75.php create mode 100644 modules/Innovation/Cards/Base/Card77.php create mode 100644 modules/Innovation/Cards/Base/Card80.php create mode 100644 modules/Innovation/Cards/Base/Card81.php diff --git a/innovation.game.php b/innovation.game.php index 7b1b7900..ea251703 100644 --- a/innovation.game.php +++ b/innovation.game.php @@ -9882,12 +9882,6 @@ function argSelectionMove() switch ($code) { - // id 80, age 8: Mass media - case "80N1B": - $message_for_player = clienttranslate('Choose a value'); - $message_for_others = clienttranslate('${player_name} must choose a value'); - break; - // id 83, age 8: Empiricism case "83N1A": $message_for_player = clienttranslate('${You} must choose two colors'); @@ -10812,10 +10806,7 @@ function isInSeparateFile($card_id) if ($card['type'] == CardTypes::CITIES) { return false; } - return $card_id <= 73 - || $card_id == 76 - || (78 <= $card_id && $card_id <= 79) - || $card_id == 82 + return $card_id <= 82 || (87 <= $card_id && $card_id <= 88) || $card_id == 92 || $card_id == 93 @@ -10941,63 +10932,11 @@ function stPlayerInvolvedTurn() // Setting the $step_max variable means there is interaction needed with the player - // id 74, age 7: Railroad - case "74N1_3E": - case "74N1_4E": - $step_max = 1; - break; - - case "74N2_3E": - $step_max = 1; - break; - - case "74N2_4E": - // "Draw three 6" - self::executeDraw($player_id, 6); - self::executeDraw($player_id, 6); - self::executeDraw($player_id, 6); - break; - - case "74N3_4E": - $step_max = 1; - break; - - // id 75, age 8: Quantum theory - case "75N1": - $step_max = 1; - break; - // id 76, age 8: Rocketry case "76N1": $step_max = 1; break; - // id 77, age 8: Flight - case "77N1": - if (self::getCurrentSplayDirection($player_id, Colors::RED) == 3 /* up */) { // "If your red cards are splayed up" - $step_max = 1; - } - break; - - case "77N2": - $step_max = 1; - break; - - // id 80, age 8: Mass media - case "80N1": - $step_max = 1; - break; - - case "80N2": - $step_max = 1; - break; - - // id 81, age 8: Antibiotics - case "81N1": - self::setAuxiliaryValueFromArray(array()); // Flag to indicate what ages have been returned - $step_max = 1; - break; - // id 83, age 8: Empiricism case "83N1": $step_max = 1; @@ -11506,147 +11445,6 @@ function stInteractionStep() // Setting the $step_max variable means there is interaction needed with the player - // id 74, age 7: Railroad - case "74N1A_3E": - case "74N1A_4E": - // "Return all the cards in your hand" - $options = array( - 'player_id' => $player_id, - - 'owner_from' => $player_id, - 'location_from' => 'hand', - 'owner_to' => 0, - 'location_to' => 'deck', - ); - break; - - case "74N2A_3E": - case "74N3A_4E": - $splayed_right_colors = array(); - foreach (Colors::ALL as $color) { - if (self::getCurrentSplayDirection($player_id, $color) == Directions::RIGHT) { - $splayed_right_colors[] = $color; - } - } - // "You may splay up any one color of your cards currently splayed right" - $options = array( - 'player_id' => $player_id, - 'n' => 1, - 'can_pass' => true, - - 'splay_direction' => 3 /* up */ , - 'color' => $splayed_right_colors - ); - break; - - // id 75, age 8: Quantum theory - case "75N1A": - // "You may return up to two cards from your hand" - $options = array( - 'player_id' => $player_id, - 'n_min' => 1, - 'n_max' => 2, - 'can_pass' => true, - - 'owner_from' => $player_id, - 'location_from' => 'hand', - 'owner_to' => 0, - 'location_to' => 'deck', - ); - break; - - // id 77, age 8: Flight - case "77N1A": - // "You may splay any one color of your cards up" - $options = array( - 'player_id' => $player_id, - 'n' => 1, - 'can_pass' => true, - - 'splay_direction' => 3 /* up */ - ); - break; - - case "77N2A": - // "You may splay your red cards up" - $options = array( - 'player_id' => $player_id, - 'n' => 1, - 'can_pass' => true, - - 'splay_direction' => 3, - /* up */ - 'color' => array(1) /* red */ - ); - break; - - // id 80, age 8: Mass media - case "80N1A": - // "You may return a card from your hand" - $options = array( - 'player_id' => $player_id, - 'n' => 1, - 'can_pass' => true, - - 'owner_from' => $player_id, - 'location_from' => 'hand', - 'owner_to' => 0, - 'location_to' => 'deck' - ); - break; - - case "80N1B": - // "Choose a value" - $options = array( - 'player_id' => $player_id, - - 'choose_value' => true - ); - break; - - case "80N1C": - // "Return all cards of that value from all score piles" - $options = array( - 'player_id' => $player_id, - - 'owner_from' => 'any player', - 'location_from' => 'score', - 'owner_to' => 0, - 'location_to' => 'deck', - - 'age' => self::getAuxiliaryValue() - ); - break; - - case "80N2A": - // "You may splay your purple cards up" - $options = array( - 'player_id' => $player_id, - 'n' => 1, - 'can_pass' => true, - - 'splay_direction' => 3, - /* up */ - 'color' => array(4) /* purple */ - ); - break; - - // id 81, age 8: Antibiotics - case "81N1A": - // "You may return up to three cards from your hand" - $options = array( - 'player_id' => $player_id, - 'n_min' => 1, - 'n_max' => 3, - 'can_pass' => true, - - 'owner_from' => $player_id, - 'location_from' => 'hand', - 'owner_to' => 0, - 'location_to' => 'deck' - ); - break; - // id 83, age 8: Empiricism case "83N1A": // "Choose two colors" @@ -12220,52 +12018,6 @@ function stInterInteractionStep() // The letter indicates the step : A for the first one, B for the second - // id 74, age 7: Railroad - case "74N1A_3E": - // "Draw three 6" - self::executeDraw($player_id, 6); - self::executeDraw($player_id, 6); - self::executeDraw($player_id, 6); - break; - - // id 75, age 8: Quantum theory - case "75N1A": - if ($n == 2) { // "If you return two" - self::executeDraw($player_id, 10); // "Draw a 10" - self::executeDraw($player_id, 10, 'score'); // "Draw and score a 10" - } - break; - - // id 80, age 8: Mass media - case "80N1A": - if ($n > 0) { // "If you do - self::incrementStepMax(2); - } - break; - - // id 81, age 8: Antibiotics - case "81N1A": - if ($n > 0) { // If you do (implicit) - $different_values_selected_so_far = self::getAuxiliaryValueAsArray(); - $number_of_cards_to_draw = count($different_values_selected_so_far); - - if ($number_of_cards_to_draw == 1) { - self::notifyPlayer($player_id, 'log', clienttranslate('Each card ${you} returned has the same value.'), array('you' => 'you')); - self::notifyAllPlayersBut($player_id, 'log', clienttranslate('Each card ${player_name} returned has the same value.'), array('player_name' => self::renderPlayerName($player_id))); - } else if ($number_of_cards_to_draw > 1) { - $n = self::renderNumber($number_of_cards_to_draw); - self::notifyPlayer($player_id, 'log', clienttranslate('${You} returned cards of ${n} different values.'), array('i18n' => array('n'), 'You' => 'You', 'n' => $n)); - self::notifyAllPlayersBut($player_id, 'log', clienttranslate('There are ${n} different values that can be found in the cards ${player_name} returned.'), array('i18n' => array('n'), 'player_name' => self::renderPlayerName($player_id), 'n' => $n)); - } - - // "For every different value of card that you returned" - for ($i = 0; $i < $number_of_cards_to_draw; $i++) { - self::executeDraw($player_id, 8); // "Draw two 8" - self::executeDraw($player_id, 8); // - } - } - break; - // id 84, age 8: Socialism case "84N1A_3E": if ($n > 0) { @@ -12959,13 +12711,6 @@ function stInterSelectionMove() // Default behaviour: make the transfer or the splay as stated in B - // id 80, age 8, Mass media - case "80N1B": - self::notifyPlayer($player_id, 'log', clienttranslate('${You} choose the value ${age}.'), array('You' => 'You', 'age' => self::getAgeSquare($choice))); - self::notifyAllPlayersBut($player_id, 'log', clienttranslate('${player_name} chooses the value ${age}.'), array('player_name' => self::renderPlayerName($player_id), 'age' => self::getAgeSquare($choice))); - self::setAuxiliaryValue($choice); - break; - // id 81, age 8: Antibiotics case "81N1A": $different_values_selected_so_far = self::getAuxiliaryValueAsArray(); diff --git a/modules/Innovation/Cards/AbstractCard.php b/modules/Innovation/Cards/AbstractCard.php index 68ea44fb..ee3d7ad5 100644 --- a/modules/Innovation/Cards/AbstractCard.php +++ b/modules/Innovation/Cards/AbstractCard.php @@ -1032,6 +1032,11 @@ protected function isSplayed(int $color, int $playerId = null): int return self::getSplayDirection($color, self::coercePlayerId($playerId)) > 0; } + protected function isSplayedUp(int $color, int $playerId = null): int + { + return self::getSplayDirection($color, self::coercePlayerId($playerId)) === Directions::UP; + } + // SELECTION HELPERS protected function getLastSelectedCard(): ?array diff --git a/modules/Innovation/Cards/Base/Card74_3E.php b/modules/Innovation/Cards/Base/Card74_3E.php new file mode 100644 index 00000000..a9bd64c9 --- /dev/null +++ b/modules/Innovation/Cards/Base/Card74_3E.php @@ -0,0 +1,31 @@ +return()->all()->fromYourHand()->build(); + } else { + return self::youMay()->splayUp()->currentlySplayedRight()->build(); + } + } + + public function afterInteraction() + { + if (self::isFirstNonDemand()) { + self::draw(6); + self::draw(6); + self::draw(6); + } + } + +} \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card74_4E.php b/modules/Innovation/Cards/Base/Card74_4E.php new file mode 100644 index 00000000..d0188f98 --- /dev/null +++ b/modules/Innovation/Cards/Base/Card74_4E.php @@ -0,0 +1,34 @@ +return()->all()->fromYourHand()->build(); + } else { + return self::youMay()->splayUp()->currentlySplayedRight()->build(); + } + } + +} \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card75.php b/modules/Innovation/Cards/Base/Card75.php new file mode 100644 index 00000000..c1bc6a66 --- /dev/null +++ b/modules/Innovation/Cards/Base/Card75.php @@ -0,0 +1,32 @@ +return()->minCards(1)->maxCards(2)->fromYourHand()->build(); + } + + public function afterInteraction() + { + if (self::getNumChosen() == 2) { + self::draw(10); + self::drawAndScore(10); + } + } + + public function nonDemandsMightBeEffective(): bool + { + return self::hasCards(Locations::HAND); + } + +} \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card76.php b/modules/Innovation/Cards/Base/Card76.php index 10dc0b61..d639f389 100644 --- a/modules/Innovation/Cards/Base/Card76.php +++ b/modules/Innovation/Cards/Base/Card76.php @@ -18,20 +18,27 @@ class Card76 extends AbstractCard public function getInteractionOptions(): array { if (self::isFirstOrThirdEdition()) { - return [ - 'owner_from' => 'any opponent', - 'location_from' => Locations::SCORE, - 'return_keyword' => true, - 'n' => $this->game->intDivision(self::getStandardIconCount(Icons::EFFICIENCY), 2), - ]; + $numCards = $this->game->intDivision(self::getStandardIconCount(Icons::EFFICIENCY), 2); } else { - return [ - 'owner_from' => 'any opponent', - 'location_from' => Locations::SCORE, - 'return_keyword' => true, - 'n' => self::countColorsWithIcon(Icons::EFFICIENCY), - ]; + $numCards = self::countColorsWithIcon(Icons::EFFICIENCY); } + return self::youMust()->return()->exactly($numCards)->fromOpponentsScore()->build(); + } + + public function nonDemandsMightBeEffective(): bool + { + if (self::isFirstOrThirdEdition() && self::getStandardIconCount(Icons::EFFICIENCY) < 2) { + return false; + } + if (self::isFourthEdition() && self::countColorsWithIcon(Icons::EFFICIENCY) == 0) { + return false; + } + foreach (self::getOpponentIds() as $opponentId) { + if (self::hasCards(Locations::SCORE, $opponentId)) { + return true; + } + } + return false; } } \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card77.php b/modules/Innovation/Cards/Base/Card77.php new file mode 100644 index 00000000..80572c12 --- /dev/null +++ b/modules/Innovation/Cards/Base/Card77.php @@ -0,0 +1,37 @@ +splayUp()->build(); + } else { + return self::youMay()->splayUp()->withColor(Colors::RED)->build(); + } + } + + public function nonDemandsMightBeEffective(): bool + { + return self::canSplayRight(Colors::RED) || (self::isSplayedUp(Colors::RED) && self::canSplayRight(Colors::NON_RED)); + } + +} \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card78.php b/modules/Innovation/Cards/Base/Card78.php index d97bb824..bbb2501f 100644 --- a/modules/Innovation/Cards/Base/Card78.php +++ b/modules/Innovation/Cards/Base/Card78.php @@ -5,8 +5,6 @@ use Innovation\Cards\AbstractCard; use Innovation\Enums\Colors; use Innovation\Enums\Icons; -use Innovation\Enums\Locations; -use Innovation\Enums\ValueSelectors; class Card78 extends AbstractCard { @@ -20,17 +18,7 @@ class Card78 extends AbstractCard public function getInteractionOptions(): array { - return [ - 'n' => 2, - 'owner_from' => self::getPlayerId(), - 'location_from' => Locations::BOARD, - 'owner_to' => self::getLauncherId(), - 'location_to' => Locations::SCORE, - 'color' => Colors::NON_RED, - 'without_icon' => Icons::INDUSTRY, - 'age' => ValueSelectors::HIGHEST, - 'refresh_selection' => true, - ]; + return self::youMust()->exactly(2)->highest()->non(Colors::RED)->withoutIcon(Icons::INDUSTRY)->fromYourBoard()->toMyScore()->refreshingSelection()->build(); } public function afterInteraction() diff --git a/modules/Innovation/Cards/Base/Card79.php b/modules/Innovation/Cards/Base/Card79.php index fef2d18f..9d6b8293 100644 --- a/modules/Innovation/Cards/Base/Card79.php +++ b/modules/Innovation/Cards/Base/Card79.php @@ -5,7 +5,6 @@ use Innovation\Cards\AbstractCard; use Innovation\Enums\Colors; use Innovation\Enums\Icons; -use Innovation\Enums\Locations; class Card79 extends AbstractCard { @@ -30,14 +29,7 @@ public function initialExecution() public function getInteractionOptions(): array { - return [ - 'color' => Colors::NON_GREEN, - 'with_icon' => Icons::INDUSTRY, - 'owner_from' => self::getPlayerId(), - 'location_from' => Locations::BOARD, - 'owner_to' => self::getLauncherId(), - 'location_to' => Locations::SCORE, - ]; + return self::youMust()->non(Colors::GREEN)->withIcon(Icons::INDUSTRY)->fromYourBoard()->toMyScore()->build(); } public function handleCardChoice(array $card) diff --git a/modules/Innovation/Cards/Base/Card80.php b/modules/Innovation/Cards/Base/Card80.php new file mode 100644 index 00000000..08ab7449 --- /dev/null +++ b/modules/Innovation/Cards/Base/Card80.php @@ -0,0 +1,48 @@ +return()->fromYourHand()->build(); + } else if (self::isSecondInteraction()) { + return self::youMay()->chooseValue()->build(); + } else { + return self::youMay()->return()->all()->value(self::getAuxiliaryValue())->fromAnyScore()->build(); + } + } else { + return self::youMay()->splayUp()->withColor(Colors::PURPLE)->build(); + } + } + + public function handleCardChoice(array $card) + { + if (self::isFirstNonDemand() && self::isFirstInteraction()) { + self::setMaxSteps(3); + } + } + + public function handleValueChoice(int $value) + { + self::setAuxiliaryValue($value); // Remember which value was chosen + } + + public function nonDemandsMightBeEffective(): bool + { + return self::hasCards(Locations::HAND) || self::canSplayUp(Colors::PURPLE); + } + +} \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card81.php b/modules/Innovation/Cards/Base/Card81.php new file mode 100644 index 00000000..f6f432d1 --- /dev/null +++ b/modules/Innovation/Cards/Base/Card81.php @@ -0,0 +1,53 @@ +return()->minCards(1)->maxCards(3)->fromYourHand()->build(); + } + + public function handleCardChoice(array $card) + { + $value = self::getValue($card); + $values = Arrays::decode(self::getAuxiliaryValue()); + if (!in_array($value, $values)) { + $values[] = $value; + } + self::setAuxiliaryValue(Arrays::encode($values)); + } + + public function afterInteraction() + { + $values = Arrays::decode(self::getAuxiliaryValue()); + for ($i = 0; $i < count($values); $i++) { + self::draw(8); + self::draw(8); + } + } + + public function nonDemandsMightBeEffective(): bool + { + return self::hasCards(Locations::HAND); + } + +} \ No newline at end of file diff --git a/modules/Innovation/Cards/Base/Card82.php b/modules/Innovation/Cards/Base/Card82.php index f74aa3c2..d6646bf1 100644 --- a/modules/Innovation/Cards/Base/Card82.php +++ b/modules/Innovation/Cards/Base/Card82.php @@ -6,7 +6,6 @@ use Innovation\Enums\CardIds; use Innovation\Enums\Colors; use Innovation\Enums\Icons; -use Innovation\Enums\Locations; class Card82 extends AbstractCard { @@ -22,20 +21,9 @@ class Card82 extends AbstractCard public function getInteractionOptions(): array { if (self::isFirstInteraction()) { - return [ - 'color' => Colors::NON_YELLOW, - 'with_icon' => Icons::EFFICIENCY, - 'owner_from' => self::getPlayerId(), - 'owner_to' => self::getLauncherId(), - 'location' => Locations::BOARD, - ]; + return self::youMust()->non(Colors::YELLOW)->withIcon(Icons::EFFICIENCY)->fromYourBoard()->toMine()->build(); } else { - return [ - 'return_keyword' => true, - 'n' => 'all', - 'color' => [self::getAuxiliaryValue()], - 'location_from' => Locations::PILE, - ]; + return self::youMust()->return()->all()->yourStack(self::getAuxiliaryValue())->build(); } } diff --git a/modules/Innovation/Cards/InteractionBuilder.php b/modules/Innovation/Cards/InteractionBuilder.php index ecef6a3e..2adbcd44 100644 --- a/modules/Innovation/Cards/InteractionBuilder.php +++ b/modules/Innovation/Cards/InteractionBuilder.php @@ -140,6 +140,12 @@ function non(int $color): InteractionBuilder return $this; } + function currentlySplayedRight(): InteractionBuilder + { + $this->interactionOptions['has_splay_direction'] = [Directions::RIGHT]; + return $this; + } + // DIRECTION OF SPLAY function splayLeft(): InteractionBuilder @@ -174,6 +180,14 @@ function fromAvailableAchievements(): InteractionBuilder return $this; } + function yourStack(int $color): InteractionBuilder + { + $this->interactionOptions['location_from'] = Locations::PILE; + $this->interactionOptions['owner_from'] = $this->state->getPlayerId(); + $this->interactionOptions['color'] = $color; + return $this; + } + function fromYourBoard(): InteractionBuilder { $this->interactionOptions['location_from'] = Locations::BOARD; @@ -216,6 +230,20 @@ function fromMyScore(): InteractionBuilder return $this; } + function fromOpponentsScore(): InteractionBuilder + { + $this->interactionOptions['location_from'] = Locations::SCORE; + $this->interactionOptions['owner_from'] = 'any opponent'; + return $this; + } + + function fromAnyScore(): InteractionBuilder + { + $this->interactionOptions['location_from'] = Locations::SCORE; + $this->interactionOptions['owner_from'] = 'any player'; + return $this; + } + function fromYourHandOrRevealed(): InteractionBuilder { $this->interactionOptions['location_from'] = 'revealed,hand';