//Attempt to parse a string into a point.
		public static bool TryParse(string parseString, out SpecialPoint point)
		{
			Match match = Regex.Match(parseString, @"([a-zA-Z])([0-9]+)");

			point = null;

			//Oops, the point isn't in the format I want it in
			if (!match.Success)
				return false;

			//Set up the new point
			int down = int.Parse(match.Groups[2].Value);
			point = new SpecialPoint(match.Groups[1].Value[0], down);

			return true;
		}
		public bool Equals(SpecialPoint otherPoint)
		{
			return otherPoint.across == across && otherPoint.down == down;
		}
		/// <summary>
		/// Return the journal as a nice formatted grid of symbols
		/// </summary>
		/// <param name="simple"></param>
		/// <returns></returns>
		public string AsString(bool simple)
		{
			string output = "*|";

			//The top row of letters to describe the horizontal index
			for (int i = 0; i < CollectionManager.Width; i++)
				output += ((char)('A' + i)).ToString();

			//A spacer between the index and the symbols
			output += "\n-+";
			for (int i = 0; i < CollectionManager.Width; i++)
				output += "-";

			//The actual symbols (and vertical index
			for (int i = 0; i < CollectionManager.Height; i++)
			{
				//Vertical index
				output += "\n" + i + "|";

				//Symbols for this row
				for (int j = 0; j < CollectionManager.Width; j++)
				{
					SpecialPoint thisPoint = new SpecialPoint(j, i);
					if (HasItem(thisPoint))
					{
						if (simple)
							output += CollectionSymbols.SimpleObtainedSymbol;
						else
							output += CollectionSymbols.GetSymbol(thisPoint);
					}
					else
					{
						if (simple)
							output += CollectionSymbols.SimpleEmptySymbol;
						else
							output += CollectionSymbols.EmptyGridSymbol;
					}
				}
			}

			return output;
		}
		/// <summary>
		/// Accessor for individual values of collection
		/// </summary>
		/// <param name="point"></param>
		/// <returns></returns>
		public int this[SpecialPoint point]
		{
			get
			{
				if (!CollectionManager.ValidPoint(point))
					return -1;

				return obtained[point.Across, point.Down];
			}
		}
		/// <summary>
		/// Get both the point and the symbol (useful for chat output)
		/// </summary>
		/// <param name="point"></param>
		/// <returns></returns>
		public static string GetPointAndSymbol(SpecialPoint point)
		{
			return point + "(" + GetSymbol(point) + ")";
		}
		/// <summary>
		/// Does this collection have the given item at the point?
		/// </summary>
		/// <param name="point"></param>
		/// <returns></returns>
		public bool HasItem(SpecialPoint point)
		{
			if (CollectionManager.ValidPoint(point) && obtained[point.Across, point.Down] > 0)
				return true;

			return false;
		}
		/// <summary>
		/// Like GetCoins, GetItem should be used whenever an item is obtained. It performs both the inventory
		/// item obtainment and the journal obtainment. It also keeps track of the "forever" journal
		/// </summary>
		/// <param name="itemPoint"></param>
		private void GetItem(SpecialPoint itemPoint)
		{
			foreverJournal.ObtainItem(itemPoint);
			journal.ObtainItem(itemPoint);
			inventory.ObtainItem(itemPoint);
		}
		/// <summary>
		/// Get the symbol for a given point
		/// </summary>
		/// <param name="point"></param>
		/// <returns></returns>
		public static string GetSymbol(SpecialPoint point)
		{
			string symbol = "";

			//Only get the symbol if the point was valid
			if (CollectionManager.ValidPoint(point))
				symbol = AllSymbols[point.Across + point.Down * CollectionManager.Width].ToString();

			return symbol;
		}
		/// <summary>
		/// Buy the given item for the given price. You lose (price) coins, but get the item
		/// Returns false if the transaction cannot go through.
		/// </summary>
		/// <param name="itemPoint"></param>
		/// <param name="price"></param>
		/// <returns></returns>
		public bool BuyItem(SpecialPoint itemPoint, int price)
		{
			if (coins < price || !CollectionManager.ValidPoint(itemPoint))
				return false;

			coins -= price;
			GetItem(itemPoint);

			return true;
		}
		/// <summary>
		/// Sell an item in your inventory for the price given. You lose the item, but get (price) coins.
		/// Returns false if the transaction cannot go through
		/// </summary>
		/// <param name="itemPoint"></param>
		/// <param name="price"></param>
		/// <returns></returns>
		public bool SellItem(SpecialPoint itemPoint, int price)
		{
			if (!inventory.HasItem(itemPoint) || !CollectionManager.ValidPoint(itemPoint))
				return false;

			GetCoins(price);
			inventory.UnobtainItem(itemPoint);

			return true;
		}
      public static int SellPrice(SpecialPoint item, CollectionPlayer player)
      {
         return (int)(IndividualSellPrice + ExtraSellPrice * (player.RareList.Select(x => CollectionManager.PointFrom1DIndex(x)).ToList().IndexOf(item) / (double)CollectionManager.TotalGridSpace));
//         double leastRare = CollectionGenerator.ItemRarity(CollectionManager.PointFrom1DIndex(player.RareList[0]), player);
//
//         return (int)(IndividualSellPrice + ExtraSellPrice * (1 - CollectionGenerator.ItemRarity(item, player) / leastRare));
      }
		/// <summary>
		/// The SpecialPoint class is a very general class, so we need to make sure it falls within our collection guidelines
		/// </summary>
		/// <param name="point"></param>
		/// <returns></returns>
		public static bool ValidPoint(SpecialPoint point)
		{
			return (point != null && point.Across >= 0 && point.Across < Width && point.Down >= 0 && point.Down < Height);
		}
      public static double ItemRarity(SpecialPoint item, CollectionPlayer player)
      {
         if (!CollectionManager.ValidPoint(item))
            return 0;
         
         int index = player.RareList.Select(x => CollectionManager.PointFrom1DIndex(x)).ToList().IndexOf(item);

         if(index < 0)
            return 0;

         double totalRarity = CumulativeRarity(CollectionManager.TotalGridSpace);

         return (CumulativeRarity(index + 1) - CumulativeRarity(index)) / totalRarity;
      }