?? hiscorelist.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>
/// <HiScore>
/// <Player name="Vladimir" score="122" steps="40" />
/// <Player name="Vova" score="88" steps="31" />
/// <Player name="Test" score="70" steps="21" />
/// <Player name="player" score="45" steps="18" />
/// <Player name="player" score="42" steps="14" />
/// <Player name="player" score="36" steps="15" />
/// <Player name="player" score="33" steps="12" />
/// <Player name="player" score="29" steps="12" />
/// <Player name="player" score="26" steps="11" />
/// <Player name="player" score="26" steps="26" />
/// </HiScore>
/// </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 + -