|
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuleOfReady.Core.DomainModels
{
/// <summary>
/// Object for storing a Partial Sequence (e.g. 2 3, as part of 2 3 4)
/// </summary>
public class MahjongPartialSequence : IEnumerable<MahjongTile>
{
/// <summary>
/// The partial sequence this object represents
/// </summary>
public IEnumerable<MahjongTile> PartialSequence { get; private set; }
/// <summary>
/// The completed sequence this partial sequence is part of
/// </summary>
public IEnumerable<MahjongSequence> PossibleCompletions { get; private set; }
/// <summary>
/// This tile needed to complete this partial sequence
/// </summary>
public IEnumerable<MahjongTile> WaitingTiles { get; private set; }
/// <summary>
/// Create a new partial sequence given a sequence, at a partial sequence in it
/// </summary>
/// <param name="sequence">sequence that this partial sequence is part of</param>
/// <param name="partialSequence">the partial sequence of tiles</param>
public MahjongPartialSequence(MahjongSequence sequence, IEnumerable<MahjongTile> partialSequence)
{
if (!(sequence.Count() - 1 == partialSequence.Count()))
throw new ArgumentException("Partial Sequence has the wrong number of tiles", "partialSequence");
;
if (partialSequence.Except(sequence).Any())
throw new ArgumentException("Partial sequence not (completely) part of sequence", "partialSequence");
this.PartialSequence = partialSequence;
this.PossibleCompletions = this.DeterminePossibleCompletions(sequence, partialSequence);
this.WaitingTiles = this.PossibleCompletions.SelectMany(seq => seq.Except(partialSequence));
}
#region IEnumerable<MahjongTile> Implementation
/// <summary>
/// Gets the enumerator for the partial sequence list
/// </summary>
/// <returns>enumerator for the partial sequence list</returns>
public IEnumerator<MahjongTile> GetEnumerator()
{
return this.PartialSequence.GetEnumerator();
}
/// <summary>
/// Gets the enumerator for the partial sequence list
/// </summary>
/// <returns>enumerator for the partial sequence list</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.PartialSequence.GetEnumerator();
}
private IEnumerable<MahjongSequence> DeterminePossibleCompletions(MahjongSequence sequence,
IEnumerable<MahjongTile> partialSequence)
{
yield return sequence;
// if the partial doesn't contain a terminal...
IEnumerable<MahjongSuitTile> partialSeq = partialSequence.Cast<MahjongSuitTile>();
Func<MahjongSuitTile, bool> NotATerminal =
tile => (tile.SuitNumber != MahjongSuitNumber.One && tile.SuitNumber != MahjongSuitNumber.Nine);
if (partialSeq.All(tile => NotATerminal(tile)))
{
MahjongSuitTile firstCompletedTile = sequence.Except(partialSequence).Cast<MahjongSuitTile>().Single();
IEnumerable<MahjongSuitTile> otherCompletedSequence = new List<MahjongSuitTile>();
if (partialSequence.All(tile => tile < firstCompletedTile))
otherCompletedSequence = Enumerable.Repeat(new MahjongSuitTile(firstCompletedTile.SuitType, firstCompletedTile.SuitNumberInt - 3), 1)
.Concat(partialSeq);
else if (partialSequence.All(tile => tile > firstCompletedTile))
otherCompletedSequence = partialSeq.Concat(
Enumerable.Repeat(new MahjongSuitTile(firstCompletedTile.SuitType, firstCompletedTile.SuitNumberInt + 3), 1));
if (otherCompletedSequence.Any())
yield return new MahjongSequence(otherCompletedSequence);
}
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I'm a software developer that works with a small team on websites in .Net. Software development is a career of constant learning, and here I'm learning by sharing.