2012-01-08 30 views
1

テキサスホールデムポーカーをプレイできるフレームプログラムを作成しようとしています。 CurrentPlayerは、そのカードを受け取る方法C#構造体変数の値を保持できません

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; 
     } 

そしてここにある:CurrentPlayerがペアを持っている場合、私は決定した機能hasPairとのトラブルを抱えています

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); 
    } 

しかしをhasPair機能では、CurrentPlayerさんのカードの数字と色は0です。さまざまな方法で試してみましたが、クエリで質問すると、Deal_Cards関数で初期化されていますが、プレーヤーのカードの数値は取得できません。しかし地上のカードは問題ありません。

興味深いことに、display_Player_Cards(Player)機能が正常に機能しているため(値が正しく取り込まれ、カードが表示されます)。

私のようなタイプPlayer(構造体)のパブリック変数を使用します。彼らはそれらの値を保持することはできませんなぜ

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

?どうすればこの問題を解決できますか? ありがとうございます。

+0

デバッグし、 'Deal_Cards'メソッドが実行を終了するかどうかを確認してください。これらの 'while(true)'ループは本当に危険です。実行が終了しない場合は、フィールドがすべてゼロである理由を確認したことがあります。 – aevitas

答えて

6

ここで実行している問題は、構造体が.NETで値渡しされることです。したがって、Deal_CardsメソッドはPlayerインスタンスのコピーを受け取り、そのコピーにカードを割り当てます。 Deal_Cardsに渡された元の値は変更されていません。

これを修正するには、Playerclassにするか、または参照渡しする必要があります。私は非常にお勧めしますPlayerclass。変更可能な構造体を持つことは、痛みへの道にすぎず、このようなバグを追跡するのは難しいです。

+0

Jaredさんに感謝し、Playerをクラスとして定義して問題を解決しました。 – void

0

Cでは、structを値渡しすると、呼び出されたルーチンにstructのコピーが効果的に与えられます。構造体のコピーでルーチンが何をするかにかかわらず、呼び出し元の構造体のフィールドは影響を受けません。呼び出された関数が構造体を変更できるようにするには、それを "ref"パラメータにする必要があります。

structをrefパラメータとして渡すと、クラスオブジェクト参照を渡すよりもセマンティクスが厳密になることに注意してください。クラスオブジェクトへの参照を与えられたルーチンは、参照で必要なものだけでなく、を望むときはいつでも、それが望むものを実行できる他のコードで利用できるようにすることができます。参照が返された場合対照的に、structをrefパラメータとして与えられたルーチンは、返されるまでは構造体で必要なことを何でも行うことができますが、構造体のフィールドを直接または間接的に変更する能力はありません。

あなたは 'Player'データ型の内容を表示しないので、構造体であるべきかクラスであるべきかは明確ではありません。しかし、プレイヤーの手は2枚のカードしか持たないので、構造体の論理的な候補に見えます。それを変更可能なクラスにすることは、私にとって本当に不快に思えるでしょう。プレイヤーの手に不変の構造体を作成し、Deal_Cardsメソッドを構造体を返すGenerateHand関数に置き換えるか、playerHandをrefパラメーターとしてDealCardsに渡すことができます。 '不変'ルートに進むと、クラスを使用することができますが、このコンテキストでは不変の構造体の代わりに不変のクラスを使用することにほとんどメリットがありません。

関連する問題