1

I'm creating a Battleship Console App. I want the system to pick between a heavy attack or a minor attack at random so the player has a chance at winning and so does the system. Here is my code.

Player and Enemy Health are both set to '30'

 public void eHeavyAttack()
    {
        Console.Clear();
        Random r = new Random();
        int rInt = r.Next(1, 7);
        Player_Health = Player_Health - rInt;
        Console.WriteLine("The enemy has dealt " + rInt + " damage!");
        Console.WriteLine("Your health is now at " + Player_Health + " health!");
        Console.ReadKey();
    }

    public void eMinorAttack()
    {
        Console.Clear();
        Random r = new Random();
        int rInt = r.Next(0, 4);
        Player_Health = Player_Health - rInt;
        Console.WriteLine("The enemy has dealt " + rInt + " damage!");
        Console.WriteLine("Your health is now at " + Player_Health + " health!");

    }
Cole Connelly
  • 333
  • 1
  • 3
  • 7
  • 1
    What's the issue with this code? – Chetan Sep 18 '17 at 23:52
  • No issue I just want to know if there is a way I can make the system randomly pick either one of them. – Cole Connelly Sep 18 '17 at 23:53
  • I note that your existing code is crossing-concerns: your logic that mutates player state (`Player_Health`) is also writing directly to console output - and mutating `Console` global state by using `Console.Clear` - this makes it difficult to reason about your functions. Try to minimize side-effects as much as possible. This will mean your application code will be easily portable to other environments, like a web-application or games-console. – Dai Sep 18 '17 at 23:58
  • I'd generate a random number and use a if statement to call one of your methods, e.g. int rInt = r.Next(1, 10); if (rInt >7) eHeavyAttack(); else eMinorAttack(); I guess you need this random selection to be repetitve, in this case check this https://stackoverflow.com/questions/13695499/proper-way-to-implement-a-never-ending-task-timers-vs-task – 4D1C70 Sep 19 '17 at 00:02
  • Apart from dasblinkenlight and 4D1C70 answers, you should also note that you're creating new instances of `Random` **without providing a seed** which makes it use the system's time as a seed. So if you call one of your attack methods within a short amount of time (e.g. in a for-loop), you'll most likely get the same result from the random. The easiest way to avoid this would be to create one instance of `Random` and reuse it in your methods. – eitamal Sep 20 '17 at 05:18

1 Answers1

3

You can use Random class for that.

First, create and initialize an instance:

Random rnd = new Random();

Then call one of two methods depending on the call to Next:

if (rnd.Next(2) == 1) {
    eMinorAttack();
} else {
    eHeavyAttack();
}

If you want to tilt the probability toward one of two attack types, generate a larger random number, and check it against some boundary at the desired percentage probability. For example, if you want roughly two out of five attacks to be heavy, change the above code as follows:

if (rnd.Next(5) < 3) {
    eMinorAttack();
} else {
    eHeavyAttack();
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523