C# Poker How to check if players have different hands - c#

I'm developing a Poker Texas Hold'Em app I have all the combinations working but i cant seem to find a compact way to check which player has the highest combination and the type of it here's some of my code
void Rules(int current,int Power)
{
//checking if the player has any pair
{
Power = 1;
current = 1;
}
}
current = the type of the hand (pair=1,two pair =2..straight flush=8)
Power = the power of the hand (pair of deuces=2....pair of kings=13)
and so on.. I'm updating current and Power with each new combination and since they are parameters of the void each player has his own "current" and "Power" so they don't get messed up.This is what i have so far and my question is how do i check which player has the highest hand without using 20-30 repetitive if statements i was thinking about :
List <int> Arr = new List <int>();
void Rules(int current,int Power)
{
//checking if the player has any pair
{
Power = 1;
current = 1;
Arr.Add(Power);
Arr.Add(current);
}
}
but like this i have no idea which type belongs to which player so it's not use i also tried with strings but than i wont be able to compare them that easily.What should i do ? What's the right approach ?

You might want to make a class for reach rule, to encapsulate the logic. Something like this:
public class Card
{
public string Name { get; private set; }
/* cards have a value of 2-14 */
public int Value { get; private set; }
}
public abstract class Rule()
{
public abstract string Name { get; }
/* hands are calculated in powers of 100, when the card value is added you will get something like 335 */
public abstract int Value { get; }
public abstract bool HasHand(IReadonlyList<Card> cards);
}
public class PairRule() : Rule
{
public override string Name
{
get { return "Pair"; }
}
public override int Value
{
get { return 100; }
}
public override bool HasHand(IReadonlyList<Card> cards)
{
/* implement rule here */
return Enumerable.Any(
from x in cards
group x by x.Value into g
where g.Count() == 2
select g
);
}
}
...
public class Player
{
public IReadonlyList<Card> Hand { get; private set; }
public int GetHandValue(IReadonlyList<Rule> rules)
{
/* get value of hand 100, 200, 300 etc. */
var handValue = Enumerable.Max(
from x in rules
where x.HasHand(Hand)
select x.Value
);
/* get value of cards */
var cardValue = Hand
.OrderByDescending(x => x.Value)
.Take(5)
.Sum();
return handValue + cardValue;
}
}
public class Pot
{
public int Value { get; private set; }
public IReadonlyList<Player> Players { get; private set; }
public IReadonlyList<Player> GetWinners(IReadonlyList<Rule> rules)
{
var playerHands = Enumerable.ToList(
from x in players
select new {
Player = x,
HandValue = x.GetHandValue(rules)
}
);
var maxHand = playerHands.Max(x => x.HandValue);
return Enumerable.ToList(
from x in playerHands
where x.HandValue == maxHand
select x.Player
);
}
}

Related

How to create a structure with embedded fields?

I am looking for information about that in the internet but with no success. The goal is to realize a sort of dataset of 10 subject (sub_1, sub_2... sub_10), each of them has done 3 kind of activities (walk, run, jump) for three time each (trial_1... trial_3) with relative scores. I would like to access these information like:
variable = dataset.sub_1.jump.trial_2.score;
or, at least:
variable = dataset.sub[0].task[2].trial[1].score;
So, the structure would be a tree structure. Until now I only realized a structure with "parallel fields":
struct dataset
{
public string[] sub; // 1 to 10 subjects
public string[] task; // 1 to 3 tasks
public string[] trial; // 1 to 3 trials
public int score; // the score of the above combination
}
Any idea?
This problem can be solved in many ways.
My solution has one drawback, there is no check if user exceeded Score arrays capacity.
I guess database tag has nothing to do with this question
using System;
using System.Linq;
namespace ConsoleApp
{
public abstract class Task
{
public string Name { get; set; }
public int TotalScore { get { return Score.Sum(); } }
public int[] Score { get; set; } = new int[3];
}
public class Walk : Task { }
public class Run : Task { }
public class Jump : Task { }
public class Subject
{
public Walk Walk { get; set; } = new();
public Run Run { get; set; } = new();
public Jump Jump { get; set; } = new();
public int TotalScore { get { return Walk.TotalScore + Run.TotalScore + Jump.TotalScore; }}
}
class Program
{
static void Main(string[] args)
{
var subject = new Subject();
// Adding score to specific trials
subject.Run.Score[0] = 50;
subject.Run.Score[1] = 40;
subject.Run.Score[2] = 60;
subject.Jump.Score[0] = 40;
subject.Jump.Score[1] = 80;
subject.Jump.Score[2] = 100;
// Output score of 1. trial for Walk task
Console.WriteLine(subject.Walk.Score[0]);
// Output total score as a sum of all trials for Jump task
Console.WriteLine(subject.Jump.TotalScore);
// Output total score as a sum of all trials in all tasks
Console.WriteLine(subject.TotalScore);
// ERROR CASE: this will be exception
subject.Jump.Score[3] = 100;
}
}
}
using System;
using System.Collections.Generic;
namespace ConsoleApp
{
public class Trial
{
public Trial(int score)
{
Score = score;
}
public int Score { get; set; }
}
public class Task
{
public List<Trial> Trials { get; } = new List<Trial>();
}
public class Subject
{
public Dictionary<string, Task> Tasks { get; } = new Dictionary<string, Task>();
public Subject()
{
Tasks.Add("walk", new Task());
Tasks.Add("run", new Task());
Tasks.Add("jump", new Task());
}
}
class Program
{
static void Main(string[] args)
{
Subject player1 = new Subject();
player1.Tasks["run"].Trials.Add(new Trial(score: 3));
Console.WriteLine(player1.Tasks["run"].Trials[0].Score);
}
}
}
Maybe a class for everything is too much, but maybe you want to add a description property for tasks one day or a timestamp for the trial. Then it's ok.
public class Subject
{
private Dictionary<string,Activity> _activities { get; }= new Dictionary<string, Activity>();
public Activity this[string activity]
{
get
{
if (!_activities.Keys.Contains(activity))
_activities[activity] = new Activity();
return _activities[activity];
}
set
{
_activities[activity] = value;
}
}
public int Score => _activities.Values.Sum(x => x.Score);
}
public class Activity
{
private Dictionary<int, Trial> _trials { get; } = new Dictionary<int, Trial>();
public Trial this[int trial]
{
get
{
if (!_trials.Keys.Contains(trial))
_trials[trial] = new Trial();
return _trials[trial];
}
set
{
_trials[trial] = value;
}
}
public int Score => _trials.Values.Sum(x => x.Score);
}
public class Trial
{
public int Score { get; set; }
}
public class Answer
{
public void DoSomething()
{
Subject Mindy = new Subject();
Mindy["curling"][1].Score = 5;
Mindy["bowling"][1].Score = 290;
Console.WriteLine(Mindy.Score);
}
}
This is what I would guess you think you need... but from your question I think you're still new to C# and might want to rethink your concept. It looks like a very database-oriented way of looking at the problem, so maybe you might want to take a look at dapper to more closely match your database.
Also, avoid using the classname Task, this can imo only cause confusion if you ever start using multithreading (System.Threading.Task is a .NET framework component)

i have a problem with my adaptive moving average trading system

I created a trading system with an adaptive moving average on the average true range but the program reports this error to me
the modifier public is not valid for this item
at line 21 of the code
public int avgTrueRange.value1 { get; set; }
I tried to change public but it always reports this error.
this is the code :
public class MediaMobileAdattiva : SignalObject
{
public MediaMobileAdattiva(object _ctx): base(_ctx)
{
Range = 14;
FirstLength = 10;
AvgTrueRange.value1 = 1;
}
private IOrderMarket buy_order;
public int Range { get; set; }
public double FirstLength { get; set; }
public int AvgTrueRange.value1 { get; set; }
private double FirstAverage()
{
if (AverageTrueRange < AvgTrueRange.value1)
return FirstLength;
}
protected override void Create()
{
// create variable objects, function objects, order objects
buy_order = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.Buy));
}
protected override void StartCalc()
{
// assign inputs
}
protected override void CalcBar()
{
// strategy logic
if (Bars.CurrentBar > 1)
{
switch (FirstAverage)
{
case FirstLength:
return 1;
}
}
if (Bars.CurrentBar > 1 && Bars.Close.CrossesOver(FirstAverage, ExecInfo.MaxBarsBack)
{
switch (FirstLength)
{
case 1:
buy_order.Send(Bars.Close[0]);
}
}
}
}
What you need is to make a struct for AvgTrueRange:
public struct Range
{
public int value1 {get; set;}
}
and change:
public int AvgTrueRange.value1 { get; set; }
to
public Range AvgTrueRange { get; set; }
Your code still won't compile btw but I don't really understand what you are trying to do in this line:
if (AverageTrueRange < AvgTrueRange.value1)
Also, change:
switch (FirstAverage)
{
case FirstLength:
return 1;
}
to
var avg = FirstAverage();
int? result = avg switch
{
var avg when avg == FirstLength => 1,
_ => null
};
if (result.HasValue) return result.Value;
as cases can only be constant values.

How to generalize a property pattern

I have classes that has multiple properties which have well-defined name and function but have the same implementation. For example:
class Stats
{
private int attack;
public int Attack
{
get =>
HasBuff ? attack + 1 : attack;
set
{
if (value < 1 || value > 10)
throw new ArgumentOutOfRangeException("Invalid value");
attack = value;
}
}
public int Defense {...}
public int Speed {...}
}
Where Defense and Speed are to be implemented just like Attack . How can I generalize this structure to avoid redundancy and make changes easier?
Make another class to generalize stats:
public class Stat
{
public bool HasBuff { get; set; }
private int _stat;
public int Score
{
get => HasBuff ? _stat + 1 : _stat;
set => _stat = value;
}
}
Then just use that for each of your skills:
public class CombatStats
{
public Stat Attack { get; } = new Stat();
public Stat Defense { get; } = new Stat();
public Stat Speed { get; } = new Stat();
}
Calling code would look like this:
var ninja = new Ninja();
ninja.skills = new CombatStats();
var attackStrength = ninja.skills.Attack.Score;
As further improvement, implicit operators can be used to avoid object creation and call to Score:
public class Stat
{
...
public static implicit operator int(Stat stat)
{
return stat.Score;
}
public static implicit operator Stat(int value)
{
return new Stat()
{
Score = value
};
}
}
This makes the change transparent to client code written w.r.t. to the example in the question:
ninja.skills = new CombatStats(){
Attack = 5,
Defense = 2
}
int attack = ninja.skills.Attack;
One approach to consider:
class Stats
{
// other existing code here
private int defense;
public int Defense
{
get
{
return GetValue(defense);
}
set
{
SetValue(value, ref defense);
}
}
private int GetValue(int value)
{
return HasBuff ? value + 1 : value;
}
private void SetValue(int value, ref int target)
{
if (value < 1 || value > 10)
throw new ArgumentOutOfRangeException("Invalid value");
target = value;
}
}
Attack etc will now be basically the same as Defence but passing in attack rather than defense to GetValue and SetValue.
I would go with composition
Stat:
public class Stats
{
private readonly StatProperty _defense;
private readonly StatProperty _attack;
private readonly StatProperty _speed;
public Stats()
{
_defense = new StatProperty(this);
_attack = new StatProperty(this);
_speed = new StatProperty(this);
}
public int Defense
{
get => _defense.Value;
set => _defense.Value = value;
}
public int Attack
{
get => _attack.Value;
set => _attack.Value = value;
}
public int Speed
{
get => _speed.Value;
set => _speed.Value = value;
}
public bool HasBuff { get; set; }
}
StatProperty:
public class StatProperty
{
public Stats Stats { get; }
public StatProperty(Stats stats)
{
Stats = stats;
}
private int _value = 1;
public int Value
{
get => Stats.HasBuff ? _value + 1 : _value;
set
{
if (value < 1 || value > 10)
throw new ArgumentOutOfRangeException("Invalid value");
_value = value;
}
}
}
I would need more details to know if it is the best option.
you also could make StatProperty as internal if don't want to show it outside of your library or nested private class if you want to use this just on the class Stats

C# - Sort method for class interface object ,error

I am trying to sort list with clubs which have best result, I must use Sort Method, but it shows error, what I am doing wrong. I know it is a problem of Sort method but can't find a mistake, I made it work with lambda expression but I want to do it with sort method;
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// class with objects
Club barca = new Club("Barcelona", 1900, 100, 20);
Club Real = new Club("Real", 1910, 80, 70);
Club Manchester = new Club("Manchester", 1890, 75, 55);
Club Milan = new Club("Milan", 1880, 45, 65);
//new list of clubs
var myclublist = new List<IClub>();
///add clubs in list
myclublist.Add(barca);
myclublist.Add(Real);
myclublist.Add(Manchester);
myclublist.Add(Milan);
// sort method for list
myclublist.Sort();
//show clubs name with best results
foreach (var item in myclublist)
{
if (item.IsPositiveBallRatio() == true)
{
Console.WriteLine(item.ClubName());
}
}
}
// club class
public class Club : IClub, IComparable<Club>
{
public string Name { get; set; }
public int Year { get; set; }
public int Scoredgoals { get; set; }
public int Lossgoals { get; set; }
public Club(string name, int year, int scoredgoals, int lossgoals)
{
Name = name;
Year = year;
Scoredgoals = scoredgoals;
Lossgoals = lossgoals;
}
public int BallRatio()
{
int ratio;
ratio = Scoredgoals - Lossgoals;
return ratio;
}
public bool IsPositiveBallRatio()
{
if (Scoredgoals > Lossgoals)
{
return true;
}
else
return false;
}
public string ClubName()
{
string n;
n = Name;
return n;
}
public int CompareTo(Club other)
{
return BallRatio().CompareTo(other.BallRatio());
}
}
// inferface for club class
interface IClub
{
int BallRatio();
bool IsPositiveBallRatio();
string ClubName();
}
}
what I am doing wrong?
Why: IClub is not comparable to itself and there is no other information about the type available to the code at run-time for generic method. So it falls back to non-generic version of IComparable which is not implemented by your Club type.
Fixes:
either use list of Club instead of List<IClub> as Club is comparable to itself
implement non-generic IComparable on the Club:
public class Club : IClub, IComparable<Club> , IComparable
{
...
public int CompareTo(object obj)
{
return CompareTo(obj as Club);
}
}
make type you have in the list (IClub) to be comparable to itself - IClub : IComparable<IClub> to fix the issue if you really expect mixed IClub implementations in the array:
public class Club : IClub, IComparable<Club>
{
...
public int CompareTo(IClub other)
{
return CompareTo(other as Club);
}
}
public interface IClub : IComparable<IClub> {...}
See List.Sort for details.
Note: CompareTo in this post are sample-only and you need to add all type/null checks for them to work in real code.

Stop Resharper from changing "from" to "#from"

I have many methods that have a parameter called from. If I do some refactoring to such a method, R# decides to change the from to #from. But both the compiler and I are happy with from and we don't want this change. I can't find any way to suppress it.
Example method:
public class ObjectA
{
public int J { get; set; }
public int K { get; set; }
}
public class ObjectB
{
public int Y { get; set; }
public int Z { get; set; }
}
public static ObjectB ConvertAtoB(ObjectA from)
{
return from != null
? new ObjectB
{
Y = from.J,
Z = from.K,
}
: null;
}
After invert condition twice on the if statement, the method looks like this:
public static ObjectB ConvertAtoB(ObjectA from)
{
return #from != null
? new ObjectB
{
Y = #from.J,
Z = #from.K,
}
: null;
}
Is there any R# setting that will prevent this?

Categories

Resources