예제 #1
0
 /// <summary>
 /// More aggressive form of orientation, this is effectively a full reset on cards within the deck.
 /// </summary>
 /// <param name="animated"></param>
 public void EnforceCardLocationAndOrientation(bool animated, StateMachineSystem.StateMachine targetMachine)
 {
     basePosition.z = 0;
     AssertOrdering();
     if (animated)
     {
         for (int i = 0; i < cards.Count; i++)
         {
             cards[i].StartCoroutine(GameManager.cardAnimator.FlyTo(basePosition, cards[i], GameManager.AnimateGame));
             if (cards[i].faceDown == false)
             {
                 cards[i].StartCoroutine(GameManager.cardAnimator.Flip(cards[i], GameManager.AnimateGame));
             }
             cards[i].StartCoroutine(GameManager.cardAnimator.Orient(cards[i], null, GameManager.AnimateGame, targetMachine));
         }
     }
     else
     {
         for (int i = 0; i < cards.Count; i++)
         {
             cards[i].transform.position = basePosition;
             cards[i].transform.rotation = Quaternion.Euler(0.0f, cards[i].transform.rotation.eulerAngles.y, 0.0f);
         }
     }
 }
예제 #2
0
    /// <summary>
    /// types 1==Passing, 2==Calling, 3==Alone
    /// </summary>
    /// <param name="playerID"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public static GameObject SpawnAIText(int playerID, int type, StateMachineSystem.StateMachine targetMachine)
    {
        GameObject spawnedOject;

        if (type == 1)
        {
            spawnedOject = Instantiate(instance.passSticker);
        }
        else if (type == 2)
        {
            spawnedOject = Instantiate(instance.callSticker);
        }
        else
        {
            spawnedOject = Instantiate(instance.aloneSticker);
        }

        spawnedOject.transform.position = Vector3.Lerp(Vector3.zero, targetMachine.Memory.GetData <Player>("Player" + playerID).gameObject.transform.position, 0.5f);
        if (type == 3)
        {
            spawnedOject.transform.position += Vector3.down * 0.65f;
        }

        spawnedOject.gameObject.GetComponent <SpriteRenderer>().color = (playerID % 2 == 0) ? PlayerColor : OpponentColor;
        foreach (TMPro.TMP_Text text in spawnedOject.GetComponentsInChildren <TMPro.TMP_Text>())
        {
            text.color = (playerID % 2 == 0) ? PlayerColor : OpponentColor;
        }
        return(spawnedOject);
    }
    /// <summary>
    /// Orients a card to line up with a player's hand. if string is empty or null it orients with the screen.
    /// </summary>
    /// <param name="target"></param>
    /// <param name="playerName"></param>
    /// <returns></returns>
    public IEnumerator Orient(Card target, string playerName, bool animated, StateMachineSystem.StateMachine targetMachine)
    {
        if (GameManager.AnimateGame)
        {
            while (target.animating)
            {
                yield return(null);
            }
        }
        target.animating = true;

        float      orientation = (string.IsNullOrEmpty(playerName)) ? 0.0f : targetMachine.Memory.GetData <Player>(playerName).gameObject.transform.eulerAngles.z + 90.0f;
        Quaternion goalRot     = Quaternion.Euler(0.0f, target.transform.eulerAngles.y, orientation);

        if (animated && GameManager.AnimateGame)
        {
            while ((goalRot.eulerAngles - target.transform.rotation.eulerAngles).magnitude > 0.1f)
            {
                target.transform.rotation = Quaternion.Lerp(target.transform.rotation, goalRot, 0.4f);
                yield return(null);
            }
        }

        //Enforce final position
        target.transform.rotation = goalRot;
        //End animation
        target.animating = false;
    }
    /// <summary>
    /// Adjusts the cards within the player's hand to match calucalted positions
    /// </summary>
    /// <param name="playerName"></param>
    /// <returns></returns>
    public IEnumerator AdjustHand(string playerName, bool animated, StateMachineSystem.StateMachine targetMachine)
    {
        Player p = targetMachine.Memory.GetData <Player>(playerName);

        p.AssertHandSpriteOrdering();
        Vector3[] pos = GetCardPlacementOffsets(p.gameObject, p.GetHand().Count);

        //Move all cards
        for (int i = 0; i < p.GetHand().Count; i++)
        {
            p.GetHand()[i].goalPosition = pos[i];
            StartCoroutine(FlyTo(pos[i], p.GetHand()[i], animated));
        }

        //Wait for all sub animations to finish
        if (GameManager.AnimateGame)
        {
            for (int i = 0; i < p.GetHand().Count; i++)
            {
                while (p.GetHand()[i].animating)
                {
                    yield return(null);
                }
            }
        }
    }
예제 #5
0
    public static int  ScoreingValue(Card c, StateMachineSystem.StateMachine targetMachine)
    {
        Card.Suit trump = targetMachine.Memory.GetData <Card.Suit>("Trump");
        Card      lead  = targetMachine.Memory.GetData <List <Card> >("Plays")[0];
        //Intial value is as printed on the card
        int val = (int)c.value;

        //If on suit, add value
        if (c.suit == lead.suit)
        {
            val += 20;
        }
        //If on trump, add value
        if (c.suit == trump)
        {
            val += 50;
        }
        //Override on-color Jack
        if (c.suit == trump.SameColorSuit() && c.value == Card.Value.Jack)
        {
            val = 200;
        }
        //Override on-trump Jack
        if (c.suit == trump && c.value == Card.Value.Jack)
        {
            val = 250;
        }
        return(val);
    }
예제 #6
0
    public static bool isValidPlay(Card c, Player p, StateMachineSystem.StateMachine targetMachine)
    {
        Card.Suit   trump = targetMachine.Memory.GetData <Card.Suit>("Trump");
        List <Card> plays = targetMachine.Memory.GetData <List <Card> >("Plays");

        if (plays.Count > 0)
        {
            bool hasLeadSuitInHand = false;

            //Figure out the lead suit
            Card.Suit leadSuit = plays[0].suit;
            //overide the lead suit for offsuit Trump jack
            if (plays[0].value == Card.Value.Jack && plays[0].suit == trump.SameColorSuit())
            {
                leadSuit = trump;
            }

            //Figure out the suit of what we playes
            Card.Suit playedSuit = c.suit;
            //Override the played suit for offsuit trump jack
            if (c.value == Card.Value.Jack && c.suit == trump.SameColorSuit())
            {
                playedSuit = trump;
            }

            //Check if the hand has a card that is valid suit
            foreach (Card card in p.GetHand())
            {
                Card.Suit cardsSuit = card.suit;
                //Overrride the offsuit Trump jack
                if (card.value == Card.Value.Jack && card.suit == trump.SameColorSuit())
                {
                    cardsSuit = trump;
                }

                if (cardsSuit == leadSuit)
                {
                    hasLeadSuitInHand = true;
                }
            }

            //If they have an on suit play at the played card isn't, invalidate the play
            if (hasLeadSuitInHand && playedSuit != leadSuit)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        else
        {
            return(true);
        }
    }
예제 #7
0
 /// <summary>
 /// Turns all of the cards in the deck towards the specific location and returns cards to the base position
 /// </summary>
 /// <param name="playerNameOrNull"></param>
 /// <returns></returns>
 public IEnumerator Orient(string playerNameOrNull, StateMachineSystem.StateMachine targetMachine)
 {
     foreach (Card card in cards)
     {
         card.StartCoroutine(GameManager.cardAnimator.Orient(card, playerNameOrNull, GameManager.AnimateGame, targetMachine));
         card.StartCoroutine(GameManager.cardAnimator.FlyTo(basePosition, card, GameManager.AnimateGame));
     }
     //Wait for all the cards to finish animating
     foreach (Card card in cards)
     {
         while (card.animating)
         {
             yield return(null);
         }
     }
 }
예제 #8
0
 // Start is called before the first frame update
 void Start()
 {
     if (instance != null)
     {
         Debug.Log("Multiple game managers in scene.");
         Debug.Break();
     }
     instance = this;
     if (GameManager.RunGenetics == false)
     {
         geneticGames = 1;
     }
     stateMachines = new StateMachineSystem.StateMachine[geneticGames];
     for (int i = 0; i < geneticGames; i++)
     {
         stateMachines[i]     = new StateMachineSystem.StateMachine();
         stateMachines[i].UID = i;
         stateMachines[i].Transition <StateMachineSystem.EuchreStates.SetupGame>();
     }
 }
예제 #9
0
 void OnEnable()
 {
     fsm = GetComponent<StateMachine>();
     fsm.Enqueue(states.downState);
     fsm.Next();
 }
    /// <summary>
    /// Draws a number of cards from the game deck and animates their arrival to the player's hand
    /// </summary>
    /// <param name="playerName"></param>
    /// <param name="deckName"></param>
    /// <param name="amt"></param>
    /// <returns></returns>
    public IEnumerator Deal(string playerName, string deckName, int amt, bool animated, StateMachineSystem.StateMachine targetMachine)
    {
        if (amt == 0)
        {
            yield break;
        }

        Card[] drawn = targetMachine.Memory.GetData <Deck>(deckName).Draw(amt);
        Player p     = targetMachine.Memory.GetData <Player>(playerName);

        for (int i = 0; i < drawn.Length; i++)
        {
            Card card = drawn[i];
            StartCoroutine(Orient(card, p.gameObject.name, animated, targetMachine));

            card.gameObject.transform.rotation = Quaternion.Euler(0.0f, 180.0f, p.gameObject.transform.rotation.eulerAngles.z + 90.0f);
            p.AddCard(card);
        }
        p.AssertHandSpriteOrdering();
        for (int i = 0; i < drawn.Length; i++)
        {
            if (p.isHuman || GameManager.ShowAllCards)
            {
                StartCoroutine(Flip(drawn[i], animated));
            }
        }
        if (GameManager.AnimateGame)
        {
            foreach (Card c in drawn)
            {
                while (c.animating)
                {
                    yield return(null);
                }
            }
        }

        if (GameManager.PlayAudio)
        {
            FMODUnity.RuntimeManager.PlayOneShot("event:/cardSlide" + Random.Range(1, 4), drawn[0].transform.position);
        }

        //This handles cards moving to the player's hand from the deck as well
        yield return(AdjustHand(playerName, animated, targetMachine));
    }
예제 #11
0
    public static IEnumerator MakePlayDecision(int playerID, PointSpread pointSpread, StateMachineSystem.StateMachine targetMachine)
    {
        int    trumpCaller = targetMachine.Memory.GetData <int>("TrumpCaller");
        Player player      = targetMachine.Memory.GetData <Player>("Player" + playerID);

        Card.Suit trump = targetMachine.Memory.GetData <Card.Suit>("Trump");
        yield return(null);

        Hand handViewframe = CloneListOfCards(player.GetHand());

        //Remove all legal plays
        handViewframe.RemoveAll((Card c) => { return(!isValidPlay(c, player, targetMachine)); });
        Card        playCard = null;
        List <Card> plays    = targetMachine.Memory.GetData <List <Card> >("Plays");

        //Calculate this player's team is winning

        //Debug.LogWarning("Player" + playerID);



        if (plays.Count == 0)
        {
            //Debug.Log(handViewframe.Count);

            Hand trumpHand = CloneListOfCards(handViewframe);
            trumpHand.RemoveAll((Card c) => { return(c.suit != trump); });
            trumpHand.Sort((Card x, Card y) => {
                if (CardValue(x, trump, pointSpread) < CardValue(y, trump, pointSpread))
                {
                    return(-1);
                }
                else
                {
                    return(1);
                }
            });
            Dictionary <Card.Suit, int> singletonSuits = new Dictionary <Card.Suit, int>();
            foreach (Card card in player.GetHand())
            {
                if (singletonSuits.ContainsKey(card.suit) == false)
                {
                    singletonSuits.Add(card.suit, 0);
                }
                singletonSuits[card.suit]++;
            }
            //Limit suit count to only those that have one in them
            foreach (Card.Suit item in System.Enum.GetValues(typeof(Card.Suit)))
            {
                if (singletonSuits.ContainsKey(item) && singletonSuits[item] > 1)
                {
                    singletonSuits.Remove(item);
                }
            }

            //If we have 3+ trump in hand, lead with our strongest trump
            if (playCard == null)
            {
                if (trumpHand.Count >= 3)
                {
                    //Debug.Log("Leading Strong Trump");
                    playCard = trumpHand[trumpHand.Count - 1];
                }
            }

            //If we have just an Ace of an OffSuit, play that
            if (playCard == null)
            {
                foreach (Card.Suit item in singletonSuits.Keys)
                {
                    foreach (Card card in player.GetHand())
                    {
                        if (card.suit == item && card.value == Card.Value.Ace)
                        {
                            //Debug.Log("Leading offsuit Ace");
                            playCard = card;
                            break;
                        }
                    }
                    if (playCard != null)
                    {
                        break;
                    }
                }
            }

            //If we have the right bower, play that if its our only trump
            if (playCard == null && trumpHand.Count == 1)
            {
                playCard = handViewframe.Find((Card c) => { return(c.suit == trump && c.value == Card.Value.Jack); });
                //if (playCard != null) Debug.Log("Leading Singleton Right Bower");
            }

            //If we have a singleton card, play that.
            if (playCard == null)
            {
                foreach (Card.Suit item in singletonSuits.Keys)
                {
                    foreach (Card card in player.GetHand())
                    {
                        if (card.suit == item)
                        {
                            //Debug.Log("Leading Singleton");
                            playCard = card;
                            break;
                        }
                    }
                    if (playCard != null)
                    {
                        break;
                    }
                }
            }

            //Play our lowest value card.
            if (playCard == null)
            {
                //Debug.Log("Leading Lowest Card");
                handViewframe.Sort((Card x, Card y) => { return((CardValue(x, trump, pointSpread) < CardValue(y, trump, pointSpread)) ? -1 : 1); });
                playCard = handViewframe[0];
            }

            //Pick a random card
            if (playCard == null)
            {
                playCard = handViewframe[Random.Range(0, handViewframe.Count)];
            }
        }
        else if (handViewframe.Count == 1)
        {
            //Debug.Log("Only one valid play");
            //If there is only one card, play it
            playCard = handViewframe[0];
        }
        else
        {
            bool teamWinningHand;

            List <Card> sortedPlays = CloneListOfCards(plays);
            sortedPlays.Sort((Card x, Card y) => {
                if (ScoreingValue(x, targetMachine) < ScoreingValue(y, targetMachine))
                {
                    return(-1);
                }
                else
                {
                    return(1);
                }
            });
            //Make it so the best card is actually in the first position
            sortedPlays.Reverse();
            {
                string ret = "SortedPlays: ";
                foreach (Card item in sortedPlays)
                {
                    ret += item.Shortname() + ", ";
                }
                //Debug.Log(ret);
            }
            int currentWinner = targetMachine.Memory.GetData <Dictionary <Card, int> >("PlaysMap")[sortedPlays[0]];
            teamWinningHand = currentWinner % 2 == playerID % 2;


            System.Func <Card, bool> isWinningPlay = (Card c) => {
                Card winningCard = sortedPlays[0];
                if (ScoreingValue(c, targetMachine) > ScoreingValue(winningCard, targetMachine))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            };

            //Calcualte all cards that can win a play
            Hand winningPlays = CloneListOfCards(handViewframe);
            //Remove things that are not winning plays
            winningPlays.RemoveAll((Card c) => { return(!isWinningPlay(c)); });
            //Sort them by CardValue
            winningPlays.Sort((Card x, Card y) => { return((CardValue(x, trump, pointSpread) < CardValue(y, trump, pointSpread)) ? -1 : 1); });
            //Calculate all cards that can lose a play
            Hand losingPlays = CloneListOfCards(handViewframe);
            //Remove things that are winning plays
            losingPlays.RemoveAll((Card c) => { return(isWinningPlay(c)); });
            //Sort them by value
            losingPlays.Sort((Card x, Card y) => { return((CardValue(x, trump, pointSpread) < CardValue(y, trump, pointSpread)) ? -1 : 1); });

            {
                string ret = "Losers: ";
                foreach (Card card in losingPlays)
                {
                    ret += card.Shortname() + ", ";
                }
                ret += "\nWinners:";
                foreach (Card card in winningPlays)
                {
                    ret += card.Shortname() + ", ";
                }
                //Debug.Log(ret);
            }

            //If we have no winning plays, or we are already winning
            if ((winningPlays.Count == 0 || teamWinningHand) && losingPlays.Count > 0)
            {
                //Debug.Log("Playing worst card:(" + (winningPlays.Count == 0) + " || " + teamWinningHand + ") && " + (losingPlays.Count > 0) );
                //Play the lowest value losing play
                playCard = losingPlays[0];
            }
            //If we have no losing plays, or we are not winning
            else if ((losingPlays.Count == 0 || teamWinningHand == false) && winningPlays.Count > 0)
            {
                //Debug.Log("Playing best card:(" + (losingPlays.Count == 0) + " || " + (teamWinningHand == false) + ") && " + (winningPlays.Count > 0));
                //Play the lowest value winning play
                playCard = winningPlays[0];
            }
        }

        //do { playCard = player.GetHand()[Random.Range(0, player.GetHand().Count)]; } while (isValidPlay(playCard, player) == false);
        player.PostNotification("CardPlayedInZone" + targetMachine.UID, new object[] { GameObject.FindGameObjectWithTag(GameManager.Tags.PlayZone), playCard });
    }
예제 #12
0
    public static IEnumerator MakeTrumpDiscardDecision(int playerID, PointSpread pointSpread, StateMachineSystem.StateMachine targetMachine)
    {
        //Discard the lowest value card or a card that makes the hand two suited (aside from a trump)
        yield return(null);

        Player p = targetMachine.Memory.GetData <Player>("Player" + playerID);

        Card.Suit trump          = targetMachine.Memory.GetData <Card.Suit>("Trump");
        Card      discard        = null;
        Hand      cardsRemaining = CloneListOfCards(p.GetHand());

        System.Func <Hand> SortByLowestValue = () => {
            Hand temp = CloneListOfCards(cardsRemaining);
            temp.Sort((Card x, Card y) => {
                if (CardValue(x, trump, pointSpread) < CardValue(y, trump, pointSpread))
                {
                    return(-1);
                }
                else
                {
                    return(1);
                }
            });
            return(temp);
        };

        System.Func <Hand> RemoveTrump = () => {
            Hand temp = CloneListOfCards(cardsRemaining);
            temp.RemoveAll((Card c) => { return(c.suit == trump); });
            return(temp);
        };
        System.Func <Hand> RemoveAces = () => {
            Hand temp = CloneListOfCards(cardsRemaining);
            temp.RemoveAll((Card c) => { return(c.value == Card.Value.Ace); });
            return(temp);
        };
        System.Func <Hand> LowerSuitCount = () => {
            Hand temp = CloneListOfCards(cardsRemaining);
            Dictionary <Card.Suit, int> suitCount = new Dictionary <Card.Suit, int>();
            foreach (Card card in temp)
            {
                if (suitCount.ContainsKey(card.suit) == false)
                {
                    suitCount.Add(card.suit, 0);
                }
                suitCount[card.suit]++;
            }
            int       lowestCount = int.MaxValue;
            Card.Suit fewestSuit  = Card.Suit.Clubs;
            foreach (Card.Suit suit in System.Enum.GetValues(typeof(Card.Suit)))
            {
                if (suitCount.ContainsKey(suit) && suitCount[suit] > 0 && suitCount[suit] < lowestCount)
                {
                    fewestSuit = suit;
                }
            }
            //Don't remove anything if it is our only suit
            if (suitCount[fewestSuit] != temp.Count)
            {
                //Otherwise, remove all suits that do not match the smallest one.
                temp.RemoveAll((Card c) => { return(c.suit != fewestSuit); });
            }

            return(temp);
        };

        System.Func <Hand>[] actions = new System.Func <Hand>[] { RemoveTrump, RemoveAces, LowerSuitCount, SortByLowestValue };
        //Attempt to try all of these actions, and if they leave us with
        for (int i = 0; i < actions.Length; i++)
        {
            if (discard != null)
            {
                break;
            }
            //Perform a reduction on the hand
            Hand newPerspectives = actions[i]();
            //Check what that leaves us with
            if (newPerspectives.Count == 1)
            {
                //If this criteria left us with only one card, we discard that.
                discard = newPerspectives[0];
            }
            else if (newPerspectives.Count == 0)
            {
                //If this action resulted in an empty list, it is not a valid criteria and we need to use our most recent intact version, sort it, and pick the lowest value from it.
                discard = SortByLowestValue()[0];
            }
            else
            {
                //Otherwise, update the remaining cards after this reduction
                cardsRemaining = newPerspectives;
            }
        }
        if (discard == null)
        {
            discard = cardsRemaining[0];
        }

        p.PostNotification("CardPlayedInZone" + targetMachine.UID, new object[] { GameObject.FindGameObjectWithTag(GameManager.Tags.PlayZone), discard });
    }
예제 #13
0
    public static IEnumerator MakeTrumpOrderingDecision(int playerID, PointSpread pointSpread, StateMachineSystem.StateMachine targetMachine)
    {
        //Default to passing
        bool   pass         = true;
        Player player       = targetMachine.Memory.GetData <Player>("Player" + playerID);
        Card   revealedCard = targetMachine.Memory.GetData <Card>("RevealedCardFromKittie");

        Card.Suit?callSuit     = (revealedCard.faceDown) ? null : (Card.Suit?)revealedCard.suit;
        int       dealerID     = targetMachine.Memory.GetData <int>("Dealer");
        bool      dealerOnTeam = (dealerID % 2) == (playerID % 2);

        //Debug.Log("Player" + playerID+" team w/ Dealer: " + dealerOnTeam);


        if (callSuit != null)
        {
            //Handle deciding on just this card
            int points = CalculateHandPoints(player.GetHand(), revealedCard, (Card.Suit)callSuit, dealerOnTeam, pointSpread);
            //Debug.Log("Player" + playerID + " Points: " + points);
            if (points >= pointSpread.callThreshold)
            {
                pass = false;
            }
            //Debug.Log("Player" + playerID + ": " + points + " for " + ((Card.Suit)callSuit).Shortname());
            //Call a loner if we are confident in our hand, unless we have more than seven points
            if (points >= pointSpread.lonerThreshold && targetMachine.Memory.GetData <int>("Team" + (playerID % 2) + "Points") <= 7)
            {
                //If we are the dealer, calling loner is fine. If we are not the dealer, and it is the right bower, don't go alone.
                if (dealerID == playerID || revealedCard.value != Card.Value.Jack)
                {
                    targetMachine.Memory.GetData <TrumpSelector>("TrumpSelector").aloneToggle.isOn = true;
                }
            }
        }
        else
        {
            //If screw-the-dealer is enabled, disable passing
            if (GameManager.ScrewTheDealer && dealerID == playerID)
            {
                pass = false;
            }

            List <Card.Suit> suits = new List <Card.Suit>(new Card.Suit[] { Card.Suit.Clubs, Card.Suit.Diamonds, Card.Suit.Hearts, Card.Suit.Spades });
            suits.Remove(revealedCard.suit);
            int maxPoints = int.MinValue;
            foreach (Card.Suit suit in suits)
            {
                int points = CalculateHandPoints(player.GetHand(), revealedCard, suit, dealerOnTeam, pointSpread);
                if (points > maxPoints)
                {
                    maxPoints = points;
                    callSuit  = suit;
                }
            }
            if (maxPoints >= pointSpread.callThreshold)
            {
                pass = false;
            }

            //If this is a strong call, go alone
            if (maxPoints >= 9 && targetMachine.Memory.GetData <int>("Team" + (playerID % 2) + "Points") <= 7)
            {
                targetMachine.Memory.GetData <TrumpSelector>("TrumpSelector").aloneToggle.isOn = true;
            }

            //Debug.Log("Player" + playerID + ": " + maxPoints + " for " + ((Card.Suit)callSuit).Shortname());
        }

        yield return(null);

        if (pass)
        {
            player.PostNotification("Pass" + targetMachine.UID);
        }
        else
        {
            player.PostNotification("OrderUp" + targetMachine.UID, (Card.Suit)callSuit);
        }
    }