strategy,pattern

Erhan 8/7/2016 0

Strategy Pattern

C#
Challenge
You are working on a Gaming application. The player can select between two
different guns:
1. Pistol having 5 bullets
2. Grenade Launcher having 20 bullets
In the normal coding scenario, if the gamer changes the gun we have to do lot of if
conditions
in the fire method, in the draw gun method, in the bullet animation methods.
How to do a better approach?
Definition
GoF Definition: "Define a family of algorithms, encapsulate each one, and make
them interchangeable. Strategy lets the algorithm vary independently from clients
that use it"
Implementation
We can avoid the above complications by switching to the Strategy pattern. Our
solution would be: Extract the difference implementations into appropriate classes
and switch between the classes.
Code Explained
The core classes involved are:
. Gamer
. PistolGun implementing IGun
. GrenadeLauncher implementing IGun
Whenever the user changes the gun the Gamer.Gun property is switched between
PistolGun and GrenadeLauncher instances.
Here the IGun interface extracts the part which differs for different guns.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace StrategyPattern.Strategy
{
    public class Gamer
    {
        private Label _bulletsLabel;

        public Gamer(Label bulletsLabel)
        {
            _bulletsLabel = bulletsLabel;
        }

        private IGun _gun;

        public IGun Gun
        {
            get { return _gun; }
            set { _gun = value ; RefreshGunInfo();  }
        }

        private void RefreshGunInfo()
        {
            _gun.Draw();
            ShowBulletsInfo();
        }

        private void ShowBulletsInfo()
        {
            _bulletsLabel.Text = "Bullets: "   _gun.Bullets.ToString();
        }

        public void Fire()
        {
            _gun.Fire();
           
            ShowBulletsInfo();
        }
    }
}

**************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace StrategyPattern.Strategy
{
    public class GrenadeLauncherGun : IGun
    {
        public GrenadeLauncherGun(PictureBox gunBox, PictureBox bulletBox)
        {
            _gunBox = gunBox;
            _bulletBox = bulletBox;
        }

        public void Fire()
        {
            if (_bullets == 0)
            {
                MessageBox.Show("No Ammo!" );
                return;
            }

            _bulletBox.Image = Images.Grenade;
            _bulletBox.Left = _gunBox.Left   _gunBox.Width   5;
            _bulletBox.Top = _gunBox.Top   60;
            _bulletBox.Show();

            for (int i = 1; i <= 18; i  )
            {
                Thread.Sleep(50);
                Application.DoEvents();
                _bulletBox.Left  = _bulletBox.Width / 2;
            }

            _bullets--;

            _bulletBox.Hide();
        }

        public void Draw()
        {
            _gunBox.Image = Images.GrenadeLauncher;

            _gunBox.Width = _gunBox.Image.Width;
            _gunBox.Height = _gunBox.Image.Height;
        }

        public int _bullets = 20;

        public int Bullets
        {
            get
            {
                return _bullets;
            }
            set
            {
                _bullets = value;
            }
        }

        private PictureBox _gunBox;
        private PictureBox _bulletBox;

        public PictureBox GunBox
        {
            get
            {
                return _gunBox;
            }
            set
            {
                _gunBox = value;
            }
        }

        public PictureBox BulletBox
        {
            get
            {
                return _bulletBox;
            }
            set
            {
                _bulletBox = value;
            }
        }
    }
}

*****************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace StrategyPattern.Strategy
{
    public interface IGun
    {
        void Fire();

        void Draw();

        int Bullets { get ; set; }

        PictureBox GunBox { get ; set; }

        PictureBox BulletBox { get ; set; }
    }
}

************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace StrategyPattern.Strategy
{
    public class PistolGun : IGun
    {
        public PistolGun(PictureBox gunBox, PictureBox bulletBox)
        {
            _gunBox = gunBox;
            _bulletBox = bulletBox;
        }

        public void Fire()
        {
            if (_bullets == 0)
            {
                MessageBox.Show("No Ammo!" );
                return;
            }

            _bulletBox.Image = Images.Bullet;
            _bulletBox.Left = _gunBox.Left   _gunBox.Width   5;
            _bulletBox.Top = _gunBox.Top   1;
            _bulletBox.Show();

            for (int i = 1; i <= 20; i  )
            {
                Thread.Sleep(50);
                Application.DoEvents();
                _bulletBox.Left  = _bulletBox.Width / 2;
            }

            _bullets--;

            _bulletBox.Hide();
        }

        public int _bullets = 5;

        public int Bullets
        {
            get
            {
                return _bullets;
            }
            set
            {
                _bullets = value;
            }
        }

        public void Draw()
        {
            _gunBox.Image = Images.Pistol;

            _gunBox.Width = _gunBox.Image.Width;
            _gunBox.Height = _gunBox.Image.Height;
        }

        private PictureBox _gunBox;
        private PictureBox _bulletBox;

        public PictureBox GunBox
        {
            get
            {
                return _gunBox;
            }
            set
            {
                _gunBox = value;
            }
        }

        public PictureBox BulletBox
        {
            get
            {
                return _bulletBox;
            }
            set
            {
                _bulletBox = value;
            }
        }
    }
}

*****************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StrategyPattern.Strategy;

namespace StrategyPattern
{
    public partial class MainForm : Form
    {
        private Gamer _gamer;
        private IList <IGun> _gunList = new List <IGun>();

        private int _index;

        public MainForm()
        {
            InitializeComponent();

            _gunList.Add( new PistolGun (GunBox, BulletBox));
            _gunList.Add( new GrenadeLauncherGun (GunBox, BulletBox));

            _gamer = new Gamer (BulletsLabel);
            _gamer.Gun = _gunList[_index = 0];
        }

        private void ChangeGun_Click(object sender, EventArgs e)
        {
            _index  ;

            if (_index >= _gunList.Count)
                _index = 0;

            _gamer.Gun = _gunList[_index];
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _gamer.Fire();
        }
    }
}

 

Report Bug

Please Login to Report Bug

Reported Bugs

Comments

Please Login to Comment

Comments