-2
\$\begingroup\$

I have an abstract class Player, which plays several games of Roulette (samples). For each game, the desired player is cloned into a session method.

for (int i = 0; i < samples; i++)
{
    IList<int> sessionStakes = this.Session(player.DeepClone() as Player);
    this.maxima.Add(sessionStakes.DefaultIfEmpty(0).Last());
    this.durations.Add(sessionStakes.Count);
}

This clone method is used in Player like so:

public virtual Player DeepClone()
{
    return this.MemberwiseClone() as Player;
}

And for specific implementations of Player, I have additional information such as a list of bet values:

public IList<int> betValues;
public CancellationPlayer(int startingMoney, Table table, int numberOfRounds) : base(startingMoney, table, numberOfRounds)
{          
    betValues = new List<int> { 1, 2, 3, 4, 5, 6 };
    bet = new Bet(this, betValues.First() + betValues.Last(), table.GetOutcome("Black"));
}

I need to override the DeepClone() method to reset this value as values are added and removed during play - I need a fresh Player for each "Session".

public override Player DeepClone()
{
    this.betValues = new List<int> { 1, 2, 3, 4, 5, 6 };
    return base.DeepClone();
}

I'm just wondering if there are any comments on the best way of handling cloning. I've never really come across cloning before and something about this seems really off, especially when child classes aren't forced to implement DeepClone() it may seem like it's doing something it's not.

EDIT: Here is a link to the full project https://drive.google.com/open?id=0Bz-njBI20A1tSXc5anVVbXVoSTQ.

The reason I'm cloning is because Simulator takes a player and then need to create a new player for each session but I'm not sure how to do that without putting the Gather() logic in the main Program below.

Random random = new Random();
Wheel wheel = new Wheel(random);
Table table = new Table(wheel, 1, 50000);
RouletteGame rg = new RouletteGame(wheel, table);
Player player = new CancellationPlayer(100, table, 250);
Simulator simulator = new Simulator(rg, player, 50);

var lists = simulator.Gather();
foreach (var session in lists.First().Zip(lists.ElementAt(1), (first, second) => string.Format("Ending Value: {0}, Duration: {1}", first, second)))
    Console.WriteLine(session.ToString());

Console.Read();
\$\endgroup\$
  • 2
    \$\begingroup\$ Cloning a Player like that feels like a very weird thing to do. Why don't you post all of your program for review instead of asking this question with decontextualized excerpts, so that we can advise you properly? \$\endgroup\$ – 200_success Jun 9 '16 at 16:36
  • 2
    \$\begingroup\$ I agree with @200_success - very strange implementation. Also, Object.MemberwiseClone() performs a shallow copy - so method name DeepClone() is misleading. \$\endgroup\$ – CoolBots Jun 9 '16 at 17:48
  • \$\begingroup\$ Thanks, I've edited the main post with the project and reasons I was thinking at the time. \$\endgroup\$ – Nick Spicer Jun 10 '16 at 8:21
  • \$\begingroup\$ Please follow the tour and read "How do I ask a good question?", "What topics can I ask about here?" and "What types of questions should I avoid asking?". Including a link to your project on Google Drive isn't according to our rules. \$\endgroup\$ – BCdotWEB Jun 10 '16 at 8:25
  • \$\begingroup\$ @BCdotWEB I can't see any documentation on not including Google Drive can you be more specific or suggest an alternative? \$\endgroup\$ – Nick Spicer Jun 10 '16 at 8:33
1
\$\begingroup\$

What you ought to do is make a copy constructor, then have the "clone" method return a new Player or new CancellationPlayer. That way both internal state is preserved, but simulations are possible.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.