<commit_before>/*
* Requirements mandating inclusion:
* */
package model.GameActions;

import javafx.application.Platform;
import model.*;
import model.GameEvents.OnTurnEndEvent;
import model.Piles.Hand;
import model.Piles.Pile;
import view.Gameplay.GameplayViewUpdater;

import java.util.List;

public class PlaceCardAction extends GameAction {

    private Hand fromHand;
    private Pile toPile;
    private Card card;

    public PlaceCardAction() {
        this.className = "PlaceCardAction";
        this.description = "A card (or cards) is placed.";
    }

    @Override
    public void run() {
        GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ACTION, defaultGameplayMessage());
        GameplayViewUpdater.postGameplayMessage(GameplayMessageType.INSTRUCTION, "Please select " + getNumCards() + " card(s) from your hand to place in pile " + getPile().getName() + ". Then, click the PLAY button.");
        GameplayViewUpdater.postGameplayMessage(GameplayMessageType.INSTRUCTION, "The card(s) must be of suit '" + getCardSuit() + "' and of value '" + getCardValue() + "'. " +
                "If you cannot play these cards, you can click the 'Skip Action' button to proceed to a different action.");

        GameState.getInstance().getLock().lock();

        if (playerInactive() || skipAction()) {
            return;
        }

        List<Card> clickedCards = GameState.getInstance().getClickedCards();

        if (!(GameState.getInstance().getSelectedPile() instanceof Hand)) {
            GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "The selected pile is not your hand. Please click \"Show Hand\" to select cards from your hand.");
            run(); // run this action again (try again for proper inputs)
            return;
        }

        if (clickedCards.size() != getNumCards()) {
            GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "Invalid number of selected cards! Expected " + getNumCards() + " card(s) to place in " + getPile().getName() +
                    " pile. Currently, " + clickedCards.size() + " cards are selected.");
            run(); // run this action again (try again for proper inputs)
            return;
        }

        Pile currentHand = GameState.getInstance().getSelectedPile();
        if (getCardValue().equals("*Any*") && getCardSuit().equals("*Any*")) {
            for (Card c : clickedCards) {
                currentHand.remove(c);
                getPile().add(c);
            }
        }<commit_msg>Implemented support for Match Pile in PlaceCardAction<commit_after>/*
* Requirements mandating inclusion:
* */
package model.GameActions;

import javafx.application.Platform;
import model.*;
import model.GameEvents.OnTurnEndEvent;
import model.Piles.Hand;
import model.Piles.Pile;
import view.Gameplay.GameplayViewUpdater;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class PlaceCardAction extends GameAction {

    private Hand fromHand;
    private Pile toPile;
    private Card card;

    public PlaceCardAction() {
        this.className = "PlaceCardAction";
        this.description = "A card (or cards) is placed.";
    }

    @Override
    public void run() {
        GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ACTION, defaultGameplayMessage());
        GameplayViewUpdater.postGameplayMessage(GameplayMessageType.INSTRUCTION, "Please select " + getNumCards() + " card(s) from your hand to place in pile " + getPile().getName() + ". Then, click the PLAY button.");
        GameplayViewUpdater.postGameplayMessage(GameplayMessageType.INSTRUCTION, "The card(s) must be of suit '" + getCardSuit() + "' and of value '" + getCardValue() + "'. " +
                "If you cannot play these cards, you can click the 'Skip Action' button to proceed to a different action.");

        GameState.getInstance().getLock().lock();

        if (playerInactive() || skipAction()) {
            return;
        }

        List<Card> clickedCards = GameState.getInstance().getClickedCards();

        if (!(GameState.getInstance().getSelectedPile() instanceof Hand)) {
            GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "The selected pile is not your hand. Please click \"Show Hand\" to select cards from your hand.");
            run(); // run this action again (try again for proper inputs)
            return;
        }

        if (clickedCards.size() != getNumCards()) {
            GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "Invalid number of selected cards! Expected " + getNumCards() + " card(s) to place in " + getPile().getName() +
                    " pile. Currently, " + clickedCards.size() + " cards are selected.");
            run(); // run this action again (try again for proper inputs)
            return;
        }

        Pile currentHand = GameState.getInstance().getSelectedPile();
        Card topCard = getPile().getTopCard();
        String matchRequirementsStr = "Please select cards that match the requirements, or click the 'Skip Action' button if you do not have the necessary cards.";

        // Check card value and suit conditions. Check if the clicked cards match the required value/suit.
        // If there is any mismatch, post a message and re-run the action (exit).
        for (Card c : clickedCards) {
            if (getCardValue().equals("*Match Pile*") && c.getValue() != topCard.getValue()) {
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "Selected card value (" + c.getValue() +
                        ") does not match the top card value (" + topCard.getValue() + ") of pile " + getPile().getName() + ".");
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, matchRequirementsStr);
                run();
                return;
            } else if (getCardSuit().equals("*Match Pile*") && c.getSuit() != topCard.getSuit()) {
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "Selected card suit (" + c.getSuit() +
                        ") does not match the top card suit (" + topCard.getSuit() + ") of pile " + getPile().getName() + ".");
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, matchRequirementsStr);
                run();
                return;
            } else if (!getCardValue().equals("*Any*") && !getCardValue().equals("*Match Pile*") && c.getValue() != PlayingCard.valueOf(getCardValue().toUpperCase())) {
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "Selected card value (" + c.getValue() +
                        ") does not match the required value (" + getCardValue() + ").");
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, matchRequirementsStr);
                run();
                return;
            } else if (!getCardSuit().equals("*Any*") && !getCardSuit().equals("*Match Pile*") && c.getSuit() != Suit.valueOf(getCardSuit().toUpperCase())) {
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, "Selected card suit (" + c.getSuit() +
                        ") does not match the required suit (" + getCardSuit() + ").");
                GameplayViewUpdater.postGameplayMessage(GameplayMessageType.ALERT, matchRequirementsStr);
                run();
                return;
            }
        }

        // All the requirements have been met. Remove clicked cards from hand and add them to pile.
        for (Card c : clickedCards) {
            currentHand.remove(c);
            getPile().addToTop(c);
        }
{'fraction_non_alphanumeric': 0.11743262596016144, 'fraction_numerical': 0.0, 'mean_word_length': 2.7786522380718153, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2490605', 'n_tokens_mistral': 2082, 'n_tokens_neox': 2045, 'n_words': 552}