Алгоритм игры "Быки и коровы" - C#
Формулировка задачи:
Здравствуйте! Суть проблемы - плохо реализован алгоритм...вы загадываете 4х значное число без повторений, а компьютер должен его угадать. В ответ компьютеру вводите 2 числе через пробел: первое - количество угаданных чисел, которые стоят на своем месте, второе - просто количество угданных чисел. Подскажите, как улучшить алгоритм поиска?
namespace Bulls_and_Cows
{
class Program
{
const int CountNumber = 4;
public static void Main()
{
Console.WriteLine("This is a game Bulls and Cows!");
Console.WriteLine("Imagine the number of four characters, computer has to guess this.");
Console.WriteLine("Enter the number of bulls and cows, separated by a space.");
Console.Write("Bulls - number in place, Cows - the correct numbers.");
Console.WriteLine();
List<string> outputList = Combinatorics.RemoveListNumder(Combinatorics.PermutateNumbers(CountNumber)).ToList();
SearchFunction(outputList);
Console.ReadKey();
}
public static void SearchFunction(List<string> outputList)
{
while (outputList.Count > 1)
{
string probability = outputList[0];
Console.Write("{0} input bulls and cows = ", probability);
int bulls, cows;
if (!InputDataClass.InputBullsCows(out bulls, out cows))
Console.WriteLine("Try again!");
else
{
for (int output = outputList.Count - 1; output >= 0; output--)
{
int countBulls = 0, countCows = 0;
for (int bufferNumber = 0; bufferNumber < CountNumber; bufferNumber++)
if (outputList[output][bufferNumber] == probability[bufferNumber])
countBulls++;
else
if (outputList[output].Contains(probability[bufferNumber]))
countCows++;
if ((countBulls != bulls) || (countCows != cows))
outputList.RemoveAt(output);
}
if (outputList.Count == 1)
Console.WriteLine("OutputList is {0}!", outputList[0]);
if (outputList.Count > 1)
Console.WriteLine("Next move: ");
if (outputList.Count < 1)
Console.WriteLine("Game over!");
}
}
}
}
}namespace Bulls_and_Cows
{
public static class InputDataClass
{
public static bool InputBullsCows(out int bulls, out int cows)
{
string[] inputMassiv = Console.ReadLine().Split(' ').ToArray();
int[] massiv = new int[inputMassiv.Length];
if (inputMassiv.Length != 2)
{
Console.WriteLine("Separated by a space");
}
else
{
for (int i = 0; i < inputMassiv.Length; i++)
{
massiv[i] = Convert.ToInt32(inputMassiv[i]);
}
}
bulls = cows = 0;
bool result = false;
for (int i = 0; i < inputMassiv.Length; i++)
{
result = inputMassiv.Length == 2 &&
massiv[i] <= 4 &&
massiv[i] >= 0 &&
int.TryParse(inputMassiv[0], out bulls) &&
int.TryParse(inputMassiv[1], out cows);
if (!result)
return false;
}
return result;
}
}
}namespace Bulls_and_Cows
{
class Combinatorics
{
public static Random RandomNumber = new Random();
public static IEnumerable<string> PermutateNumbers(int sizeNumber)
{
if (sizeNumber > 0)
{
foreach (string sizePermutate in PermutateNumbers(sizeNumber - 1))
foreach (char numberCollection in "0123456789")
if (!sizePermutate.Contains(numberCollection))
yield return sizePermutate + numberCollection;
}
else
yield return "";
}
public static IEnumerable<T> RemoveListNumder<T>(IEnumerable<T> sourse)
{
List<T> listNumber = sourse.ToList();
while (listNumber.Count > 0)
{
int bufferNumber = RandomNumber.Next(listNumber.Count);
yield return listNumber[bufferNumber];
listNumber.RemoveAt(bufferNumber);
}
}
}
}Решение задачи: «Алгоритм игры "Быки и коровы"»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BC
{
public class Program
{
private const string My = "8765";
private static void Main()
{
var taurs = new TaursAndCows();
do
{
taurs.Try();
} while (taurs.Answer != My);
Console.WriteLine("Hi");
Console.ReadKey();
}
public static Tuple<int, int> GetCows(string s)
{
int cows = 0, taurs = 0;
for (int i = 0; i < s.Length; i++)
if (s[i] == My[i])
taurs++;
else if (My.Contains(s[i]))
cows++;
return new Tuple<int, int>(taurs, cows);
}
}
public class TaursAndCows
{
private class Taur
{
public readonly int Position;
public readonly int Value;
public Taur(int position, int value)
{
Position = position;
Value = value;
}
}
public string Answer { get { return number; } }
private string number = "0123";
private int Cows { get { return cowsGuess.Count; } }
private int Taurs { get { return taurs.Count; } }
private int modifiedPosition;
private bool firstTry = true;
private List<Taur> taurs = new List<Taur>();
private int lastGuessedValue;
private readonly HashSet<int> defaultGuess = new HashSet<int> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
private readonly HashSet<int> cowsGuess = new HashSet<int>();
private int[] RestGuess { get { return defaultGuess.Except(cowsGuess).Except(number.Skip(1).Select(c => (int) char.GetNumericValue(c))).ToArray(); } }
private int lastCowGuess = 0;
public void Try()
{
if (Cows + Taurs == number.Length)
FindCombination();
var array = number.ToCharArray();
if (cowsGuess.Count > lastGuessedValue)
array[modifiedPosition] = (char) (cowsGuess.ToArray()[lastGuessedValue] + '0');
else
{
array[modifiedPosition] = (char) (RestGuess[lastGuessedValue - cowsGuess.Count] + '0');
}
var newnumber = new string(array);
AnalyseResponse(newnumber);
}
private void AnalyseResponse(string newnumber)
{
var tuple = Program.GetCows(newnumber);
var newtaurs = tuple.Item1;
var newcows = tuple.Item2;
if (newtaurs == Taurs)
{
lastGuessedValue++;
}
else if (newtaurs > Taurs)
{
number = newnumber;
taurs.Add(new Taur(modifiedPosition, (int) char.GetNumericValue(number[modifiedPosition])));
lastGuessedValue = 0;
modifiedPosition++;
}
if (newcows > Cows)
cowsGuess.Add((int) char.GetNumericValue(newnumber[modifiedPosition]));
}
private void FindCombination()
{
var pos = 0;
while (taurs[pos].Position == pos)
pos++; //находим позицию для поиска
var array = number.ToCharArray();
array // дописать
}
}
}