Skip to content

Instantly share code, notes, and snippets.

@GraemeF
Created January 27, 2011 11:50
Show Gist options
  • Save GraemeF/798405 to your computer and use it in GitHub Desktop.
Save GraemeF/798405 to your computer and use it in GitHub Desktop.
Runner up hangman player - done in a hurry so UNCLEAN! :P
namespace Graeme
{
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using CodeFest2PlayerRef;
[Export(typeof(ICanPlayCodeFest2))]
public class Player : ICanPlayCodeFest2
{
private IEnumerable<string> _allPossibleWords;
private List<char> _guesses;
private Dictionary<char, int> _hits = new Dictionary<char, int>();
#region ICanPlayCodeFest2 members
public void NewGame(IEnumerable<string> allPossibleWords)
{
_allPossibleWords = allPossibleWords;
_guesses = new List<char>();
}
public string PlayerName()
{
return "Graeme";
}
public MyGo TakeTurn(string current)
{
_hits = new Dictionary<char, int>(26);
IEnumerable<string> givenWords = current.Split(' ').Select(x => x.Trim());
IEnumerable<string> phrases = PossiblePhrases(givenWords);
if (!phrases.Skip(1).Any())
return new MyGo(GameAction.Guess, phrases.Single());
foreach (string target in givenWords)
{
IEnumerable<string> candidates = CandidatesMatching(target);
foreach (char missingLetter in candidates.
SelectMany(x => x.MissingLetters(target)))
AddMissingLetterHit(missingLetter);
}
char guess = GetMostLikelyLetter();
_guesses.Add(guess);
return new MyGo(GameAction.RequestLetter, GetMostLikelyLetter());
}
#endregion
private void AddMissingLetterHit(char missingLetter)
{
int count = 0;
_hits.TryGetValue(missingLetter, out count);
if (!_guesses.Contains(missingLetter))
_hits[missingLetter] = count + 1;
}
private IEnumerable<string> CandidatesMatching(string target)
{
return _allPossibleWords.
Where(x => x.CanMatch(target, _guesses));
}
private char GetMostLikelyLetter()
{
int max = _hits.Max(x => x.Value);
return _hits.First(x => x.Value == max).Key;
}
private IEnumerable<string> PossiblePhrases(IEnumerable<string> givenWords)
{
foreach (string match in CandidatesMatching(givenWords.First()))
if (givenWords.Skip(1).Any())
{
IEnumerable<string> possiblePhraseEnds = PossiblePhrases(givenWords.Skip(1));
foreach (string possiblePhraseEnd in possiblePhraseEnds)
yield return match + " " + possiblePhraseEnd.Trim();
}
else
yield return match;
}
}
}
namespace Graeme
{
using System.Collections.Generic;
using System.Linq;
public static class StringExtensions
{
public static bool CanMatch(this string candidate, string target, List<char> guesses)
{
if (candidate.Length !=
target.Length)
return false;
//if (guesses.Any(x => candidate.Contains(x)))
// return false;
for (int i = 0; i < target.Length; i++)
if (target[i] != '_')
if (candidate[i] !=
target[i])
return false;
return true;
}
public static IEnumerable<char> MissingLetters(this string candidate, string target)
{
return AllMissingLetters(target, candidate).Distinct();
}
private static IEnumerable<char> AllMissingLetters(string target, string candidate)
{
for (int i = 0; i < target.Length; i++)
if (target[i] == '_')
yield return candidate[i];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment