Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution:
An abstract GameObject class


The abtract class GameObject is here:

public enum GameObjectMedium {Paper, Plastic, Electronic}

public abstract class GameObject{

  public abstract int GameValue{
    get;
  }

  public abstract GameObjectMedium Medium{
    get;
  }
}

The class Die specializes the abstract class GameObject:

using System;

public class Die: GameObject {
  private int numberOfEyes;
  private Random randomNumberSupplier; 
  private readonly int maxNumberOfEyes;

  public Die (): this(6){}

  public Die (int maxNumberOfEyes){
    randomNumberSupplier = 
      new Random(unchecked((int)DateTime.Now.Ticks));
    this.maxNumberOfEyes = maxNumberOfEyes;
    numberOfEyes = NewTossHowManyEyes();
  }   
    
  public void Toss (){
    numberOfEyes = NewTossHowManyEyes();
  }

  private int NewTossHowManyEyes (){
    return randomNumberSupplier.Next(1,maxNumberOfEyes + 1);
  }

  public int NumberOfEyes() {
    return numberOfEyes;
  }

  public override String ToString(){
    return String.Format("Die[{0}]: {1}", maxNumberOfEyes, numberOfEyes);
  }

  public override int GameValue{
    get{
      return numberOfEyes;
    }
  }

  public override GameObjectMedium Medium{
    get{
      return 
       GameObjectMedium.Plastic;
    }
  }   

}

Similarly, the class Card specializes the abstract class GameObject:

using System;

public class Card: GameObject{
  public enum CardSuite { spades, hearts, clubs, diamonds };
  public enum CardValue { two = 2, three = 3, four = 4, five = 5, 
                          six = 6, seven = 7, eight = 8, nine = 9,
                          ten = 10, jack = 11, queen = 12, king = 13,
                          ace = 14 };

  private CardSuite suite;
  private CardValue value;

  public Card(CardSuite suite, CardValue value){
    this.suite = suite;
    this.value = value;
  }

  public CardSuite Suite{
    get { return this.suite; }
  }

  public CardValue Value{
    get { return this.value; }
  }

  public override String ToString(){
    return String.Format("Suite:{0}, Value:{1}", suite, value);
  }

  public override int GameValue{
    get { return (int)(this.value); }
  }

  public override GameObjectMedium Medium{
    get{
      return GameObjectMedium.Paper;
    }
  }   
}

Here is the client class, which shows a mixed used of dies and playing cards on the basis of the abstract class GameObject:

using System;
using System.Collections.Generic;

class Client{

  public static void Main(){

    Die d1 = new Die(),
        d2 = new Die(10),
        d3 = new Die(18);

    Card cs1 =  new Card(Card.CardSuite.spades, Card.CardValue.queen),
         cs2 =  new Card(Card.CardSuite.clubs, Card.CardValue.four),
         cs3 =  new Card(Card.CardSuite.diamonds, Card.CardValue.ace);

    List lst = new List();

    lst.Add(d1);  lst.Add(d2);  lst.Add(d3);
    lst.Add(cs1); lst.Add(cs2); lst.Add(cs3);

    foreach(GameObject gao in lst){
      Console.WriteLine("{0}: {1} {2}", 
                        gao, gao.GameValue, gao.Medium); 
    }
  }
}

Only few modifications where necessary in our transition from the interface IGameObject to the abstract class GameObject:

  1. The methods in GameObject must use the modifiers public and abstract.
  2. In Die and Card, the methods GameValue and Medium must override the abstract methods.
  3. We must change the name of the type IGameObject to GameObject in the client program.