Bulls and Cows
A project for a Job Interview to build a quick game of "Bulls and Cows". Review draft for r/CodeReview Creator- u/Cheesy_Coreunknown
csharp
3 years ago
4.3 kB
6
Indexable
using System; using System.Collections.Generic; using System.Linq; // namespace: BullsAndCows // // summary: A project for a Job Interview // to build a quick game of "Bulls and Cows". // Review draft for r/CodeReview // Creator- u/Cheesy_Core namespace BullsAndCows { /// <summary> A static class to provide assistant functions over generic type. </summary> public static class Applier { /// <summary> Applies a function over argument. </summary> /// /// <typeparam name="TIn"> Type of the argument for application. </typeparam> /// <typeparam name="TOut"> Type of the applied argument result. </typeparam> /// <param name="x"> The applied argument. </param> /// <param name="f"> The function applied over the argument. </param> /// /// <returns> The applied argument result. </returns> public static TOut Apply<TIn, TOut>(this TIn x, Func<TIn, TOut> f) => f(x); } /// <summary> The program main class. </summary> class Program { /// <summary> Returns how many values are similar /// in the same position in guess and gen, /// and in different position in guess and gen. </summary> /// /// <exception cref="ArgumentException"> Thrown when guess or gen /// aren't the same length. </exception> /// /// <typeparam name="T"> Type of argument to compare guess and gen. </typeparam> /// <param name="guess"> The guessed input. </param> /// <param name="gen"> The generated value. </param> /// /// <returns> First result number of similar values in the same position, /// Second result number of similar values in different position. </returns> private static (int, int) Score<T>(IEnumerable<T> guess, IEnumerable<T> gen) where T : IEquatable<T> { var (bulls, nonbulls) = guess.Zip(gen) .ToLookup(x => { if (x.First == null || x.Second == null) throw new System.ArgumentException("guess and gen aren't the same length"); return x.First.Equals(x.Second); }) .Apply(x => (x[true], x[false])); var cows = nonbulls .Apply(x => (x.Select(xs => xs.First), x.Select(xs => xs.Second))) .Apply(x => x.Item1.Intersect(x.Item2)); return (bulls.Count(), cows.Count()); } /// <summary> The game's logic loop. </summary> /// /// <param name="gen"> The generated value. </param> /// <param name="length"> The length of the value. </param> /// <param name="nTry"> The current iteration. </param> /// /// <returns> whether the game have been won </returns> public static bool GameLoop(IEnumerable<char> gen, int length, int nTry) { var bulls = 0; var cows = 0; Console.Write(nTry + ": "); var guess = Console.ReadLine().ToCharArray(); if (guess.Length == length) { (bulls, cows) = Score(guess, gen); Console.WriteLine("Bulls={0}, Cows={1}", bulls, cows); return bulls == length; } else { Console.WriteLine("Wrong length"); return false; } } /// <summary> Main entry-point for this application. </summary> public static void Main() { var rand = new Random(Guid.NewGuid().GetHashCode()); var nTry = 1; Console.WriteLine("Enter the length of the number you intending to guess"); var length = int.Parse(Console.ReadLine()); var gen = new char[length].Select(_ => (char)rand.Next('0', '9')).ToList(); //ToList forces evaluation of rand.next at initialization, preventing access to uninitialized data while (!GameLoop(gen, length, nTry)) nTry++; Console.WriteLine("you Win! tries: {0}", nTry); } } }
Editor is loading...