Click here to Skip to main content
15,885,961 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
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


Above is an input file The input file will contain 5 rows, one for each player's hand of 5 cards. Each row will contain the player's name separated by a colon then a comma separated list of the 5 cards. Each card will be 2 characters, the face value followed by the suit (S = Spades, H = Hearts, D = Diamonds and C = Clubs).

I want to extract it and calculate score for each player

What I have tried:

string path = @"abc.txt";

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


foreach (var line in lines)
{
    var playerName = line.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[0];
}
Posted
Updated 3-Dec-22 7:51am
v3
Comments
Richard MacCutchan 2-Dec-22 15:48pm    
You now need to split the second part of each line using comma as the separator.
PIEBALDconsult 2-Dec-22 17:51pm    
RegularExpressions is your friend.

I would go for the simplistic approach. Something along these lines:

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
*/

 
Share this answer
 
v2
How you score a hand will depend on the rules of the game being played.
But here's a way to at least extract the parts of the data you want by using a Regular Expression.
I would likely parse the string values into enumerated values for easier comparisons.
Also, if you are in control of the format of the file, then I recommend putting the suit before the rank.

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 ) ;
    }
  }
} 
 
Share this answer
 
Don't discard the results of your first split: each line generates a two element array:
["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"]
So the first element is the player name, the second is the the list of cards.
So extract the name, then use a second split to give you the cards list.
Process that, and you can work out the score.

Do note however that your file description does not match the sample data!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900