Object representation of betting rounds at poker - c#

I'm writing a HandConverter of a poker hand. This is my first project and I'm trying to do it right from the beginning.
I got already the most parts, like lists of players, their position, stack sizes, cards for different boards, what game is being played and so on, but I struggle with the representation of the betting, especially the different raises, bets and multiple calls from the same player.
I found some cases where my naive case based solution does not work, and it's really complicated and I dislike it. As it currently works for NL Hold'em I think I'll have more workarounds to do if I want to implement games like Stud, Razz and so on altough the betting structure is likely the same.
For now I use this representation and I would like to improve especially the Round and Action classes. Do you have some suggestions for me?
public class HandHistory
{
public GameInfo GameInfo;
public TableInfo TableInfo;
public List<Player> Players;
public List<Round> Rounds;
public string rawtext;
public bool withHero;
}
public Round
{
public List<Action> Action;
public string Name;
public decimal Potsize;
public ulong Cards; //usually would have used a custom class,
//but I need them in a ulong mask for some library I use
}
public class Action
{
public Player Player;
public string Type;
public decimal Amount;
}
P.S. I'm also using a List to store the different rounds, is there better way like inheriting the round class for Flop, Turn and River e.g?

Instead of a string for your Action.Type, you could use an enum:
enum BettingAction
{
Check,
Bet,
Call,
Raise,
Fold
}

When you say first project what do you mean? I am guessing you are a student or new to programming.
Under that assumption I would suggest picking something simpler and than a poker hand history. As in game programming it is unreasonable to think on your first shot of programming a game you create the latest Call of Duty. You start with breakout and move up from there.
If you do not wish to start smaller than I suggest never jump into coding. When you do that you will spend more time just spinning your wheels rather than getting something done.
For instance you should first spend time designing what your program will do and what it will not do. Try to be as complete as possible. This can be done from something as complicated using a UML program or as simple as pen and paper.
I would flow out how you want a hand to progress. Information you want to track. Once you really understand this your data structures will start to come to life.
Since you are new to programming, I would start to write proof of concept code. Then move it to your final project. What I mean by proof of concept is code that you are just testing an idea to see how it works. For example, how would hand history work? Can you create some 'mock' history and set them up? Ideally you would unit test, but lets start a little smaller.
It is important to know that you are constructing a program, just like a house. You need to know what you want it to do and not do (blue prints). What each step is. And you build upon other pieces slowly. It is a process that takes time, but in the end is well worth it.

Cards could have a better name, but I am assuming you mean the community cards. I would make it a list of Cards, then the turn and river subclasses would just only ever have one card in the list. I would also suggest representing the cards in a way that makes sense to you and then doing a conversion when you need to interface with the library.

Not really a programming related answer; but the betting styles for Razz or Stud is different from Hold 'em in several ways.
1.) There are no blinds; rather antes
2.) The person opening can either bring-in or complete the bet
3.) There are more rounds of betting
You have a pretty good start. You'd probably want to create a List<Hands> which has List<Rounds> inside it. Otherwise you'll have a huge list of rounds without being able to tell when one hand started/ended and another one began.
I think you probably need to define out your action types, and then things will probably start to fall into place. Here's what I would have for types:
Check
Bet
Fold
Call
Raise (essentially a call and bet)
Might also want to think about implementing something like "Prior Action" on your action class; as each player is reacting to the action before them.
You'd also want to address some nuances of the game; where player a bets 500 and player b goes all in for 250; since except in this instance, the call needs to match the prior bet.

The term Round is a little ambiguous. BettingRound makes it more obvious.
I don't see the need to have cards, name and potsize here. Potsize is a function of the actions and changes throughout the betting round.
Seats represent the game a little better than a list of players does as this allows you to represent the game state (stack sizes etc.) a little more obviously.
I don't see the need to make the flop, river cards explicitly assigned to rounds - just use a list of cards and some conventions. e.g. first three cards = flop... first betting round = flop. Use some extension methods for convenience of referring to the flop for holdem.
Use the ulong version of cards via conversion when you need to use it rather than cluttering your domain model.
This is how I see the model of a particular individual Game (i.e. 1 flop, river, turn etc.). There's still a bunch of work to do to model all games (e.g. limit games use small bet / big bet instead of blinds to define the stakes).
public class Card
{
public Suit Suit;
public Rank Rank;
public ulong ToCardMask();
}
public enum Suit
{
Clubs,
Diamonds,
Hearts,
Spades
}
public enum Rank
{
Ace,
Deuce,
Trey,
//...
Jack,
Queen,
King
}
public class Game
{
public GameInfo GameInfo;
public TableInfo TableInfo;
public List<BettingRound> BettingRounds;
public List<Card> CommunityCards;
public string Rawtext;
public bool WithHero; //??
}
public static class GameExtensions
{
public static BettingRound Flop(this Game game)
{
return game.BettingRounds[0];
}
public static List<Card> FlopCards(this Game game)
{
return game.CommunityCards.Take(3).ToList();
}
}
public class GameInfo
{
public GameType GameType;
public GameBettingStructure BettingStructure; // Limit, PotLimit, NoLimit
public Stakes Stakes; // e.g. { $1, $2 }
public long Id;
public List<Seat> Seats;
}
enum GameType // prob change to a class for extensibility
{
HoldEm,
Razz,
StudHi,
StudHiLo,
OmahaHi,
OmahaHiLo
}
enum GameBettingStructure
{
Limit,
PotLimit,
NoLimit
}
class Stakes // probably needs some tweeking for stud games (e.g. bring-in ...)
{
public Money Ante;
public List<Money> Blinds;
}
public class Seat
{
public Player Player;
public Money InitialStackAmount;
public Money FinalStackAmount; // convienience field can be calculated
public List<Card> Hand;
}
class Money
{
public decimal Amount;
public Unit Unit;
}
enum Unit
{
USD,
EUR,
AUD,
TournamentDollars
}
public class Player
{
public string Name;
}
public class TableInfo
{
public string Name;
}
public class BettingRound
{
public List<BettingAction> BettingActions;
}
public class BettingAction
{
public abstract Money PotSizeAfter();
public byte SeatNumber;
}
public class Fold : BettingAction { }
public class Call : BettingAction { }
public class BringIn : BettingAction { }
public class Complete : BettingAction { }
public class Bet : BettingAction
{
public Money Amount;
}
public class Raise : Bet { }

instead of SubClassing Round into FlopRound TurnRound etc, I would use a Street attribute within round, and within Action as well.
static public enum Street {PREFLOP, FLOP, TURN, RIVER};
...

Related

How do I organize nested classes to be references in Unity?

So I'm working on a game and I'd like some recommendations for how to sort items for easy, legible, coding reference in Unity. I know my current method is flawed, and really I'd just like some guidance.
So what I'm doing is using classes to separate item categories and their items.
For example, here's an idea of a setup for a script :
public class Items {
public class Equipment {
public class Weapons {
public Item Sword = new Item();
Sword.name = "Sword";
Sword.cost = 1;
}
}
}
then a basic Item class for example
public class Item {
public string name;
public int cost;
}
I can tell this is terrible practice, especially based on the problems I've been having, but I like the idea of using a reference like Items.Equipment.Weapons.Sword and I've grown accustomed to using that from an API I previously used.
I'm open to completely changing everything, I just want some tips. Thanks.
I guess my main question is (was), what's the best way to organize nested classes so they can be references from other scripts easily?
The answer I found was that instead of nesting classes, in my case, it's better to use namespaces to separate items into categories. Thanks a million.
I recommend using ScriptableObjects to create your items, armor, and weapons. You'll have to spend an hour or two learning them, but I think you'll be much happier with your design if you go that route.
Think of a ScriptableObject as a set of properties (item name, cost, attack power, defense power, etc.). For each item you have in your game, you create an instance of a ScriptableObject. Those ScriptableObject instances then become assets in your Unity project, just like a prefab or a sprite. That means you can drag them around in your project, and assign them to the fields on your MonoBehaviours. That'll result in you being able to assign equipment to a character by dragging it from your Project view into the Inspector.
Here's an example of how it'll look
Item.cs
public class Item : ScriptableObject
{
public string name;
public int cost;
public Sprite image;
}
Equipment.cs
public class Equipment : Item
{
public Slots slot;
}
public enum Slots
{
Body,
DoubleHanded,
Hands,
Head,
Feet,
Legs,
LeftHand,
RightHand
}
Weapon.cs
// CreateAssetMenu is what lets you create an instance of a Weapon in your Project
// view. Make a folder for your weapons, then right click inside that folder (in the
// Unity project view) and there should be a menu option for Equipment -> Create Weapon
[CreateAssetMenu(menuName = "Equipment/Create Weapon")]
public class Weapon : Equipment
{
public int attackPower;
public int attackSpeed;
public WeaponTypes weaponType;
}
public enum WeaponTypes
{
Axe,
Bow,
Sword
}
Armor.cs
[CreateAssetMenu(menuName = "Equipment/Create Armor")]
public class Armor : Equipment
{
public int defensePower;
}
Now create a bunch of weapons and armor in your project.
One thing that makes ScriptableObjects nice is you can edit them in your Inspector, rather than having to do it through code (although you can do that too).
Now on your "character" MonoBehaviour, add some properties for that character's equipment.
public class Character : MonoBehaviour
{
public Armor bodyArmor;
public Armor headArmor;
public Weapon weapon;
}
Now you can assign your weapons and armor to your character in the Inspector
You'll probably want something more customized to your needs than my example, but those are the basics. I recommend spending some time looking at ScriptableObjects. Read the Unity docs I linked earlier, or watch some videos on YouTube.
One of Unity's strengths is that it lets you do a lot of design and configuration through the editor rather than through code, and ScriptableObjects reinforce that.

Getting typed items from a collection of objects - how to keep track of type?

I instantiate my class firedragon. I store it in a public List collection that holds objects.
List<object> currentEnemies = new List<object>();
I want to grab that list item,
currentEnemies[0]
and convert it back into my class. I just don't know how to do that. Can anyone explain to me how to do that, or a better way to store my data?
NOTE: The reason why I am using a list that holds objects is because I have many different classes that may be stored in the list.
One way of handling this is with pattern matching. You could implement a common handler for currentEnemies like,
foreach (var enemy in currentEnemies)
{
switch (enemy)
{
case FireDragon dragon:
UpdateDragon(dragon);
break;
case Bulbasaur plant:
BeAdorable(plant);
break;
// and so on...
}
}
If you have just a handful of types, and won't have much more in the future (consider this carefully), this isn't too bad, but gets horribly cumbersome quickly.
Ideally, you should look for common elements on your enemies, so that you can simplify this. For example, if you have code that moves the enemy in the world every step, they could all implement a common interface,
interface IMobile
{
(int X, int Y) Move(int x, int y);
int Speed { get; }
}
Then code to handle movement of enemies could be just,
var mobiles = new List<IMobile>();
// then in other code that can access `mobiles`
foreach (var mobile in mobiles)
{
mobile.Move(mobile.Speed);
}
Generally it's a bad idea when you have direct control over the items be inserted and removed from a list to use object as the generic type for a List. It sounds like you're building a game, and if you are I would architect it using interfaces and then use OfType<> quite a bit.
// Anything you want to track in the game
public interface IGameEntity {}
// Anything that opposes a plyaer
public interface IEnemy : IGameObject {}
// Anything used to do Physical Harm
public interface IWeapon : IGameObject {}
// Anything that can be collected for a purpose (wood, gold, etc)
public interface IResource : IGameObject {}
I'm honestly not sure if a red dragon would be much different then a blue dragon, I would assume not so I would just create a Dragon class.
public class Dragon : IEnemy
{
public DragonColor Color { get; set; }
}
public enum DragonColor
{
Red,
}
Then you're list is:
List<IGameEntity> entities;
All dragons are
var dragons = entities.OfType<Dragon>();
I have a feeling you are looking for a solution using composition. Example:
public class Enemies {
public FireDragon TheDraggon { get; set; }
public List<Troll> Trolls { get; set; }
/* other enemies that you need to track */
}
With this approach you do not have to guess or check what type an instance is within the list of objects.

C# / Unity3D - One constructor for all subclasses?

I'm a noob, and a rusty one at that, so bear with me here. I want to make a digital implementation of an old, obscure card game. I have a Card type with properties such as name, rarity, classification, etc. Then there's more specific stuff that not all cards have, such as attack power, resource cost, etc. A fate card doesn't have a power stat, a planet card doesn't have an influence stat, and so forth.
I want to subclass Card out into these various kinds of cards with the appropriate properties that only they have, but I don't want to give up having a single "new Card(string name)" constructor. My idea was to have the Card constructor call a subclass's constructor with arguments for the general properties, but I read that you can't return anything from a constructor other than the type being constructed. Any way to do this cleanly?
If I understand well, what you want to have in the end would be something like this:
Card planetCard = new Card("Planet");
Card fateCard = new Card("Fate");
Your plan of using inheritance won't work this way, as a base class cannot call a constructor of the inherited class from its own costructor. It can only happen the other way around. The two simpler options to solve this would be:
1- Instantiate the propper class as you need it.
Given two classes like this:
public class PlanetCard : Card
{
///--- Attributes of planet here
public PlanetCard() : base("Planet"){}
}
public class FateCard : Card
{
///--- Attributes of fate here
public FateCard() : base("Fate"){}
}
You can now create the cards as follows (which is kind of similar to what you wanted to achieve in the first place):
Card planetCard = new PlanetCard();
Card fateCard = new FateCard();
2- Using Components instead of inheritance.
The use of components instead of inheritance is very common nowadays when it comes to games. The idea is having only one Card class, but each card, depending on what it really is, would have different components to use:
interface IComponent{}
public class PlanetComponent : IComponent
{
///--- Attributes of Planet
}
public class FateComponent : IComponent
{
///--- Attributes of Fate
}
public class Card
{
List<IComponent> components;
public Card(string cardName)
{
///--- Fill components according to the name
}
public T GetComponent<T>()
{
///--- return the component of the type T in the list, or null
}
}
And now you can create cards like in the first place (although the use later will be a bit different):
Card planetCard = new Card("Planet");
Card fateCard = new Card("Fate");
///--- Using the planet card
PlanetComponent planetComp=planetCard.GetComponent<PlanetComponent>();
if (planetComp!=null)
{
///--- you can use here the planet attributes
}
This solution is much more flexible, as it allows you to combine the components at will (you clud have a "FatePlanet" card with both components if you wanted). You will need though, some way of matching the name of the card with the components you want it to have.
Hope it helps!

C#/AS3 How do I create a public global data object that any other object can read, but only certain objects can set?

Here is the conundrum. I have a specific set of state variables that are used in almost every supporting object I have, and I want those variables to be able to be read by any object that needs to read them, but I want to protect them so that only 1 object has the ability to set them.
For example, lets say I am making a poker game. Variables like:
- Minimum Ante
- Maximum Bet
- Maximum Number of Players
- Current GameState (Placing Bets, Shuffling, Dealing, Paying, etc.)
Personally, I prefer small compact component classes, so lets say I have the majority of the poker game logic in 1 controller class, but i have 50 supporting objects that handle everything that isn't the poker game logic itself, such as a PlayerInterface, a graphics controller, 'The Deck' to handle shuffle and deal logic, etc. Alot of my smaller support classes need to see what the minimum ante is, and the current method I am using is for the controller class to pass these variables into the supporting classes as parameters.
The obvious downside to this is I have 50 supporting objects all holding on to their own local variables for minimum ante to hold the same information that I am passing to them from the controller. Wasted parameters, memory, and opens a ton of risk if any of those variables ever get out of sync.
So, how to I make these variables global so everyone can access and read them? The knee jerk reactionary answer is some public static variables, however this presents the problem that anyone could also write to them. Not only do I not want my supporting objects having the power to change the minimum ante without the controller's knowledge, but I also don't want the client shell that holds the poker game to be able to change them without first going through the proper checks contained in the controller.
So what do I do? Someone once mentioned to me the idea of a Singleton, but after plenty of research, most of it a few years old or more, I found about a 50/50 split in the community who say Singletons are a good idea vs those who think they aren't.
If not singletons or statics, then what? I am open to any ideas to research and try out.
Remember, I want any object, anytime, anywhere to be able to GET the data it needs, but only a very specific object to have the ability to SET the data, should it need to change, so that it can filter through the proper checks. By proper checks, I mean for example in the poker game, if a player has the ability to change the Minimum Bet on the table, he should only be able to do so between hands, or before a tournament begins. I don't want him messing with these things during play.
Thanks in advance for any input.
You could use interfaces approach here.
Declare two interfaces as
public interface IReadOnlyAccess
{
int Property{get;}
}
public interface IFullAccess
{
int Property{get;set;}
}
Then your class would implement both interfaces like
public interface MyClass: IReadOnlyAccess, IFullAccess
{
public int Property{get;set;}
}
Then wherever you need full access you get it via IFullAccess, if otherwise - via IReadOnlyAccess.
Make an inner class, it will have access to the main classes private vars:
public class OuterClass
{
public string StringProperty { get; private set; }
public InnerClass CreateInnerClass()
{
InnerClass ic = new InnerClass(this);
return ic;
}
public class InnerClass
{
private OuterClass _outer;
public InnerClass(OuterClass oc)
{
_outer = oc;
}
public string Prop
{
get
{
return _outer.StringProperty ;
}
set
{
_outer.StringProperty = value;
}
}
}
}
So create the main class that most people have readonly access:
var oc = new OuterClass();
oc.StringProperty = "123"; <-- not allowed, is `readonly`
To write to properties, create inner class instance:
var oc = new OuterClass();
var ic = oc.CreateInnerClass();
ic.StringProperty = "123";
Seems like the cleanest, easiest solution is to have everything done in your controller class.
Let's say something like this:
AS3:
//adding the final keyword, locks this class so others can't extent/inherit from it
public final class MyController {
//create a privately scoped var (it can only be accessed in this class)
private var minBet:Number = 0;
//create a public getter that can be read by any class/object
public function get minimumBet():Number {
return minBet;
}
private function set minimumBet(value:Number):void {
//do you checks etc
minBet = value;
}
}
C#
//sealed in C# is the same as final in AS3
public sealed class MyController
{
private float minBet = 0;
public float minimumBet
{
get { return minBet; }
}
}
instanceOfMyController.minBet //will throw an error
instanceOfMyController.minimumBet = 10; //will throw an error
instanceOfMyController.minimumBet //will supply the value of the minBet var
If you're doing a lot cross-language code, consider checking out something like Haxe which can compile out to AS3 or C# with the same code.

Best design pattern for refactoring a class that does calculation based on many parameters

I'm refactoring a set of classes as below which does some price calculations.
the calculation is done based on many parameters.
The code is :
public interface IParcel {
int SourceCode { get; set; }
int DestinationCode { get; set; }
int weight{get;set;}
decimal CalculatePrice();
}
public abstract class GeneralParcel : IParcel {
//implementation of inteface properties
//these properties set with in SourceCode & DestinationCode
//and are used in CalculatePrice() inside classes that inherit from GeneralParcel
protected SourceProvinceCode{get; protected set;}
protected DestinationProvinceCode{get;protected set;}
//private variables we need for calculations
private static ReadOnlyDictionary<int, List<int>> _States_neighboureness;
private static ReadOnlyCollection<City> _Citieslist;
private static ReadOnlyCollection<Province> _Provinceslist;
protected ReadOnlyCollection<City> Citieslist {get { return _Citieslist; }}
protected ReadOnlyCollection<Province> ProvincesList {get { return _Provinceslist; }}
protected ReadOnlyDictionary<int, List<int>> StatesNeighboureness {get {return _States_neighboureness; }}
//constructor code that initializes the static variables
//implementation is in concrete classes
public abstract decimal CalculatePrice();
}
public ExpressParcel : GeneralParcel {
public decimal CalculatePrice() {
//use of those three static variables in calculations
// plus other properties & parameters
// for calculating prices
}
}
public SpecialParcel : GeneralParcel {
public decimal CalculatePrice() {
//use of those three static variables in calculations
// plus other properties & parameters
// for calculating prices
}
}
Right now, the code uses "Strategy pattern" efficiently.
my question is that those three static properties, really are not part of parcel object, they are need only for price calculations, so which design pattern or wrapping(refactoring), is suggested?
Is having another interface as below necessary (& then wrap those static properties inside it?, even make static that class, because it is basically only some calculations), then how to connect it to IParcel?
Doing so, how to implement CalculatePrice() in SpecialParcel & ExpressParcel classes?
public interface IPriceCalculator {
decimal CalculatePrice();
}
EDIT: the above was only a big picture of all system, there is also other consideration that in comments, we discus about them, and i write them here again for clearing things .
there is BulkDiscount for all of ParcelTypes. bulk post happens when customer send more than 10 parcels(or any threshold), also there is special discount when one customer send more than 10 parcel to a unique destination(there is only one receiver). now this type of discounts are managed in each parcel type's CalculatePrice(). even there are discount for blinds for under 7Kg parcels.
also right now there are 3 parceltype, i show only 2 of them here. but we need to add other type in future(TNT & DHL support).
each type has many services that customer can select and pay for it.
for example, sms service or email service & so on.
Personally, while others might say that a Parcel shouldn't know how to calculate its own shipping cost, I disagree. Your design already identifies that there are three different kinds of parcel with three different calculations, so to my (naive?) eyes it's entirely appropriate that the object should have a method e.g. CalculatePrice().
If you really want to go that way, then you'd need two implementations of IParcelPriceCalculator (or whatever you call it) and an abstract factory method on the GeneralParcel to create the concrete ExpressParcelPriceCalculator or SpecialParcelPriceCalculator classes. Which, personally, I'd consider overkill, not least as that code will then be tightly coupled to each GeneralParcel implementation anyway.
I would however consider making the static collections of City and Province public static properties of City and Province respectively. That's just tidier, and it's where I'd expect to find them if I were maintaining the code. StatesNeighbourliness should probably go into Province, or it might even justify its own class.
The way in which you calculate a price for a given parcel is a responsibility that shouldn't belong to a data object.
Given what you've told me, here is how I would implement, to try and account for future considerations:
public interface IParcel {
int SourceCode { get; set; }
int DesinationCode { get; set; }
int Weight { get; set; }
}
public class PricingCondition {
//some conditions that you care about for calculations, maybe the amount of bulk or the date of the sale
//might possibly be just an enum depending on complexity
}
public static class PricingConditions {
public static readonly PricingCondition FourthOfJulyPricingCondition = new PricingCondition();
public static readonly PricingCondition BulkOrderPricingCondition = new PricingCondition();
//these could alternatively come from a database depending on your requirements
}
public interface IParcelBasePriceLookupService {
decimal GetBasePrice(IParcel parcel);
//probably some sort of caching
}
public class ParcelPriceCalculator {
IParcelBasePriceLookupService _basePriceLookupService;
decimal CalculatePrice(IParcel parcel, IEnumerable<PricingCondition> pricingConditions = new List<PricingCondition>()) {
//do some stuff
}
decimal CalculatePrice(IEnumerable<IParcel> parcels, IEnumerable<PricingCondition> pricingConditions = new List<PricingCondition>()) {
//do some stuff, probably a loop calling the first method
}
}
The IPriceCalculator would be best practice for Single Responsibility Principle.
But change the method's signature to decimal CalculatePrice(IParcel parcel);
The method is calling IParcel's CalculatePrice() method to get base price for each parcel.
The advice I'd offer would depend to a degree on how you go about generating and using the Parcel polymorphs. What I mean is, we can't see what criteria are used to determine whether something is "Express" or "Special" and whether those criteria have to do with the properties of the parcel itself or some external factor.
Having said that, I think your intuition is a good one about separating the price calculation from the Parcel object itself. As kmkemp pointed out, a parcel shouldn't be figuring out how to calculate the price of a parcel depending on what type of parcel it is. A parcel is a data transfer/POCO type object, at least as indicated in your giving it a weight, source, etc.
However, I'm not clear on why you're using these interfaces. Don't get me wrong -- interfacing is nice for decoupling and testability, but why is there a parcel interface in addition to an abstract base class with an abstract method. Personally, going on just the information that I have, I'd do this:
public class Parcel
{
int SourceCode { get; set; }
int DestinationCode { get; set; }
int weight { get; set; }
}
public abstract class GeneralCalculator
{
//Statics go here, or you can inject them as instance variables
//and they make sense here, since this is presumably data for price calculation
protected static ReadOnlyDictionary<int, List<int>> _States_neighboureness;
protected static ReadOnlyCollection<City> _Citieslist;
protected static ReadOnlyCollection<Province> _Provinceslist;
//.... etc
public abstract Decimal CalculatePrice(Parcel parcel);
}
public class ExpressCalculator : GeneralCalculator
{
public override decimal CalculatePrice(Parcel parcel)
{
return 0.0M;
}
}
public class SpecialCalculator : GeneralCalculator
{
public override decimal CalculatePrice(Parcel parcel)
{
return 0.0M;
}
}
But, again, I don't know how the parcels are actually being processed. You may need some kind of modification to this concept depending on how you generate and then process the parcels. For instance, if the kind of parcel it is depends on the property values of the parcel, you might want to define a factory method or class that takes a parcel and returns an appropriate instance of the calculator.
But, however you modify it, I'd definitely cast my vote for your thought of decoupling the definition of the parcel from the scheme for calculating its price. Data storage and data processing are separate concerns. I'd also not vote in favor of a static class somewhere containing global settings, but that's my own personal taste -- that kind of thing too easily acquires a setter and becomes a global variable down the road.
Like you say, those static properties aren't really part of the GeneralParcel class. Move them to a static "ListsOfThings" class.
Then you can use code that refers to ListsOfThings.ProvincesList, etc.

Categories