简体   繁体   中英

C# Cannot hold the value of struct variable

I am trying to write a frame program that allows you to play Texas Hold'em Poker. And I am having trouble with function hasPair that decides if CurrentPlayer has a Pair:

  public bool hasPair(Player CurrentPlayer)
        {
            bool flag;
            Card[] SevenCards = new Card[7];

            SevenCards[0].Color = CurrentPlayer.Card1.Color;
            SevenCards[0].Number = CurrentPlayer.Card1.Number;
            SevenCards[1].Color = CurrentPlayer.Color2;
            SevenCards[1].Number = CurrentPlayer.Number2;

            SevenCards[2] = Ground.Card1;
            SevenCards[3] = Ground.Card2;
            SevenCards[4] = Ground.Card3;
            SevenCards[5] = Ground.Card4;
            SevenCards[6] = Ground.Card5;

            flag = isThere_Pair(SevenCards); 

            return flag;
        }

And here is how CurrentPlayer receives its cards:

    public void Deal_Cards(Player Player)
    {
        int Color1, No1, Color2, No2;

        while (true)
        {


        dealhelper1:

            Color1 = (RandomColor.Next() % 4);
            No1 = ((RandomNo.Next() % 13));


            if (CardDeck[Color1, No1].isChosen == true)
            {
                goto dealhelper1;
            }

            if (CardDeck[Color1, No1].isChosen == false)
            {
                Player.Card1.Color = Color1;

                Player.Card1.Number = No1+1;
                Player.Card1.imagePath = CardDeck[Color1, No1].imagePath;

                Player.Color1 = CardDeck[Color1, No1].Color;
                Player.Number1 = CardDeck[Color1, No1].Number;                   

                CardDeck[Color1, No1].isChosen = true;
                break;
            }
        }

        while (true)
        {
            dealhelper2:

            Color2 = (RandomColor.Next() % 4);
            No2 = ((RandomNo.Next() % 13));

            if (CardDeck[Color2, No2].isChosen == true)
            {
                goto dealhelper2;
            }

            if (CardDeck[Color2, No2].isChosen == false)
            {
                CardDeck[Color2, No2].isChosen = true;


                Player.Card2.Color = Color2;
                Player.Card2.Number = (No2)+1;

                Player.Color2 = CardDeck[Color2, No2].Color;
                Player.Number2 = CardDeck[Color2, No2].Number;
                break;
            }
        }

        display_Player_Cards(Player);
    }

But in the hasPair function, CurrentPlayer 's cards' numbers and colors are 0. I tried it in different ways but when I ask in a query, i cannot get the player cards' number values, although they have been initialized by the Deal_Cards function. Ground's cards have no problem, though.

interestingly, display_Player_Cards(Player) function works correctly (so it takes the values successfully and displays the cards) .

I use public variables of type Player (struct) like:

    public Player P1 = new Player();
    public Player AI = new Player();

Why can't they hold their values? How can I solve this issue? Thanks for help.

The issue your running into here is that struct's are passed by value in .Net. Hence the Deal_Cards method receives a copy of the Player instance and assigns cards to that copy. The original value passed to Deal_Cards is unmodified.

To fix this you need to either make Player a class or pass it by reference. I highly recomend making Player a class . Having mutable structs is just a path to pain and hard to track down bugs like this.

In C, passing a struct by value effectively gives a copy of the struct to the called routine; regardless of what the routine does with its copy of the struct, the fields of the caller's struct will be unaffected. If you want the called function to be able to modify the struct, you must make it a "ref" parameter.

Note that passing a struct as a ref parameter has tighter semantics than passing a class-object reference. A routine that is given a reference to a class object may not only do whatever it wants with the reference, but it can make it available to other code that may do whatever it wants whenever it wants , even after the function that was originally given the reference has returned. By contrast, a routine which is given a struct as a ref parameter may do whatever it wants with the struct until it returns, but it will have no ability to directly or indirectly modify the fields of the struct after it returns.

You don't show the contents of your 'Player' data type, so it's not clear whether it should be a struct or a class. The player's hand, however, would seem to be a logical candidate for a struct since it simply holds two cards. Making it a mutable class would seem really icky to me. One could either make the player's hand an immutable struct and replace the Deal_Cards method with a GenerateHand function that returns a playerHand struct, or else pass a playerHand to a DealCards as a ref parameter. If one goes the 'immutable' route, one could use a class, but I see little benefit in using an immutable class instead of an immutable struct in this context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM