0
Console.WriteLine("Please, choose your weapon. \n1: Glock 18 \n2:");

switch (choice)
{
    case 1:
        Glock18 glock18 = new Glock18() ;
        break;
}


 Console.WriteLine("Let's shoot. Press space to fire and 'r' to reload. ('q' to quit) \n");

while (true)
{
    ConsoleKeyInfo input = Console.ReadKey(true);
    if (char.IsWhiteSpace(input.KeyChar))
    {
        pistol.Shoot();
    }
}

I have to write a program in which I can select a weapon using a switch-case, but the implementation of the specific weapons differ from one another (A glock sounds different and has a different mag size than a desert eagle for instance)

How can I make sure that the shoot and reload methods for each of the weapons are the ones that are being run? I.e. how to save the chosen gun as a variable so that I can run something like currentWeapon.Shoot, which will ensure that it is the weapon currently selected, instead of the pistol.Shoot() method?

Kit
  • 20,354
  • 4
  • 60
  • 103
  • 4
    You need your weapons to implement some kind of shared functionality, either through a base class, or alternatively by implementing an interface. A base class is probably more logical here. Then implement the shared functionality in the base class – Martin Sep 17 '18 at 16:19
  • You've literally just described https://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping – Rotem Sep 17 '18 at 16:19
  • The commenters are right; the whole point of inheritance via subtyping is to *avoid* having to switch on an object's type, but rather to put the logic in the object itself. But that said, I don't think these comments are addressing your concern, which is something I don't quite understand. You're asking something about switch statements; can you be more clear? – Eric Lippert Sep 17 '18 at 16:23

5 Answers5

1

How can I make sure that the shoot and reload methods for each of the weapons are the ones that are being run? I.e. how to save the chosen gun as a variable so that I can run something like currentWeapon.Shoot, which will ensure that it is the weapon currently selected, instead of the pistol.Shoot() method?

In your switch statement assign the weapon that you created to a variable that represents any weapon. That variable has to be of your interface's type.

So, step 1, create the interface for all your weapons (guns). They all operate similarly, but differentiate when fired. This is polymorphism, which is available to you via an interface or an abstract class.

interface IWeapon
{
    void Shoot();
    void Reload();
    bool HasAmmo { get; }
    void MakeClickSound();
}

Then the various classes (implementation up to you):

class BasicPistol : IWeapon { ... }
class Glock18: IWeapon { ... }
class GiganticLaserBlaster: IWeapon { ... }

Then in the "action" code, declare the variable that is of your interface's type. This is the chosen weapon.

IWeapon chosenWeapon;

Assign that variable in your switch statement (a factory would be better here though as some of the other answers say).

switch (choice)
{
    case 1:
        chosenWeapon = new Glock18() ;
        break;
    case 2:
        chosenWeapon = new GiganticLaserBlaster() ;
        break;
    ...
    default:
        chosenWeapon = new BasicPistol();
        break
}

Then do whatever you want with your weapon. You know it's the right method because you have the right weapon.

while (true)
{
    ConsoleKeyInfo input = Console.ReadKey(true);
    if (char.IsWhiteSpace(input.KeyChar))
    {
        if (chosenWeapon.HasAmmo)
            chosenWeapon.Shoot();
        else
           chosenWeapon.MakeClickSound();
    }
    else if (input.KeyChar == 'r')
        chosenWeapon.Reload();
}
Rotem
  • 21,452
  • 6
  • 62
  • 109
Kit
  • 20,354
  • 4
  • 60
  • 103
0

you need to use both, inheritance and polymorphism, so that when you call methods on an object of type base-class ( or interface ), in fact the virtual method of the derived class will be called instead,

see here one of my top answers on the same matter: what's the difference between inheritance and polymorphism?

Davide Piras
  • 43,984
  • 10
  • 98
  • 147
0

I guess that a Glock implements the IPistol interface, am I right? If that's the case, you can do something like that;

IPistol pistol;  

Console.WriteLine("Please, choose your weapon. \n1: Glock 18 \n2:");
            switch (choice)
            {
                case 1:
                    pistol = new Glock18() ;
                    break;
                case 2:
                    pistol = new WaltherP99() ;
                    break;
                default:
                    pistol = new BasicGun() ;
                    break;
            }


            Console.WriteLine("Let's shoot. Press space to fire and 'r' to reload. ('q' to quit) \n");

            while (true)
            {
                ConsoleKeyInfo input = Console.ReadKey(true);
                if (char.IsWhiteSpace(input.KeyChar))
                {
                    pistol.Shoot();
                }
Max
  • 2,529
  • 1
  • 18
  • 29
  • 1
    I note that in your program fragment here there is a code path where `pistol` is not initialized; you might want to set it to null or have a default case. – Eric Lippert Sep 17 '18 at 16:27
  • Thank you. I've made a small edit. This code is far from perfect. It's just to give the OP an idea about how polymorphism works. – Max Sep 17 '18 at 16:33
  • I have tried this approach, but the currentWeapon.Shoot() cannot find the Glock18 value that i have assigned to it in the switch. When trying to call the method, it says "use of unassigned local variable" when hovering over 'currentWeapon' – Lasse Fisker Sep 17 '18 at 16:39
  • Can you please post the entire method? – Max Sep 17 '18 at 17:25
0

You can try to use facotry pattern to provide the Weapon for your code.

create an interface be all Weapons base, there is a method Shoot in the interface.

public interface IWeapon {
    void Shoot();
}

then let Glock18 or others type of weapons implement IWeapon interface and make its own logic in the method.

public class Glock18 : IWeapon
{
    public void Shoot()
    {
        // Do Glock18 shoot thing
    }
}

WeaponFactory provide the weapon produce code creating.

public class WeaponFactory {
    public static IWeapon GetWeapon(int choice)
    {
        IWeapon weapon = null;
        switch (choice)
        {
            case 1:
                weapon = new Glock18();
                break;
        }
        return weapon;
    }
}

then you can get a weapon by the WeaponFactory class, pass which weapon mode did you want.

IWeapon weapon = WeaponFactory.GetWeapon(choice);
D-Shih
  • 44,943
  • 6
  • 31
  • 51
0

Is you code incomplete or is this the actual code?. Because with the provided code you are no getting any input from the user. Try this:

Console.WriteLine("Please, choose your weapon. \n1: Glock 18 \n2:");
string choice = Console.ReadLine();
switch (choice)
{
    case 1:
        Glock18 glock18 = new Glock18() ;
        break;
}
Max
  • 2,529
  • 1
  • 18
  • 29