【解決方法】このファイルを抽出するにはどうすればよいですか


Player1:AH,3C,8C,2S,JD
Player2:KD,QH,10C,4C,AC
Player3:6S,8D,3D,JH,2D
Player4:5H,3S,KH,AS,9D
Player5:JS,3H,2H,2C,4D

上記は入力ファイルです。入力ファイルには 5 つの行が含まれ、各プレイヤーの手札 5 枚のカードに対応しています。 各行には、コロンで区切られたプレーヤーの名前と、カンマで区切られた 5 枚のカードのリストが含まれます。 各カードは 2 文字で、額面の後にスートが続きます (S = スペード、H = ハート、D = ダイヤ、C = クラブ)。

抽出して各プレイヤーのスコアを計算したい

私が試したこと:

string path = @"abc.txt";

string[] lines = File.ReadAllLines(path);


foreach (var line in lines)
{
    var playerName = line.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[0];
}

解決策 1

最初の分割の結果を破棄しないでください。各行は 2 つの要素の配列を生成します。

["Player1","AH,3C,8C,2S,JD"]
["Player2","KD,QH,10C,4C,AC"]
["Player3","6S,8D,3D,JH,2D"]
["Player4","5H,3S,KH,AS,9D"]
["Player5","JS,3H,2H,2C,4D"]

したがって、最初の要素はプレイヤー名で、2 番目の要素はカードのリストです。
そのため、名前を抽出し、2 番目の分割を使用してカード リストを取得します。
それを処理すると、スコアを計算できます。

ただし、ファイルの説明がサンプル データと一致しないことに注意してください。

解決策 2

どのようにハンドを獲得するかは、プレイ中のゲームのルールによって異なります。
しかし、正規表現を使用して、必要なデータの部分を少なくとも抽出する方法を次に示します。
比較を容易にするために、文字列値を列挙値に解析する可能性があります。
また、ファイルの形式を管理している場合は、スーツをランクの前に置くことをお勧めします.

C#
result += CP.Cards.ParseCards 
( 
@"
Player1:AH,3C,8C,2S,JD
Player2:KD,QH,10C,4C,AC
Player3:6S,8D,3D,JH,2D
Player4:5H,3S,KH,AS,9D
Player5:JS,3H,2H,2C,4D
"
) ;

namespace CP
{
  public static partial class Cards 
  {
    private static readonly System.Collections.Generic.Dictionary<string,string> deck ;

    private static readonly System.Text.RegularExpressions.Regex reg ;

    static Cards
    (
    )
    {
      deck = new System.Collections.Generic.Dictionary<string,string>
      (
        System.StringComparer.InvariantCultureIgnoreCase
      )
      {
        { "H" , "Hearts" } , { "C"  , "Clubs" } , { "S" , "Spades" } , { "D" , "Diamonds" } ,
        { "A" , "Ace"    } , { "2"  , "Two"   } , { "3" , "Three"  } , { "4" , "Four"     } ,
        { "5" , "Five"   } , { "6"  , "Six"   } , { "7" , "Seven"  } , { "8" , "Eight"    } ,
        { "9" , "Nine"   } , { "10" , "Ten"   } , { "J" , "Jack"   } , { "Q" , "Queen"    } ,
        { "K" , "King"   }
      } ;

      reg = new System.Text.RegularExpressions.Regex
      (
        @"((^|\G)\s*(?'Player'[^:]+):(?'Card'(?'Rank'\w{1,2})(?'Suit'[HCSD])\s*(,|$)){5})"
      ,
        System.Text.RegularExpressions.RegexOptions.Compiled
        |
        System.Text.RegularExpressions.RegexOptions.IgnoreCase
        |
        System.Text.RegularExpressions.RegexOptions.Multiline
      ) ;

      return ;
    }

    public static int
    ParseCards
    (
      string Cards
    )
    {
      System.Text.RegularExpressions.MatchCollection mat = reg.Matches ( Cards ) ;

      for ( int i = 0 ; i < mat.Count ; i++ )
      {
        System.Console.Write ( "\r\n{0}  means  {1} has :" , mat [ i ].Value.Trim() , mat [ i ].Groups [ "Player" ].Value ) ;

        System.Text.RegularExpressions.Group rank = mat [ i ].Groups [ "Rank" ] ;
        System.Text.RegularExpressions.Group suit = mat [ i ].Groups [ "Suit" ] ;

        for ( int j = 0 ; j < mat [ i ].Groups [ "Card" ].Captures.Count ; j++ )
        {
          System.Console.Write ( "   {0} of {1}" , deck [ rank.Captures [ j ].Value ] , deck [ suit.Captures [ j ].Value ] ) ;
        }
      }

      return ( mat.Count ) ;
    }
  }
} 

解決策 3

私は単純なアプローチに行きます。 これらの行に沿ったもの:

C#
IEnumerable<(string player,string[] cards)>items=lines.Select(l =>
  {
    var array = l.Split(':');
    var player = array[0];
    var cards = array[1].Split(',');
    return (player, cards);
  });
  foreach(var (player, cards) in items)
    {
     Console.WriteLine($"The player is {player} the cards are {string.Join(',',cards)}");
    }
/* Prints
The player is Player1 the cards are AH,3C,8C,2S,JD
The player is Player2 the cards are KD,QH,10C,4C,AC
The player is Player3 the cards are 6S,8D,3D,JH,2D
The player is Player4 the cards are 5H,3S,KH,AS,9D
The player is Player5 the cards are JS,3H,2H,2C,4D
*/

コメント

タイトルとURLをコピーしました