⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hiscorelist.cs

📁 C#开发的运行于windows mobile PDA上的游戏
💻 CS
字号:
////////////////////////////////////////////////
// 
// Project: Lines.NET
// Version: 1.1
// Author:  Vladimir L.
// 
// homepage: http://www.boomsoft.org
// e-mail:   support@boomsoft.org
// 
// Copyright (c) 2003-2004, Boomsoft.org
// 

using System;
using System.Collections;
using System.Xml;
using System.IO;

namespace Lines.Core
{
	/// <summary>
	/// Represents the hi score list of the game players.
	/// </summary>
	/// <remarks>
	/// This class supports serialization to XML formatted file.
	/// </remarks>
	public class HiScoreList : IEnumerable
	{
		/// <summary>
		/// Encloses a single entry of hi score list.
		/// </summary>
		/// <remarks>
		/// Provides a set of read only properties to retrieve hi score entry information and 
		/// implements <see cref="IComparable"/> interface to simplify sorting.
		/// </remarks>
		public class PlayerScore : IComparable
		{
			/// <summary>
			/// Holds the player name.
			/// </summary>
			private string name;
			/// <summary>
			/// Holds a value of player best score.
			/// </summary>
			private int score;
			/// <summary>
			/// Holds a value of steps the player did to reach a score.
			/// </summary>
			private int steps;

			/// <summary>
			/// Creates an instance of hi score entry.
			/// </summary>
			/// <param name="name">The player name.</param>
			/// <param name="score">The game score.</param>
			/// <param name="steps">The amount of steps were used.</param>
			public PlayerScore(string name, int score, int steps)
			{
				this.name = name;
				this.score = score;
				this.steps = steps;
			}

			/// <summary>
			/// Gets the player name.
			/// </summary>
			public string Name
			{
				get {return name;}
			}

			/// <summary>
			/// Gets the game score.
			/// </summary>
			public int Score
			{
				get {return score;}
			}

			/// <summary>
			/// Gets the amount of steps were used to reach a score.
			/// </summary>
			public int Steps
			{
				get {return steps;}
			}
			#region IComparable Members

			/// <summary>
			/// Compares the current instance with another object of PlayerScore type.
			/// </summary>
			/// <param name="obj">The object of PlayerScore type to compare the current object to.</param>
			/// <returns>An integer value that indicates the relative order of the comparands. The return 
			/// value has these meanings:
			/// <list type="table">
			///		<listheader>
			///			<term>Value</term>
			///			<description>Meaning</description>
			///		</listheader>
			///		<item>
			///			<term>Less than zero</term>
			///			<description>This instance is less than <c>obj</c>.</description>
			///		</item>
			///		<item>
			///			<term>Zero</term>
			///			<description>This instance is equal to <c>obj</c>.</description>
			///		</item>
			///		<item>
			///			<term>Greater than zero</term>
			///			<description>This instance is greater than <c>obj</c>.</description>
			///		</item>
			/// </list>
			/// </returns>
			public int CompareTo(object obj)
			{
				PlayerScore playerScore = (PlayerScore)obj;
				
				if (Score > playerScore.Score)
					return 1;
				if (Score == playerScore.Score)
				{
					if (Steps < playerScore.Steps)
						return 1;
					else if (Steps == playerScore.Steps)
						return 0;
					else
						return -1;
				}
				return -1;
			}

			/// <summary>
			/// Compares if score of a first player less then score of a second player.
			/// </summary>
			/// <param name="ps1">The game score of a first player.</param>
			/// <param name="ps2">The game score of a second player.</param>
			/// <returns><c>true</c> if the score of a first player less then the score of a second player,
			/// <c>false</c> otherwise.</returns>
			public static bool operator < (PlayerScore ps1, PlayerScore ps2)
			{
				return (ps1.CompareTo(ps2) < 0);
			}
			/// <summary>
			/// Compares if score of a first player greater then score of a second player.
			/// </summary>
			/// <param name="ps1">The game score of a first player.</param>
			/// <param name="ps2">The game score of a second player.</param>
			/// <returns><c>true</c> if the score of a first player greater then the score of a second player,
			/// <c>false</c> otherwise.</returns>
			public static bool operator > (PlayerScore ps1, PlayerScore ps2)
			{
				return (ps1.CompareTo(ps2) > 0);
			}
			/// <summary>
			/// Compares if score of a first player less or equal to score of a second player.
			/// </summary>
			/// <param name="ps1">The game score of a first player.</param>
			/// <param name="ps2">The game score of a second player.</param>
			/// <returns><c>true</c> if the score of a first player less or equal to the score of a second player,
			/// <c>false</c> otherwise.</returns>
			public static bool operator <= (PlayerScore ps1, PlayerScore ps2)
			{
				return (ps1.CompareTo(ps2) <= 0);
			}
			/// <summary>
			/// Compares if score of a first player greater or equal to score of a second player.
			/// </summary>
			/// <param name="ps1">The game score of a first player.</param>
			/// <param name="ps2">The game score of a second player.</param>
			/// <returns><c>true</c> if the score of a first player greater or equal to the score of a second player,
			/// <c>false</c> otherwise.</returns>
			public static bool operator >= (PlayerScore ps1, PlayerScore ps2)
			{
				return (ps1.CompareTo(ps2) >= 0);
			}

			#endregion
		}

		/// <summary>
		/// Holds an array of the best players' score.
		/// </summary>
		private PlayerScore[] topList = null;
		/// <summary>
		/// Defines the maximum size of his score list.
		/// </summary>
		private int maxLength;
		
		/// <summary>
		/// Creates an instance of hi score list.
		/// </summary>
		/// <remarks>
		/// The value of <see cref="maxLength"/> is set to 10 by default.
		/// </remarks>
		public HiScoreList()
			: this(10)
		{
		}

		/// <summary>
		/// Creates an instance of hi score list with predefined <see cref="maxLength"/> value.
		/// </summary>
		/// <param name="maxLength">The value of <see cref="maxLength"/> property.</param>
		public HiScoreList(int maxLength)
		{
			this.maxLength = maxLength;
			this.topList = new PlayerScore[10];
		}

		/// <summary>
		/// Loads from file a players' hi score list in XML format.
		/// <seealso cref="Save(string)"/>
		/// </summary>
		/// <param name="filename">The hi score list file name.</param>
		/// <example>
		/// <code>
		/// &lt;HiScore&gt;
		///		&lt;Player name="Vladimir" score="122" steps="40" /&gt;
		///		&lt;Player name="Vova" score="88" steps="31" /&gt;
		///		&lt;Player name="Test" score="70" steps="21" /&gt;
		///		&lt;Player name="player" score="45" steps="18" /&gt;
		///		&lt;Player name="player" score="42" steps="14" /&gt;
		///		&lt;Player name="player" score="36" steps="15" /&gt;
		///		&lt;Player name="player" score="33" steps="12" /&gt;
		///		&lt;Player name="player" score="29" steps="12" /&gt;
		///		&lt;Player name="player" score="26" steps="11" /&gt;
		///		&lt;Player name="player" score="26" steps="26" /&gt;
		///	&lt;/HiScore&gt;
		///	</code>
		/// </example>
		public void Load(string filename)
		{
			if (File.Exists(filename))
			{
				XmlDocument doc = new XmlDocument();
				doc.Load(filename);
				XmlNode root = doc.DocumentElement;
				XmlNode node = root.FirstChild;
				int count = 0;
				while ((node != null) && (count < maxLength))
				{
					topList[count] = new PlayerScore(node.Attributes["name"].Value, 
						int.Parse(node.Attributes["score"].Value), int.Parse(node.Attributes["steps"].Value));

					count++;
					node = node.NextSibling;
				}

				// Just to be sure that nobody tricked
				Array.Sort(topList);
				Array.Reverse(topList, 0, topList.Length);
			}
		}

		/// <summary>
		/// Saves to file a players' hi score list in XML format.
		/// <seealso cref="Load(string)"/>
		/// </summary>
		/// <param name="filename">The hi score list file name.</param>
		/// <remarks>
		/// See example for <see cref="Load(string)"/>.
		/// </remarks>
		public void Save(string filename)
		{
			XmlDocument doc = new XmlDocument();
			XmlNode root = doc.CreateNode(XmlNodeType.Element, "HiScore", "");
			doc.AppendChild(root);

			XmlNode node;
			XmlAttribute attribute;
			
			for (int i = 0; i < maxLength; i++)
			{
				PlayerScore playerScore = topList[i];
				if (playerScore == null)
					break;
				node = doc.CreateNode(XmlNodeType.Element, "Player", "");
				attribute = doc.CreateAttribute("name");
				attribute.Value = playerScore.Name;
				node.Attributes.Append(attribute);
				attribute = doc.CreateAttribute("score");
				attribute.Value = playerScore.Score.ToString();
				node.Attributes.Append(attribute);
				attribute = doc.CreateAttribute("steps");
				attribute.Value = playerScore.Steps.ToString();
				node.Attributes.Append(attribute);
				root.AppendChild(node);
			}

			doc.Save(filename);
		}

		/// <summary>
		/// Verifies whether a new result is a record or not.
		/// </summary>
		/// <param name="score">The player's score.</param>
		/// <param name="steps">The amount of steps player used to reach that score.</param>
		/// <returns><c>true</c> if new result is better then the worst result of hi score list, or the length
		/// of hi score list is smaller then <see cref="maxLength"/>.</returns>
		public bool IsRecord(int score, int steps)
		{
			PlayerScore playerScore = topList[maxLength - 1];
			
			if (playerScore == null)
				return true;
			if (score > playerScore.Score)
				return true;
			if ((score == playerScore.Score) && (steps < playerScore.Steps))
				return true;
			
			return false;
		}

		/// <summary>
		/// Adds a new record to hi score list.
		/// </summary>
		/// <param name="name">The player name.</param>
		/// <param name="score">The result score.</param>
		/// <param name="steps">The amount of steps were done during game.</param>
		/// <returns>A 0-based position of added record, or -1 if the result is not a record.</returns>
		public int AddRecord(string name, int score, int steps)
		{
			if (!IsRecord(score, steps))
				return -1;

			PlayerScore newPlayerScore = new PlayerScore(name, score, steps);
			PlayerScore playerScore;
			for (int i = maxLength; i > 0; i--)
			{
				playerScore = topList[i - 1];
				if (playerScore != null)
				{
					if (playerScore > newPlayerScore)
					{
						topList[i] = newPlayerScore;
						return i;
					} 
					else if (i < maxLength)
					{
						topList[i] = playerScore;
					}
				}
			}
			topList[0] = newPlayerScore;

			return 0;
		}
		#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through a collection of player records.
		/// </summary>
		/// <returns>An <see cref="IEnumerator"/> that can be used to iterate through the collection.</returns>
		public IEnumerator GetEnumerator()
		{
			return topList.GetEnumerator();
		}

		#endregion
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -