    Solutions to Project 2
  Feel free to post your source code or links to source code for project 2 in this thread.Cheers!   
  I've been in China for the past 3 weeks moving my family from the states so I honestly haven't had as much time as I would like to complete this project, but I was able to get all the non-optional parts completed. I'm working on the optional stuff now, but it won''t be finished before the project is due. Here is what I got:Main Program:namespace CharacterGenerator{    class Program    {   static void Main(string[] args)   {  Console.Title = "Random Character Generator";  System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\Documents and Settings\onufert\My Documents\Visual Studio 2005\Projects\CharacterGenerator\CharacterGenerator\IntroArt.txt");  string introArt = sr.ReadToEnd();  Console.Write(introArt + "\r\n");  RandomCharacter randomCharacter = new RandomCharacter();  bool repeat = true;  while (repeat)  { Character character = new Character(); character.Name = GetName(); character.Gender = GetGender(); character.Race = GetRace(); character.Class = GetClass(); character.Level = GetLevel(); randomCharacter.GenerateCharacter(ref character); CharacterDisplay.DisplayCharacter(character); repeat = GetRepeatFlag(); Console.Clear();  }   }   static bool GetRepeatFlag()   {  bool repeatGame;  bool run = false;  string response;  Console.Write("Would you like to generate another character? ");  do  { Console.Write("Enter [y]es or [n]o: "); response = Console.ReadLine(); response = response.ToLower(); if (response == "n" || response == "no" || response == "y" || response == "yes") {if (response.StartsWith("n")){    run = false;}else if (response.StartsWith("y")){    run = true;}repeatGame = false; } else {Console.Write("Incorrect response! ");repeatGame = true; }  } while (repeatGame);  return (run);   }   static string GetName()   {  Boolean repeat = false;  string name;   do  { Console.Write("Character's Name: "); name = Console.ReadLine(); if (name.ToLower() == "help") {Console.WriteLine("Naming rules:");Console.WriteLine("1) Limit of 25 characters.");Console.WriteLine(@"2) A name can consist of only letters, apostrophes (\') and hyphens (-).");Console.WriteLine("3) Only single hyphens, apostrophes and spaces are allowed.");repeat = true; } else if (CheckName(name)) {name = FormatName(name);return (name); } else {Console.WriteLine("Invalid name! Type \'help\' for naming rule. ");repeat = true; }  } while (repeat);  return (name);   }   static bool CheckName(string name)   {  bool nameValid = true;    if (name.Length > 26)  { nameValid = false; return (nameValid);  }  foreach (char c in name)  { if (System.Char.IsLetter(c) || System.Char.IsWhiteSpace(c) || c == Convert.ToChar("'") || c == Convert.ToChar("-")) {nameValid = true;  } else {nameValid = false;return (nameValid); }  }  return (nameValid);   }   static string FormatName(string name)   {  string myName = name;  string formatedName = "";  char testChar1 = Convert.ToChar("-");  char testChar2 = Convert.ToChar("'");  char[] validChars = {testChar1, testChar2};  string[] myNameSub;  myNameSub = myName.Split();  string word = "";  for (int i = 0; i < myNameSub.Length; i++)  { if (!(myNameSub == "")) {if (myNameSub.Contains("-") || myNameSub.Contains("'")){    word = myNameSub;    for(int j = word.IndexOfAny(validChars); j < word.Length - 1; j++)    {   if(word[j] == testChar1 || word[j] == testChar2)   {  if (word[j + 1] == testChar1 || word[j + 1] == testChar2)  { word = word.Remove(j+1,1); j--; }   }    }}word = word + " ";formatedName = formatedName + word;word = ""; }   }  return (formatedName);   }   static CharGender GetGender()   {  Type genders = typeof(CharGender);  Boolean repeat = false;  string input;  do  { Console.Write("Character's Gender: "); input = Console.ReadLine(); if (input.ToLower() == "help") {Console.WriteLine("Available Genders:");foreach (string s in Enum.GetNames(genders)){    Console.WriteLine(s);}repeat = true; } else  {try{    return (CharGender)(Enum.Parse(genders, input, true));}catch{    Console.Write("Invalid Gender! Type \'help\' for available genders. ");    Console.WriteLine();    repeat = true;} }  } while (repeat);  return (0);   }   static CharRace GetRace()   {  Type races = typeof(CharRace);  Boolean repeat = false;  string input;  do  { Console.Write("Character's Race: "); input = Console.ReadLine(); if (input.ToLower() == "help") {Console.WriteLine("Available Races:");foreach (string s in Enum.GetNames(races)){    Console.WriteLine(s);}repeat = true; } else {try{    return (CharRace)(Enum.Parse(races, input, true));}catch{    Console.Write("Invalid Race! Type \'help\' for available races. ");    Console.WriteLine();    repeat = true;} }  } while (repeat);  return (0);   }   static CharClass GetClass()   {  Type classes = typeof(CharClass);  Boolean repeat = false;  string input;  do  { Console.Write("Character's Class: "); input = Console.ReadLine(); if (input.ToLower() == "help") {Console.WriteLine("Available Classes:");foreach (string s in Enum.GetNames(classes)){    Console.WriteLine(s);}repeat = true; } else {try{    return (CharClass)(Enum.Parse(classes, input, true));}catch{    Console.Write("Invalid Class! Type \'help\' for available classes. ");    Console.WriteLine();    repeat = true;} }  } while (repeat);  return (0);   }   static byte GetLevel()   {  byte level = 1;  Boolean repeat = false;  string input;  do  { Console.Write("Character's Level: "); input = Console.ReadLine(); try {level = Convert.ToByte(input);if (level > 0 && level < 21){    repeat = false;}else{    Console.Write("Invalid Level! Please enter a number between 1 and 20: ");    repeat = true;} } catch {Console.Write("Invalid Level! Please enter a number between 1 and 20: ");repeat = true; } Console.WriteLine();  } while (repeat);  return (level);   }    }}RandomCharacter.cs:namespace CharacterGenerator{    class RandomCharacter    {   //static Dice Dice = new Dice();   Character myCharacter = new Character();   public void GenerateCharacter(ref Character character)   {  float weight;  this.myCharacter = character;  myCharacter.Size = GetSize(myCharacter.Race);  myCharacter.Age = GetAge(myCharacter.Race, myCharacter.Class);  myCharacter.Height = GetHeightWeight(myCharacter.Race, myCharacter.Gender, out weight);  myCharacter.Weight = weight;  myCharacter.Hair = GetHair();  myCharacter.Eyes = GetEyes();  myCharacter.Money = GetMoney(myCharacter.Level, myCharacter.Class);  myCharacter.Strength = GetAbility(CharAbilities.Strength, 4, 3, 6, myCharacter.Race);  myCharacter.Dexterity = GetAbility(CharAbilities.Dexterity, 4, 3, 6, myCharacter.Race);  myCharacter.Constitution = GetAbility(CharAbilities.Constitution, 4, 3, 6, myCharacter.Race);  myCharacter.Intelligence = GetAbility(CharAbilities.Intelligence, 4, 3, 6, myCharacter.Race);  myCharacter.Wisdom = GetAbility(CharAbilities.Wisdom, 4, 3, 6, myCharacter.Race);  myCharacter.Charisma = GetAbility(CharAbilities.Charisma, 4, 3, 6, myCharacter.Race);  myCharacter.HitDie = GetHitDie(myCharacter.Class);  myCharacter.MaxHitPoints = GetHitPoints(myCharacter.Level, myCharacter.ConstitutionModifier, myCharacter.HitDie);  myCharacter.CurrentHitPoints = myCharacter.MaxHitPoints;   }   private CharSize GetSize(CharRace race)   {  switch (race)  { case CharRace.Dwarf:return (CharSize.Medium); case CharRace.Elf:return (CharSize.Medium); case CharRace.Gnome:return (CharSize.Small); case CharRace.HalfElf:return (CharSize.Medium); case CharRace.Halfling:return (CharSize.Medium); case CharRace.HalfOrc:return (CharSize.Medium); case CharRace.Human:return (CharSize.Medium); default:return (CharSize.Medium);  }   }   private int GetAge(CharRace race, CharClass charClass)   {  int age = 0;  switch (race)  { case CharRace.Dwarf:age = 40;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(5, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(5, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(5, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(5, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(7, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(7, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(7, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(7, 6);   return (age);    default:   return (age);}#endregion case CharRace.Elf:age = 110;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(10, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(10, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(10, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(10, 6);   return (age);    default:   return (age);}#endregion case CharRace.Gnome:age = 40;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(6, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(9, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(9, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(9, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(9, 6);   return (age);    default:   return (age);}#endregioncase CharRace.HalfElf:age = 20;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(3, 6);   return (age);    default:   return (age);}#endregion case CharRace.Halfling:age = 20;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(2, 4);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(2, 4);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(2, 4);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(3, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(4, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(4, 6);   return (age);    default:   return (age);}#endregion case CharRace.HalfOrc:age = 14;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(1, 4);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(1, 4);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(1, 4);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(2, 6);   return (age);    default:   return (age);}#endregion case CharRace.Human:age = 15;#region Class based age casesswitch (charClass){    case (CharClass.Barbarian):   age += Dice.ThrowDice(1, 4);   return (age);    case (CharClass.Rogue):   age += Dice.ThrowDice(1, 4);   return (age);    case (CharClass.Sorcerer):   age += Dice.ThrowDice(1, 4);   return (age);    case (CharClass.Bard):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Fighter):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Paladin):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Ranger):   age += Dice.ThrowDice(1, 6);   return (age);    case (CharClass.Cleric):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Druid):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Monk):   age += Dice.ThrowDice(2, 6);   return (age);    case (CharClass.Wizard):   age += Dice.ThrowDice(2, 6);   return (age);    default:   return (age);}#endregion default:return (age);  }   }   private CharHeight GetHeightWeight(CharRace race, CharGender gender, out float weight)   {  int inches = 0;  int pounds = 0;  int hDice = 1;  int hSides = 1;  int wDice = 1;  int wSides = 1;  int roll = 0;  CharHeight myHeight = new CharHeight();   switch (race)  { case CharRace.Dwarf:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 3 + 7;    pounds = 100;}else if (gender == CharGender.Male){    inches = 12 * 3 + 9;    pounds = 130;}hDice = 2;hSides = 4;wDice = 2;wSides = 6;break;#endregion case CharRace.Elf:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 4 + 5;    pounds = 80;}else if (gender == CharGender.Male){    inches = 12 * 4 + 5;    pounds = 85;}hDice = 2;hSides = 6;wDice = 1;wSides = 6;break;#endregion case CharRace.Gnome:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 2 + 10;    pounds = 35;}else if (gender == CharGender.Male){    inches = 12 * 3 + 0;    pounds = 40;}hDice = 2;hSides = 4;wDice = 1;wSides = 1;break;#endregion case CharRace.HalfElf:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 4 + 5;    pounds = 80;}else if (gender == CharGender.Male){    inches = 12 * 4 + 7;    pounds = 100;}hDice = 2;hSides = 8;wDice = 2;wSides = 4;break;#endregion case CharRace.Halfling:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 2 + 6;    pounds = 25;}else if (gender == CharGender.Male){    inches = 12 * 2 + 8;    pounds = 30;}hDice = 2;hSides = 4;wDice = 1;wSides = 1;break;#endregion case CharRace.HalfOrc:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 4 + 5;    pounds = 110;}else if (gender == CharGender.Male){    inches = 12 * 4 + 10;    pounds = 150;}hDice = 2;hSides = 12;wDice = 2;wSides = 6;break;#endregion case CharRace.Human:#region Base Height/Weightif (gender == CharGender.Female){    inches = 12 * 4 + 5;    pounds = 85;}else if (gender == CharGender.Male){    inches = 12 * 4 + 10;    pounds = 120;}hDice = 2;hSides = 10;wDice = 2;wSides = 4;break;#endregion  }  roll = Dice.ThrowDice(hDice, hSides);  inches += roll;  myHeight.Feet = (byte)(inches / 12);  myHeight.Inches =(byte)(inches % 12);  pounds += roll * (Dice.ThrowDice(wDice, wSides));  weight = pounds;  return (myHeight);   }   private CharHair GetHair()   {  CharHair hair = new CharHair();  hair = (CharHair)Dice.ThrowDice(1, Enum.GetNames(typeof(CharHair)).Length - 1);  return (hair);   }   private CharEyes GetEyes()   {  CharEyes eyes = new CharEyes();  eyes = (CharEyes)Dice.ThrowDice(1, Enum.GetNames(typeof(CharEyes)).Length - 1);  return (eyes);   }   private CharMoney GetMoney(byte level, CharClass myClass)   {  int mdice = 1;  int sides = 1;  CharMoney money = new CharMoney();  switch (myClass)  { case (CharClass.Barbarian):mdice = 4;sides = 4;break; case (CharClass.Rogue):mdice = 5;sides = 4;break; case (CharClass.Sorcerer):mdice = 3;sides = 4;break; case (CharClass.Bard):mdice = 4;sides = 4;break; case (CharClass.Fighter):mdice = 6;sides = 4;break; case (CharClass.Paladin):mdice = 6;sides = 4;break; case (CharClass.Ranger):mdice = 6;sides = 4;break; case (CharClass.Cleric):mdice = 5;sides = 4;break; case (CharClass.Druid):mdice = 2;sides = 4;break; case (CharClass.Monk):mdice = 5;sides = 4;break; case (CharClass.Wizard):mdice = 3;sides = 4;break;}  int numLevels = 0;  for (int i = 1; i <= level; i++)  { numLevels += (i * mdice);  }  money.Copper = Dice.ThrowDice(numLevels, sides) * 10;  if (myClass == CharClass.Monk)  { money.Copper = money.Copper / 10;  }  money.SortCopper();  return (money);   }   private byte GetAbility(CharAbilities ability, int numRolls, int numToKeep, int diceSides, CharRace race)   {  byte value = 0;  byte[] abilityRolls = new byte[4];  for (int i = 0; i < numRolls; i++)  { abilityRolls = (byte)Dice.ThrowDice(1, diceSides);  }  Array.Sort(abilityRolls);  for (int i = abilityRolls.Length - (abilityRolls.Length - numToKeep); i > 0; i--)  { value += (byte)abilityRolls;  }  value = (byte)((sbyte)value + GetRaceAbility(race, ability));  return (value);   }   private sbyte GetRaceAbility(CharRace race, CharAbilities ability)   {  sbyte value = 0;  switch (race)  { case CharRace.Dwarf:#region Race Specific Ability Modifiersswitch (ability){case CharAbilities.Strength:   value = 0;   break;    case CharAbilities.Dexterity:   value = 0;   break;    case CharAbilities.Constitution:   value = +2;   break;    case CharAbilities.Intelligence:   value = 0;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = -2;   break;    default:   value = 0;   break;}#endregionbreak; case CharRace.Elf:#region Race Specific Ability Modifiersswitch (ability){    case CharAbilities.Strength:   value = 0;   break;    case CharAbilities.Dexterity:   value = 2;   break;    case CharAbilities.Constitution:   value = -2;   break;    case CharAbilities.Intelligence:   value = 0;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = 0;   break;    default:   value = 0;   break;}#endregionbreak; case CharRace.Gnome:#region Race Specific Ability Modifiersswitch (ability){    case CharAbilities.Strength:   value = -2;   break;    case CharAbilities.Dexterity:   value = 0;   break;    case CharAbilities.Constitution:   value = 2;   break;    case CharAbilities.Intelligence:   value = 0;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = 0;   break;    default:   value = 0;   break;}#endregionbreak; case CharRace.HalfElf:#region Race Specific Ability Modifiersswitch (ability){    case CharAbilities.Strength:   value = 0;   break;    case CharAbilities.Dexterity:   value = 0;   break;    case CharAbilities.Constitution:   value = 0;   break;    case CharAbilities.Intelligence:   value = 0;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = 0;   break;    default:   value = 0;   break;}#endregionbreak; case CharRace.Halfling:#region Race Specific Ability Modifiersswitch (ability){    case CharAbilities.Strength:   value = -2;   break;    case CharAbilities.Dexterity:   value = 2;   break;    case CharAbilities.Constitution:   value = 0;   break;    case CharAbilities.Intelligence:   value = 0;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = 0;   break;    default:   value = 0;   break;}#endregionbreak; case CharRace.HalfOrc:#region Race Specific Ability Modifiersswitch (ability){    case CharAbilities.Strength:   value = 2;   break;    case CharAbilities.Dexterity:   value = 0;   break;    case CharAbilities.Constitution:   value = 0;   break;    case CharAbilities.Intelligence:   value = -2;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = -2;   break;    default:   value = 0;   break;}#endregionbreak; case CharRace.Human:#region Race Specific Ability Modifiersswitch (ability){    case CharAbilities.Strength:   value = 0;   break;    case CharAbilities.Dexterity:   value = 0;   break;    case CharAbilities.Constitution:   value = 0;   break;    case CharAbilities.Intelligence:   value = 0;   break;    case CharAbilities.Wisdom:   value = 0;   break;    case CharAbilities.Charisma:   value = 0;   break;    default:   value = 0;   break;}#endregionbreak; default:value = 0;break;  }  return (value);   }   private int GetHitDie(CharClass myClass)   {  int sides = 1;  switch (myClass)  { case (CharClass.Barbarian):sides = 12;break; case (CharClass.Rogue):sides = 6;break; case (CharClass.Sorcerer):sides = 4;break; case (CharClass.Bard):sides = 6;break; case (CharClass.Fighter):sides = 10;break; case (CharClass.Paladin):sides = 10;break; case (CharClass.Ranger):sides = 8;break; case (CharClass.Cleric):sides = 8;break; case (CharClass.Druid):sides = 8;break; case (CharClass.Monk):sides = 8;break; case (CharClass.Wizard):sides = 4;break;  }  return (sides);   }   private int GetHitPoints(int level, sbyte constModifier, int hitDie)   {  int hitPoints = hitDie + constModifier;  for (int i = 1; i < level; i++)  { hitPoints += Dice.ThrowDice(1, hitDie) + constModifier;  }  return (hitPoints);   }    }}Character.cs:namespace CharacterGenerator{    class Character    {   string name;   CharGender gender;   CharRace race;   CharClass charClass;   byte level;   CharSize size;   int age;   CharHeight height;   float weight;   CharEyes eyes;   CharHair hair;   byte strength;   byte dexterity;   byte constitution;   byte intelligence;   byte wisdom;   byte charisma;   byte fortitude;   byte reflex;   byte will;   int maxHitPoints;   int currentHitPoints;   CharMoney money;   int hitDie;   #region Properties   public string Name   {  get  { return (this.name);  }  set  { this.name = value;  }   }   public CharGender Gender   {  get  { return (this.gender);  }  set  { this.gender = value;  }   }   public CharRace Race   {  get  { return (this.race);  }  set  { this.race = value;  }   }   public CharClass Class   {  get  { return (this.charClass);  }  set  { this.charClass = value;  }   }   public byte Level   {  get  { return (this.level);  }  set  { this.level = value;  }   }   public CharSize Size   {  get  { return (this.size);  }  set  { this.size = value;  }   }   public int Age   {  get  { return (this.age);  }  set  { this.age = value;  }   }   public CharHeight Height   {  get  { return (this.height);  }  set  { this.height = value;  }   }   public float Weight   {  get  { return (this.weight);  }  set  { this.weight = value;  }   }   public CharEyes Eyes   {  get  { return (this.eyes);  }  set  { this.eyes = value;  }   }   public CharHair Hair   {  get  { return (this.hair);  }  set  { this.hair = value;  }   }   public CharMoney Money   {  get  { return (this.money);  }  set  { this.money = value;  }   }   public byte Strength   {  get  { return (this.strength);  }  set  { this.strength = value;  }   }   public byte Dexterity   {  get  { return (this.dexterity);  }  set  { this.dexterity = value;  }   }   public byte Constitution   {  get  { return (this.constitution);  }  set  { this.constitution = value;  }   }   public byte Intelligence   {  get  { return (this.intelligence);  }  set  { this.intelligence = value;  }   }   public byte Wisdom   {  get  { return (this.wisdom);  }  set  { this.wisdom = value;  }   }   public byte Charisma   {  get  { return (this.charisma);  }  set  { this.charisma = value;  }   }   public sbyte StrengthModifier   {  get  { return (GetModifier(this.strength));  }  }   public sbyte DexterityModifier   {  get  { return (GetModifier(this.dexterity));  }   }   public sbyte ConstitutionModifier   {  get  { return (GetModifier(this.constitution));  }    }   public sbyte IntelligenceModifier   {  get  { return (GetModifier(this.intelligence));  }    }   public sbyte WisdomModifier   {  get  { return (GetModifier(this.wisdom));  }    }   public sbyte CharismaModifier   {  get  { return (GetModifier(this.charisma));  }    }   public int MaxHitPoints   {  get  { return (this.maxHitPoints);  }  set  { this.maxHitPoints = value;  }   }   public int CurrentHitPoints   {  get  { return (this.currentHitPoints);  }  set  { this.currentHitPoints = value;  }   }   public int HitDie   {  get  { return (this.hitDie);  }  set  { this.hitDie = value;  }   }   public int Fortitude   {  get  { return (SavingThrows.BaseFortitude(this.level,this.charClass) + ConstitutionModifier);  }   }   public int Reflex   {  get  { return (SavingThrows.BaseReflex(this.level, this.charClass) + DexterityModifier);  }   }   public int Will   {  get  { return (SavingThrows.BaseWill(this.level, this.charClass) + WisdomModifier);  }   }   #endregion   private sbyte GetModifier(byte attribute)   {  if (attribute >= 10)  { byte atr = (byte)(attribute - 10); sbyte atrMod = (sbyte)(atr / 2); return (atrMod);  }  else if (attribute < 10)  { byte atr = attribute; sbyte atrMod = (sbyte)(0 - ((9 - atr) / 2 + 1)); return (atrMod);  }  return (0);   }    }CharacterStructs.cs:namespace CharacterGenerator{   struct CharHeight   {  public byte Feet;  public byte Inches;   }   struct CharMoney   {  public int Platinum;  public int Gold;  public int Copper;  public int Silver;  public void SortCopper()  { int copper = this.Copper; if (copper >= 1000) {this.Platinum = copper / 1000;copper -= this.Platinum * 1000; } if (copper >= 100) {this.Gold = copper / 100;copper -= this.Gold * 100; } if (copper >= 10) {this.Silver = copper / 10;copper -= this.Silver * 10; } this.Copper = copper;  }   }}CharacterEnumerations.cs:namespace CharacterGenerator{    public enum CharGender    {   Male,   Female,    }    public enum CharRace    {   Human,   Dwarf,   Elf,   Gnome,   HalfElf,   HalfOrc,   Halfling,    }    public enum CharClass    {   Barbarian,   Bard,   Cleric,   Druid,   Fighter,   Monk,   Paladin,   Ranger,   Rogue,   Sorcerer,   Wizard,    }    public enum CharSize    {   Small,   Medium,    }    public enum CharEyes    {   Brown,   Hazel,   Amber,   Green,   Blue,   Gray    }    public enum CharHair    {   Brown,   Mahogany,   Chocolate,   Cinnamon,   Chestnut,   Black,   Raven,   Ebony,   Charcoal,   Blonde,   Honey,   Golden,   Strawberry,   Platinum,   Red,   Auburn,   Russet,   Scarlet,   White,   Gray,   Silver    }    public enum CharAbilities    {   Strength,   Dexterity,   Constitution,   Intelligence,   Wisdom,   Charisma    }}SavingThrows.cs:namespace CharacterGenerator{    class SavingThrows    {   static private byte[] sequence2 = new byte[] { 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12 };   static private byte[] sequence1 = new byte[] { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, };   static public byte BaseFortitude(int level, CharClass myClass)   {  byte value = 0;  switch (myClass)  { case (CharClass.Barbarian):value = sequence2[level - 1];break; case (CharClass.Rogue):value = sequence1[level - 1];break; case (CharClass.Sorcerer):value = sequence1[level - 1];break; case (CharClass.Bard):value = sequence1[level - 1];break; case (CharClass.Fighter):value = sequence2[level - 1];break; case (CharClass.Paladin):value = sequence2[level - 1];break; case (CharClass.Ranger):value = sequence2[level - 1];break; case (CharClass.Cleric):value = sequence2[level - 1];break; case (CharClass.Druid):value = sequence2[level - 1];break; case (CharClass.Monk):value = sequence2[level - 1];break; case (CharClass.Wizard):value = sequence1[level - 1];break;  }  return (value);   }   static public byte BaseReflex(int level, CharClass myClass)   {  byte value = 0;  switch (myClass)  { case (CharClass.Barbarian):value = sequence1[level - 1];break; case (CharClass.Rogue):value = sequence2[level - 1];break; case (CharClass.Sorcerer):value = sequence1[level - 1];break; case (CharClass.Bard):value = sequence2[level - 1];break; case (CharClass.Fighter):value = sequence1[level - 1];break; case (CharClass.Paladin):value = sequence1[level - 1];break; case (CharClass.Ranger):value = sequence2[level - 1];break; case (CharClass.Cleric):value = sequence1[level - 1];break; case (CharClass.Druid):value = sequence1[level - 1];break; case (CharClass.Monk):value = sequence2[level - 1];break; case (CharClass.Wizard):value = sequence1[level - 1];break;  }  return (value);   }   static public byte BaseWill(int level, CharClass myClass)   {  byte value = 0;  switch (myClass)  { case (CharClass.Barbarian):value = sequence1[level - 1];break; case (CharClass.Rogue):value = sequence1[level - 1];break; case (CharClass.Sorcerer):value = sequence2[level - 1];break; case (CharClass.Bard):value = sequence2[level - 1];break; case (CharClass.Fighter):value = sequence1[level - 1];break; case (CharClass.Paladin):value = sequence1[level - 1];break; case (CharClass.Ranger):value = sequence1[level - 1];break; case (CharClass.Cleric):value = sequence2[level - 1];break; case (CharClass.Druid):value = sequence2[level - 1];break; case (CharClass.Monk):value = sequence2[level - 1];break; case (CharClass.Wizard):value = sequence2[level - 1];break;  }  return (value);   }    }}Dice.csnamespace CharacterGenerator{    class Dice    {   static Random randomNum = new Random();   public static int ThrowDice(int numberDice, int diceSides)   {  int roll = 0;  for (int i = 0; i < numberDice; i++)  { roll += randomNum.Next(1 , diceSides + 1);  }  return (roll);   }    }}CharacterDisplay.cs:namespace CharacterGenerator{    static class CharacterDisplay    {   static Character myCharacter = new Character();   public static void DisplayCharacter(Character character)   {  myCharacter = character;  Console.WriteLine();  Console.WriteLine("Name:    {0}", myCharacter.Name);  Console.WriteLine("Gender:  {0}", myCharacter.Gender);  Console.WriteLine("Race:    {0}", myCharacter.Race);  Console.WriteLine("Class:   {0}", myCharacter.Class);  Console.WriteLine("Level:   {0}", myCharacter.Level);  Console.WriteLine("Size:    {0}", myCharacter.Size);  Console.WriteLine("Age:{0}", myCharacter.Age);  Console.WriteLine("Height:  {0}' {1}''", myCharacter.Height.Feet, myCharacter.Height.Inches);  Console.WriteLine("Weight:  {0}lbs", myCharacter.Weight);  Console.WriteLine("Eyes:    {0}", myCharacter.Eyes);  Console.WriteLine("Hair:    {0}", myCharacter.Hair);  Console.WriteLine("Money:   {0} Platinum, {1} Gold, {2} Silver, {3} Copper", myCharacter.Money.Platinum, myCharacter.Money.Gold, myCharacter.Money.Silver, myCharacter.Money.Copper);  Console.WriteLine("Strength:{0}", myCharacter.Strength);  Console.WriteLine("StrengthMod:  {0}", myCharacter.StrengthModifier);  Console.WriteLine("Dexterity:    {0}", myCharacter.Dexterity);  Console.WriteLine("DexterityMod: {0}", myCharacter.DexterityModifier);  Console.WriteLine("Constitution: {0}", myCharacter.Constitution);  Console.WriteLine("ConstMod:{0}", myCharacter.ConstitutionModifier);  Console.WriteLine("Intelligence: {0}", myCharacter.Intelligence);  Console.WriteLine("IntelMod:{0}", myCharacter.IntelligenceModifier);  Console.WriteLine("Wisdom:  {0}", myCharacter.Wisdom);  Console.WriteLine("WisdomMod:    {0}", myCharacter.WisdomModifier);  Console.WriteLine("Charisma:{0}", myCharacter.Charisma);  Console.WriteLine("CharismaMod:  {0}", myCharacter.CharismaModifier);  Console.WriteLine("MaxHitPoints: {0}", myCharacter.MaxHitPoints);  Console.WriteLine("CurrentHitPts:{0}", myCharacter.CurrentHitPoints);  Console.WriteLine("Fortitude:    {0}", myCharacter.Fortitude);  Console.WriteLine("Reflex:  {0}", myCharacter.Reflex);  Console.WriteLine("Will:    {0}", myCharacter.Will);   }    }}I saved the intro art into a text file that I parse and display, this way I can put any art I want into the program by replacing the text file. I never quite figured out how to specify the file as part of the project, the only way I could find it was to put the actual path of the file on my computer.IntroArt.txt:;Quote:Original post by Rule3o3I've been in China for the past 3 weeks moving my family from the states so I honestly haven't had as much time as I would like to complete this project, but I was able to get all the non-optional parts completed. I'm working on the optional stuff now, but it won''t be finished before the project is due. Here is what I got:Main Program:*** Source Snippet Removed ***RandomCharacter.cs:*** Source Snippet Removed ***Character.cs:*** Source Snippet Removed ***CharacterStructs.cs:*** Source Snippet Removed ***CharacterEnumerations.cs:*** Source Snippet Removed ***SavingThrows.cs:*** Source Snippet Removed ***Dice.cs*** Source Snippet Removed ***CharacterDisplay.cs:*** Source Snippet Removed ***I saved the intro art into a text file that I parse and display, this way I can put any art I want into the program by replacing the text file. I never quite figured out how to specify the file as part of the project, the only way I could find it was to put the actual path of the file on my computer.IntroArt.txt:I am still working then mine (school started!!!), but I think you should be fine if you just put the text file in with the .exe; CharGen.zipIncluded is a largely step by step, test first approach description of how I approached the problem, though the description is pretty rough. HTML format; uses NUnit.   ;  Overachiever. [lol];Quote:Original post by SiCrane CharGen.zipIncluded is a largely step by step, test first approach description of how I approached the problem, though the description is pretty rough. HTML format; uses NUnit.SiCrane,This is great! Thank you for taking the time to write your steps out. Quite a few "light-bulb" moments and "Wows!" I also love the use of your unittest approach. Good stuff. Thanks again!-Rule ;Quote:Original post by JWalshOverachiever. [lol]Damn straight. So what's happening with Project 3? Seeing as its deadline has already passed....   ;  I've got a milestone this weekend.  =(  I'll post project 3 this Sunday.  That gives people a little bit more time to finish project 2, and gives me a reprieve at the same time.Cheers!   ;Quote:Original post by JWalshI've got a milestone this weekend.  =(  I'll post project 3 this Sunday.  That gives people a little bit more time to finish project 2, and gives me a reprieve at the same time.Cheers!My implementation has growing a lot - and I have no idea when I'll will finish. I will try to NOT add Lua scripting (that how I first intended to implement the various spell effects and special abilities). Hopefully, project 3 will use either the character generation OR the maze generation OR some basic gameplay using the generated character, so I'll be able to use what i'm doing right now [smile].   ;  Okay I have finally completed all the basic functionality that the generator needs to provide for this project. Heres the source:The structs I used:    struct Height    {   public int feet;   public int inches;   public Height(int f, int i)   {  feet = f;  inches = i;   } //possible problem if user constructs height like  Height height = new Height(6, 15);   //maybe restrict to 12 or convert within constructor   public static int ToInches(Height height)   {  int feetAsInches = height.feet * 12;  int inches = feetAsInches + height.inches;  return inches;   }   public static Height ToFeet(int inches)   {  Height height;  int feet = inches / 12;  int inch = inches % 12;  height.feet = feet;  height.inches = inch;  return height;   }   public override string ToString()   {  string str = "";  str = str + feet + "ft'" + inches;  return str;   }    }    struct Money    {   public int platinum;   public int gold;   public int silver;   public int copper;   public Money(int pla, int gol, int sil, int cop)   {  platinum = pla;  gold = gol;  silver = sil;  copper = cop;   }   public static Money Sort(Money amount)   {  Money money = amount;  int tempSilver;  int tempGold;  int tempPlatinum;  tempSilver = money.copper / 10;  money.copper -= tempSilver * 10;  money.silver += tempSilver;  tempGold = money.silver / 10;  money.silver -= tempGold * 10;  money.gold += tempGold;  tempPlatinum = money.gold / 10;  money.gold -= tempPlatinum * 10;  money.platinum += tempPlatinum;  return money;   }   public override string ToString()   {  string str = platinum + "pp " + gold + "gp " + silver + "sp " + copper + "cp";  return str;   }    }    struct Abilities    {   public int strength;   public int dexterity;   public int constitution;   public int intelligence;   public int wisdom;   public int charisma;    }    struct SThrows    {   public int fortitude;   public int reflex;   public int will;    }The race class(RaceDef)abstract class RaceDef    {   public abstract int RandomAge(Class type);   public abstract Height RandomHeight(Gender gen);   public abstract float RandomWeight(Height playerHeight, Gender gen);   public abstract Size Size();   public abstract Abilities RandomAbilities();   public EyeColour RandomEyeColour()   {  int numEnum = Enum.GetValues(typeof(EyeColour)).Length;  Random rand = new Random();  EyeColour colour = (EyeColour)rand.Next(numEnum);  return colour;   }   public HairColour RandomHairColour()   {  int numEnum = Enum.GetValues(typeof(HairColour)).Length;  Random rand = new Random();  HairColour colour = (HairColour)rand.Next(numEnum);    return colour;   }   private int BestRolls()   {  int[] iArray = new int[4];  for (int i = 0; i < 4; i++)  { iArray = Dice.Roll(1, 6);  }  Array.Sort(iArray);  int total = 0;  for (int i = iArray.Length - 1; i > 0; i--) total += iArray;  return total;   }   public void InitAbilities(ref Abilities abilities)   {  abilities.strength = BestRolls();  abilities.dexterity = BestRolls();  abilities.constitution = BestRolls();  abilities.intelligence = BestRolls();  abilities.wisdom = BestRolls();  abilities.charisma = BestRolls();  //Console.WriteLine("str: {0}, dex: {1}, con: {2}, int: {3}, wis: {4}, cha: {5}", abilities.strength,  //    abilities.dexterity, abilities.constitution, abilities.intelligence, abilities.wisdom, abilities.charisma);    }   public static RaceDef human = new Human();   public static RaceDef dwarf = new Dwarf();   public static RaceDef elf = new Elf();   public static RaceDef gnome = new Gnome();   public static RaceDef halfelf = new HalfElf();   public static RaceDef halforc = new HalfOrc();   public static RaceDef halfling = new Halfling();    }    class Human : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "1d4", "1d6", "2d6", "2d6", "1d6", "2d6", "1d6", "1d6", "1d4", "1d4", "2d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 15 + Dice.Roll(numDie, dieSize);  return age;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(4, 10);  Height fHeight = new Height(4, 5);  int inches = Dice.Roll(2, 10);   Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH += inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);    int weight;  int diceRoll = Dice.Roll(2, 4);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(4, 10)); int eWeight = (inches - sInches) * diceRoll; weight = 120 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(4, 5)); int eWeight = (inches - sInches) * diceRoll; weight = 85 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Medium;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  //no changes needed  return abilities;   }    }    class Dwarf : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "3d6", "5d6", "7d6", "7d6", "5d6", "7d6", "5d6", "5d6", "3d6", "3d6", "7d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 40 + Dice.Roll(numDie, dieSize);  return age;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(3, 9);  Height fHeight = new Height(3, 7);  int inches = Dice.Roll(2, 4);  Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH += inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);  int weight;  int diceRoll = Dice.Roll(2, 6);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(3, 9)); int eWeight = (inches - sInches) * diceRoll; weight = 130 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(3, 7)); int eWeight = (inches - sInches) * diceRoll; weight = 100 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Medium;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  abilities.constitution += 2;  abilities.charisma -= 2;  return abilities;   }    }    class Elf : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "4d6", "6d6", "10d6", "10d6", "6d6", "10d6", "6d6", "6d6", "4d6", "4d6", "10d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 110 + Dice.Roll(numDie, dieSize);  return age;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(4, 5);  Height fHeight = new Height(4, 5);  int inches = Dice.Roll(2, 6);  Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH +=inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);  int weight;  int diceRoll = Dice.Roll(1, 6);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(4, 5)); int eWeight = (inches - sInches) * diceRoll; weight = 85 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(4, 5)); int eWeight = (inches - sInches) * diceRoll; weight = 80 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Medium;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  abilities.dexterity += 2;  abilities.constitution -= 2;  return abilities;   }    }    class Gnome : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "4d6", "6d6", "9d6", "9d6", "6d6", "9d6", "6d6", "6d6", "4d6", "4d6", "9d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 40 + Dice.Roll(numDie, dieSize);  return age;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(3, 0);  Height fHeight = new Height(2, 10);  int inches = Dice.Roll(2, 4);  Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH += inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);  int weight;  int diceRoll = Dice.Roll(1, 1);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(3, 0)); int eWeight = (inches - sInches) * diceRoll; weight = 40 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(2, 10)); int eWeight = (inches - sInches) * diceRoll; weight = 35 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Small;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  abilities.constitution += 2;  abilities.strength -= 2;  return abilities;   }    }    class HalfElf : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "1d6", "2d6", "3d6", "3d6", "2d6", "3d6", "2d6", "2d6", "1d6", "1d6", "3d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 20 + Dice.Roll(numDie, dieSize);  return 20;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(4, 7);  Height fHeight = new Height(4, 5);  int inches = Dice.Roll(2, 8);  Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH += inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);  int weight;  int diceRoll = Dice.Roll(2, 4);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(4, 7)); int eWeight = (inches - sInches) * diceRoll; weight = 100 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(4, 5)); int eWeight = (inches - sInches) * diceRoll; weight = 80 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Medium;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  //no changes needed  return abilities;   }    }    class HalfOrc : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "1d4", "1d6", "4d6", "4d6", "1d6", "4d6", "1d6", "1d6", "1d4", "1d4", "4d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 14 + Dice.Roll(numDie, dieSize);  return age;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(4, 10);  Height fHeight = new Height(4, 5);  int inches = Dice.Roll(2, 12);  Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH += inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);  int weight;  int diceRoll = Dice.Roll(2, 6);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(4, 10)); int eWeight = (inches - sInches) * diceRoll; weight = 150 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(4, 5)); int eWeight = (inches - sInches) * diceRoll; weight = 110 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Medium;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  abilities.strength += 2;  abilities.intelligence -= 2;  abilities.charisma -= 2;  return abilities;   }    }    class Halfling : RaceDef    {   public override int RandomAge(Class type)   {  string[] ageTable = { "2d4", "3d6", "4d6", "4d6", "3d6", "4d6", "3d6", "3d6", "2d4", "2d4", "4d6" };  string dice = ageTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int age = 20 + Dice.Roll(numDie, dieSize);  return age;   }   public override Height RandomHeight(Gender gen)   {  Height mHeight = new Height(2, 8);  Height fHeight = new Height(2, 6);  int inches = Dice.Roll(2, 4);  Height height;  if (gen == Gender.Male)  { int mH = Height.ToInches(mHeight); mH += inches; height = Height.ToFeet(mH);  }  else  { int fH = Height.ToInches(fHeight); fH += inches; height = Height.ToFeet(fH);  }  return height;   }   public override float RandomWeight(Height playerHeight, Gender gen)   {  int inches = Height.ToInches(playerHeight);  int weight;  int diceRoll = Dice.Roll(1, 1);  if (gen == Gender.Male)  { int sInches = Height.ToInches(new Height(2, 8)); int eWeight = (inches - sInches) * diceRoll; weight = 30 + eWeight;  }  else  { int sInches = Height.ToInches(new Height(2, 6)); int eWeight = (inches - sInches) * diceRoll; weight = 25 + eWeight;  }  return weight;   }   public override Size Size()   {  return CharacterGenerator.Size.Small;   }   public override Abilities RandomAbilities()   {  Abilities abilities = new Abilities();  InitAbilities(ref abilities);  abilities.dexterity += 2;  abilities.strength -= 2;  return abilities;   }    }The Character class:class Character    {   //fields   string name;   Gender gender;   RaceDef race;   Class type;   byte level;    int age;   Height height;   float weight;   EyeColour eyeColour;   HairColour hairColour;   Size size;   Abilities abilities;   SThrows savingThrows;   Money money;   int maxHitPoints;   int currentHitPoints;   //properties -- perhaps make them private to the class   public string Name   {  set  { name = value;  }  get  { return name;  }   }   public Gender Gender   {  set  { gender = value;  }  get  { return gender;  }   }   public RaceDef Race   {  set  { race = value; Age = race.RandomAge(type); EyeColour = race.RandomEyeColour(); HairColour = race.RandomHairColour(); Height = race.RandomHeight(Gender); Weight = race.RandomWeight(Height, Gender); Size = race.Size(); Abilities = race.RandomAbilities();  }  get  { return race;  }   }   public Class Type   {  set  { type = value;  }  get  { return type;  }   }   public byte Level   {  set  { level = value;  }  get  { return level;  }   }   public int Age   {  set  { age = value;  }  get  { return age;  }   }   public Height Height   {  set  { height = value;  }  get  { return height;  }   }   public float Weight   {  set  { weight = value;  }  get  { return weight;  }   }   public EyeColour EyeColour   {  set  { eyeColour = value;  }  get  { return eyeColour;  }   }   public HairColour HairColour   {  set  { hairColour = value;  }  get  { return hairColour;  }   }   public Size Size   {  set  { size = value;  }  get  { return size;  }   }   public Abilities Abilities   {  set  { abilities = value;  }  get  { return abilities;  }   }   public SThrows SavingThrows   {  set  { savingThrows = value;  }  get  { return savingThrows;  }   }   public Money Money   {  set  { money = value;  }  get  { return money;  }   }   public int MaxHitPoints   {  set  { maxHitPoints = value;  }  get  { return maxHitPoints;  }   }   public int CurrentHitPoints   {  set  { currentHitPoints = value;  }  get  { return currentHitPoints;  }   }   //end of properties   private int GoodSave(int level)   {  return 2 + level / 2;   }   private int WeakSave(int level)   {  return level / 3;   }   private int FortSave(Class type, int level)   {  switch (type)  { case Class.Barbarian: case Class.Cleric: case Class.Druid: case Class.Fighter: case Class.Monk: case Class.Paladin: case Class.Ranger:return GoodSave(level); case Class.Bard: case Class.Rogue: case Class.Sorcerer: case Class.Wizard:return WeakSave(level); default:throw new ArgumentException("Invalid class");  }   }   private int RefSave(Class type, int level)    {  switch (type)   { case Class.Bard: case Class.Monk: case Class.Ranger: case Class.Rogue:return GoodSave(level); case Class.Barbarian: case Class.Cleric: case Class.Druid: case Class.Fighter: case Class.Paladin: case Class.Sorcerer: case Class.Wizard:return WeakSave(level); default:throw new ArgumentException("Invalid class");  }   }   private int WillSave(Class type, int level)    {  switch (type)   { case Class.Bard: case Class.Cleric: case Class.Druid: case Class.Monk: case Class.Sorcerer: case Class.Wizard:return GoodSave(level); case Class.Barbarian: case Class.Fighter: case Class.Paladin: case Class.Ranger: case Class.Rogue:return WeakSave(level); default:throw new ArgumentException("Invalid class");  }   }   private SThrows GetSavingThrows(Class type, int level)   {  SThrows save = new SThrows();  save.fortitude = FortSave(type, level);  save.reflex = RefSave(type, level);  save.will = WillSave(type, level);  return save;   }   private Money RandomMoney(Class type, byte level)   {  string[] moneyTable = { "4d4", "4d4", "5d4", "2d4", "6d4", "5d4", "6d4", "6d4", "5d4", "3d4", "3d4" };  string dice = moneyTable[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  int totalLevel = 0;  for (int i = 1; i < (level + 1); i++)  { totalLevel += i;  }  int gold;  if (type != Class.Monk)  { gold = Dice.Roll((totalLevel * numDie), dieSize); gold *= 10;  }  else gold = Dice.Roll((totalLevel * numDie), dieSize);  Money money = new Money(0, gold, 0, 0);    return money;   }   private int GetMaxHitPoints(Class type, int level, int constitution)   {  int mHP = 0;  int conMod = (constitution - 10) / 2;  string[] hitDie = { "1d12", "1d6", "1d8", "1d8", "1d10", "1d8", "1d10", "1d8", "1d6", "1d4", "1d4"};  string dice = hitDie[(int)type];  string[] split = dice.Split('d');  int numDie;  int dieSize;  int.TryParse(split[0], out numDie);  int.TryParse(split[1], out dieSize);  if (level == 1)  { mHP = dieSize + conMod;  }  else  { int rolls = (level - 1); mHP = dieSize + conMod; for (int i = 0; i < rolls; i++) {mHP = mHP + Dice.Roll(numDie, dieSize) + conMod; } if (mHP < 1)mHP = 1;  }  return mHP;   }   public void GenerateRandom(string name, Gender gender, Race race, Class type, byte level)   {  Name = name;  Gender = gender;  switch (race)  { case CharacterGenerator.Race.Human:Race = RaceDef.human;break; case CharacterGenerator.Race.Dwarf:Race = RaceDef.dwarf;break; case CharacterGenerator.Race.Elf:Race = RaceDef.elf;break; case CharacterGenerator.Race.Gnome:Race = RaceDef.gnome;break; case CharacterGenerator.Race.HalfElf:Race = RaceDef.halfelf;break; case CharacterGenerator.Race.HalfOrc:Race = RaceDef.halforc;break; case CharacterGenerator.Race.Halfling:Race = RaceDef.halfling;break;  }  Type = type;  Level = level;  savingThrows = GetSavingThrows(Type, Level);  Money = RandomMoney(Type, Level);  MaxHitPoints = GetMaxHitPoints(Type, Level, abilities.constitution);  CurrentHitPoints = MaxHitPoints;   }   public void DisplayStats()   {  string str = Race.ToString();  string[] strArray = str.Split('.');  string[] stats = {  "Name ",  "Gender ",  "Race ",  "Class ",  "Level ",  "Age ",  "Eye colour ",  "Hair colour ",  "Height ",  "Weight ",  "Size ",  "Strength ",  "Dexterity ",  "Constitution ",  "Intelligence ",  "Wisdom ",  "Charisma ",  "Fortitude ",  "Reflex ",  "Will ",  "Max HP ",  "Current HP ",  "Money "    };  string[] resul = {  Name,  Gender + "",  strArray[strArray.Length - 1],  Type + "",  Level + "",  Age + "",  EyeColour + "",  HairColour + "",  Height + "",  Weight + "lbs",  Size + "\n",  abilities.strength + "",  abilities.dexterity + "",  abilities.constitution + "",  abilities.intelligence + "",  abilities.wisdom + "",  abilities.charisma + "\n",  savingThrows.fortitude + "",  savingThrows.reflex + "",  savingThrows.will + "\n",  MaxHitPoints + "",  CurrentHitPoints + "",  Money + ""    };    int longest = 0;  for (int i = 0; i < stats.Length; i++)  { if (longest < stats.Length)longest = stats.Length;  }  Console.WriteLine("\nStatistics\n");  for (int i = 0; i < stats.Length; i++)  { string pad = new string(' ', longest - stats.Length); Console.WriteLine(stats + pad + ":" + '\t' + resul);  }   }    }and finally main which includes functions(static methods) for getting basic info:class Program    {   static string GetName()   {  string name;  Console.Write("Enter your character name: ");  name = Console.ReadLine();  while (true)  { if (name.Length > 25) {Console.Write("Name is too long. Try again: ");name = Console.ReadLine(); } else {bool valid = true;for(int i = 0; i < name.Length; i++){    if (char.IsDigit(name) || char.IsSymbol(name) || (char.IsPunctuation(name) && name != '-') && (char.IsPunctuation(name) && name != '\''))    {   valid = false;   break;    }}if (!valid){    Console.Write("Only letters,' ', - and ' allowed. Try again: ");    name = Console.ReadLine();}else    break; }  }  //remove multiples  Remove(ref name, ' ');  Remove(ref name, '-');  Remove(ref name, '\'');//maybe make remove a param argument so it can take a array of chars to remove  //Console.WriteLine(name);  //tidy up - remove characters that are allowed but should not next to each other  //remove any unnecessary characters from the start and end of the string  name = name.TrimStart(new char[] { ' ', '-', '\'' });  name = name.TrimEnd(new char[] { ' ', '-', '\'' });  //Console.WriteLine(name);  for (int i = 0; i < name.Length; i++)  { if (char.IsPunctuation(name) || char.IsWhiteSpace(name)) {while (!char.IsLetter(name))<br>{<br>    name = name.Remove(i + <span class="cpp-number">1</span>, <span class="cpp-number">1</span>);<br>}<br> }<br>  }<br><br>  <span class="cpp-keyword">return</span> name;<br>   }<br><br>   <span class="cpp-keyword">static</span> <span class="cpp-keyword">void</span> Remove(ref string str, <span class="cpp-keyword">char</span> ch)<br>   {<br>  <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; str.Length; i++)<br>  {<br> <span class="cpp-keyword">int</span> pos = <span class="cpp-number">0</span>;<br> <span class="cpp-keyword">int</span> length = <span class="cpp-number">0</span>;<br><br> <span class="cpp-keyword">if</span> (i == <span class="cpp-number">0</span> &amp;&amp; str<span style="font-weight:bold;"> == ch)<br> {<br>pos = i;<br><span class="cpp-keyword">int</span> j = i;<br><span class="cpp-keyword">while</span> (j &lt; str.Length &amp;&amp; str[j] == ch)<br>{<br>    length++;<br>    j++;<br>}<br><span class="cpp-keyword">if</span> (length &gt; <span class="cpp-number">1</span>)<br>{<br>    str = str.Remove(pos, length - <span class="cpp-number">1</span>);<br>    i = <span class="cpp-number">0</span>;<br>}<br> }<br> <span class="cpp-keyword">else</span> <span class="cpp-keyword">if</span> (str<span style="font-weight:bold;"> == ch)<br> {<br>pos = i;<br><span class="cpp-keyword">int</span> j = i;<br><span class="cpp-keyword">while</span> (j &lt; str.Length &amp;&amp; str[j] == ch)<br>{<br>    length++;<br>    j++;<br>}<br><br><span class="cpp-keyword">if</span> (length &gt; <span class="cpp-number">1</span>)<br>{<br>    <span class="cpp-comment">//string temp = str.Substring(pos, length);</span><br>    <span class="cpp-comment">//Console.WriteLine("temp:" + temp);</span><br>    str = str.Remove(pos, length - <span class="cpp-number">1</span>);<br>    i = i - (length - <span class="cpp-number">1</span>);<br>}<br> }<br>  }<br>   }<br><br>   <span class="cpp-keyword">static</span> Gender GetGender()<br>   {<br>  string gender;<br><br>  Console.Write(<span class="cpp-literal">"Enter the characters gender(Male or Female): "</span>);<br>  gender = Console.ReadLine();<br><br>  gender = gender.ToLower();<br><br>  <span class="cpp-keyword">while</span> (gender != <span class="cpp-literal">"male"</span> &amp;&amp; gender != <span class="cpp-literal">"female"</span>)<br>  {<br> Console.Write(<span class="cpp-literal">"Please enter a valid gender(Male or Female: "</span>);<br> gender = Console.ReadLine();<br> gender = gender.ToLower();<br>  }<br><br>  Gender gen;<br><br>  <span class="cpp-keyword">if</span> (gender == <span class="cpp-literal">"male"</span>)<br> gen = Gender.Male;<br>  <span class="cpp-keyword">else</span><br> gen = Gender.Female;<br><br>  <span class="cpp-keyword">return</span> gen;<br>   }<br><br>   <span class="cpp-keyword">static</span> Race GetRace()<br>   {<br>  <span class="cpp-keyword">int</span> numEnum = <span class="cpp-keyword">Enum</span>.GetValues(typeof(Race)).Length;<br>  Race race = <span class="cpp-number">0</span>;<br><br>  <span class="cpp-keyword">int</span> longest = race.ToString().Length;<br><br>  <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; numEnum; i++)<br>  {<br> <span class="cpp-keyword">if</span> (longest &lt; race.ToString().Length)<br>longest = race.ToString().Length;<br><br> race++; <br>  }<br><br>  race = <span class="cpp-number">0</span>;<br><br>  Console.WriteLine(<span class="cpp-literal">"Race options:"</span>);<br>  <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; numEnum; i++)<br>  {<br> string pad = <span class="cpp-keyword">new</span> string(' ', longest - race.ToString().Length);<br> Console.Write(race + pad + '\t');<br> race++;<br><br> <span class="cpp-keyword">if</span> (i % <span class="cpp-number">3</span> == <span class="cpp-number">2</span>)<br>Console.WriteLine();<br>  }<br><br>  string[] strArray = <span class="cpp-keyword">new</span> string[numEnum];<br><br>  strArray = <span class="cpp-keyword">Enum</span>.GetNames(typeof(Race));<br><br>  string tempRace;<br>  Console.Write(<span class="cpp-literal">"\nEnter your race: "</span>);<br>  tempRace = Console.ReadLine();<br><br>  <span class="cpp-keyword">while</span> (<span class="cpp-keyword">true</span>)<br>  {<br> <span class="cpp-keyword">bool</span> found = <span class="cpp-keyword">false</span>;<br><br> <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; strArray.Length; i++)<br> {<br><span class="cpp-keyword">if</span> (strArray<span style="font-weight:bold;">.ToLower() == tempRace.ToLower())<br>{<br>    found = <span class="cpp-keyword">true</span>;<br>    <span class="cpp-keyword">break</span>;<br>}<br> }<br><br> <span class="cpp-keyword">if</span> (!found)<br> {<br>Console.Write(<span class="cpp-literal">"Invalid input. Please try again: "</span>);<br>tempRace = Console.ReadLine();<br> }<br> <span class="cpp-keyword">else</span><br> {<br>race = (Race)<span class="cpp-keyword">Enum</span>.Parse(typeof(Race), tempRace, <span class="cpp-keyword">true</span>);<br><span class="cpp-keyword">break</span>;<br> }<br><br>  }<br><br>  <span class="cpp-keyword">return</span> race;<br>   }<br><br>   <span class="cpp-keyword">static</span> <span class="cpp-keyword">Class</span> GetClass()<br>   {<br>  <span class="cpp-keyword">int</span> numEnum = <span class="cpp-keyword">Enum</span>.GetValues(typeof(<span class="cpp-keyword">Class</span>)).Length;<br>  <span class="cpp-keyword">Class</span> type = <span class="cpp-number">0</span>;<br><br>  <span class="cpp-keyword">int</span> longest = type.ToString().Length;<br><br>  <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; numEnum; i++)<br>  {<br> <span class="cpp-keyword">if</span> (longest &lt; type.ToString().Length)<br>longest = type.ToString().Length;<br><br> type++;<br>  }<br><br>  type = <span class="cpp-number">0</span>;<br><br>  Console.WriteLine(<span class="cpp-literal">"Class options:"</span>);<br>  <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; numEnum; i++)<br>  {<br> string pad = <span class="cpp-keyword">new</span> string(' ', longest - type.ToString().Length);<br> Console.Write(type + pad + <span class="cpp-literal">"\t"</span>);<br> type++;<br><br> <span class="cpp-keyword">if</span> (i % <span class="cpp-number">3</span> == <span class="cpp-number">2</span>)<br>Console.WriteLine();<br>  }<br><br>  string[] strArray = <span class="cpp-keyword">new</span> string[numEnum];<br><br>  strArray = <span class="cpp-keyword">Enum</span>.GetNames(typeof(<span class="cpp-keyword">Class</span>));<br><br>  string tempType;<br>  Console.Write(<span class="cpp-literal">"\nEnter your Class: "</span>);<br>  tempType = Console.ReadLine();<br><br>  <span class="cpp-keyword">while</span> (<span class="cpp-keyword">true</span>)<br>  {<br> <span class="cpp-keyword">bool</span> found = <span class="cpp-keyword">false</span>;<br><br> <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; strArray.Length; i++)<br> {<br><span class="cpp-keyword">if</span> (strArray<span style="font-weight:bold;">.ToLower() == tempType.ToLower())<br>{<br>    found = <span class="cpp-keyword">true</span>;<br>    <span class="cpp-keyword">break</span>;<br>}<br> }<br><br> <span class="cpp-keyword">if</span> (!found)<br> {<br>Console.Write(<span class="cpp-literal">"Invalid input. Please try again: "</span>);<br>tempType = Console.ReadLine();<br> }<br> <span class="cpp-keyword">else</span><br> {<br>type = (<span class="cpp-keyword">Class</span>)<span class="cpp-keyword">Enum</span>.Parse(typeof(<span class="cpp-keyword">Class</span>), tempType, <span class="cpp-keyword">true</span>);<br><span class="cpp-keyword">break</span>;<br> }<br><br>  }<br><br>  <span class="cpp-keyword">return</span> type;<br>   }<br><br>   <span class="cpp-keyword">static</span> byte GetLevel()<br>   {<br>  byte level = <span class="cpp-number">0</span>;<br><br>  Console.Write(<span class="cpp-literal">"Enter a level(1 - 20): "</span>);<br>  byte.TryParse(Console.ReadLine(), out level);<br><br>  <span class="cpp-keyword">while</span> (level &lt; <span class="cpp-number">1</span> || level &gt; <span class="cpp-number">20</span>)<br>  {<br> Console.Write(<span class="cpp-literal">"Please enter a value between 1 and 20: "</span>);<br> byte.TryParse(Console.ReadLine(), out level);<br>  }<br><br>  <span class="cpp-keyword">return</span> level;<br>   }  <br><br>   <span class="cpp-keyword">static</span> <span class="cpp-keyword">void</span> Main(string[] args)<br>   {<br>  TextReader tr = <span class="cpp-keyword">new</span> StreamReader(<span class="cpp-literal">"picture.txt"</span>);<br>  Console.Title = <span class="cpp-literal">"Character Generator"</span>;<br>  Console.ForegroundColor = ConsoleColor.Red;<br>  Console.WriteLine(tr.ReadToEnd());<br>  Console.ResetColor();<br>  <br>  string repeat = <span class="cpp-literal">"y"</span>;<br><br>  <span class="cpp-keyword">while</span> (repeat == <span class="cpp-literal">"y"</span>)<br>  {<br> Character player = <span class="cpp-keyword">new</span> Character();<br> string name = GetName();<br> Gender gen = GetGender();<br> Race race = GetRace();<br> <span class="cpp-keyword">Class</span> type = GetClass();<br> byte level = GetLevel();<br><br> player.GenerateRandom(name, gen, race, type, level);<br> player.DisplayStats();<br><br> Console.Write(<span class="cpp-literal">"Create again(y/n): "</span>);<br> repeat = Console.ReadLine();<br>  }<br>   }<br>    }<br>}<br><br></pre></div><!–ENDSCRIPT–><br><br>Finally a few thoughts about the project from myself:<br><br>Initially when I created the character class it consisted of &#111;nly properties - this is because I thought that when ever somebody used the class they would use these properties and fill in the fields themselves, however as the project went &#111;n I realised that this wouldn't be a good idea because sometimes certain fields needed to be filled in before other fields. As a result I decided to give the character class a GenerateRandom method - this brings all control of the creation of a random character under the control of the class creator. After this I added a DisplayStats method which also seemed to me that it should be part of the character class.<br> <br>This makes me think I should either make all the properties private within the character class or have no properties at all, would this be a good idea?<br><br>Also the RaceDef class, I'm not sure if creating this class was a good idea, there is a lot of duplicate code in the various subclasses which I am unhappy with. <br>With the various threads I created regarding this issue(Telestyn if your reading) - is this what I should have been doing?<br>I can't help but feel there is something I'm missing when it comes to creating classes and using them?<br><br>Lastly some of the code in my character class - anything to do with saving throws was taken from SiCranes source code, I think SiCrane implements this in a clever way, my own solution to this would probably to create tables using class and level as indexes to get the correct results - this would be hard coded into the method like most of the other tables in my source code.<br><br>Any feedback would be welcome.