2014-04-15 3 views
3

В настоящее время я работаю над проектом, который является игрой Mastermind, созданной в Windows Forms.C# Вам нужна помощь, чтобы понять этот код

После каждого случая, когда игрок делает предположение, что он полагает, что он считает правильным цветом, он узнает, сколько его контактов было правильным цветом в нужном месте, и правильный цвет, но неправильное место.

Я спросил помощника, который гораздо более опытный с программированием для некоторой помощи, и он дал мне это:

/* RightCRightP is the variable for how many pins which are right colour and on right 
       place. 
    RightCWrongP is the variable for how many pins which are right colour but on wrong 
       place. 
    guessList is a list including the players guesses. 
    answerList is a list including the right answer (right order). 
*/ 
//His code 
var RightCRightP = guessList 
     .Zip(answerList, (g, s) => g == s) 
     .Count(z => z); 

var RightCWrongP = guessList 
     .Intersect(answerList) 
     .Sum(c => 
      System.Math.Min(
       answerList.Count(x => x == c), 
       guessList.Count(x => x == c))) - RightCRightP; 

Дело в том, я хочу узнать, что каждая вещь в этом коде делает. К сожалению, я не могу спросить его лично, потому что он в настоящее время в отпуске.

+3

Что мне нужно сделать, это загрузить бесплатную пробную версию ReSharper и преобразовать код из LINQ в обычный код, вы можете сделать это, нажав Alt + Enter в операторах и выбрав вариант, который вернет его. Это позволит вам точно увидеть, что делает каждый, и, возможно, облегчит его понимание. –

+0

Возьмите каждую штуку за один шаг за раз. Посмотрите на каждый метод; посмотрите свою документацию, если вы не знаете, что она будет делать; используйте некоторые примеры ввода/вывода, чтобы увидеть, что произойдет после каждой операции, и должно быть довольно очевидно, что происходит. – Servy

ответ

4

Данные, которые мы будем использовать будет

guesses = [1,2,0,3] 
answers = [1,2,3,4] 

Первое выражение

guessList.Zip(answerList, (g, s) => g == s) 

ЗИП расширение два списка «застежки-молнии», выполняя прилагаемое операцию лямбда на каждом соответствующем элементе между guessList и answerList, и возвращает коллекцию результатов.

Индекс essentialy дает

[f(guesses[0], answers[0]), f(guesses[1], 
answers[1]), f(guesses[2], answers[2]), f(guesses[3],answers[3])] 

, где функция F является функцией лямбда поставляется:

f(g,s) => g == s 

В результате [правда, истина, ложь, ложь]

Мы затем принять

.Count(z => z) 

результата метода Zip, который подсчитывает количество элементов в zipresult, которые являются истинными.

(прочитайте это как .Count (z => z!= false), если это помогает)

Таким образом, граф равен 2, потому что у нас есть два элемента, которые являются истинными. Итак, наш RightCRightP - это 2. Проверка нашего ввода - это то, что мы ожидали, потому что наши первые две догадки - правильный цвет и место размещения, но последние два - нет.

Второе выражение

guessList.Intersect(answerList) 

http://www.dotnetperls.com/intersect Цитирование Intersect применяет теорию множеств. В теории множеств пересечение является подмножеством каждой коллекции, которая находится в обеих коллекциях. В двух словах он дает набор элементов, которые существуют в обоих списках. Помните, что элементы набора различны.

Итак, из приведенных выше догадок и ответов, пересечение [1,2,0,3] и [1,2,3,4] даст [1,2,3] (обратите внимание, как 3 здесь включен, но его не в нужном месте!)

Затем мы применяем операцию суммирования результата пересечения. Сумма будет перебирать каждый элемент и находить сумму результатов, полученных с помощью прилагаемого лямбда-выражения. Цель этой операции пересечения - дать нам список правильно угаданных цветов независимо от правильного размещения.

Наша лямбда

c => Min(answerList.Count(x => x == c), guessList.Count(x => x == c)) 

Рассчитывает количество значений в answerList и guessList, равный цвет с, и принимать меньший из двух. Эта операция с суммой дает нам количество элементов, правильно угадываемых цветов независимо от правильного размещения. Итак, повторяя результат пересечения [1,2,3], лямбда вернет значение 1 для всех итераций, поэтому сумма будет равна 1 + 1 + 1 = 3. Это наш счет правильно угаданных цветов.

Поскольку мы теперь имеем Количество правильных цветов, мы можем вывести число правильных цветов с неправильным размещением путем вычитания количества правильных цветов с правым местами размещения.

RightCWrongP = 3 - 2 => 1. 

Проверка наши входы угадывает = [1, 2, 0, 3] и ответы = [1, 2, 3, 4]

RightColorWrongP 1, как мы ожидали, поскольку наше предположение о colorvalue 3, правильный цвет, но не в нужном месте.

P.S. Если что-то, что я сказал, неверно, сообщите мне, пожалуйста, в комментариях и не просто downvote, я не мастер LINQ или C#.

2

Что вы видите - это код Linq. Сейчас я объясню первую строчку, чтобы вы могли попробовать и понять вторую по своему усмотрению.

var RightCRightP = guessList 
     .Zip(answerList, (g, s) => g == s) 
     .Count(z => z); 

Эта линия в основном принимает как списки (guesslist и answerlist) и сравнивает каждый ответ (г == ы) и отсчитывает одинаковые из них.

Например, если guessList является {1, 2, 3, 4, 5}, а список ответов {1, 2, 4, 5, 3}, то "RightCRightP" будет равен 2. (1 == 1, 2 == 2, а 3 = 4, 4 = 5, 3 = 5)

Добавление к моему ответу на полноту:!!

следующий код:

List<int> guessList = new List<int>() { 1, 2, 3, 4, 5 }; 
    List<int> answerList = new List<int>() { 1, 2, 4, 5, 3 }; 

    List<bool> zipList = guessList.Zip(answerList, (g, s) => g == s).ToList<bool>(); 

    Console.WriteLine("Content of 'zipList': "); 
    foreach (bool b in zipList) { Console.WriteLine(b); } 

    int RightCRightP = zipList.Count(z => z); 

    Console.WriteLine("Number of matches in 'RightCRightP': " + RightCRightP); 

Выходы:

Content of 'zipList': 
True 
True 
False 
False 
False 
Number of matches in 'RightCRightP': 2