Для сравнения обоих вариантов вы хотите иметь function
, который выполняет сравнение для вас и дает вам результат. Но прежде чем вы сможете написать это, вы должны назначить сопоставимое значение для каждой возможной комбинации выбора. В вашем случае то, что вам нужно, называется hashmap / key-value-pair.
Например:
const CHOICES = {
paper: { stone: 1, scissors: -1, paper: 0 }, // paper beats stone, but looses against scissors
scissors: { paper: 1, stone: -1, scissors: 0 }, // scissors beat paper but loose against stone
stone: { scissors: 1, paper: -1, stone: 0 }
};
С помощью этого вы можете написать себе функцию, которая принимает оба варианта и сравнивает их с этой хэш-картой:
function compareChoices (user, computer) {
const choiceValue = CHOICES[user][computer];
return choiceValue > 0 ? 'user' :
choiceValue < 0 ? 'computer' :
/* otherwise */ 'draw';
}
Это позволяет вам определить победитель. Например:
var winner1 = compareChoices('stone', 'scissors');
// winner1 === 'user'
var winner2 = compareChoices('paper', 'scissors');
// winner2 === 'computer'
var winner3 = compareChoices('paper', 'paper');
// winner3 ==== 'draw'
Далее вам нужна еще одна функция, которая восстанавливает выбор компьютера. В противном случае вы можете играть в свою игру только один раз без дублирования кода. Вы можете использовать то, что у вас уже есть внутри тела функции:
function getComputerChoice () {
var computerChoice = Math.random();
return computerChoice < 0.34 ? 'stone' :
computerChoice < 0.671 ? 'paper' :
/* otherwise */ 'scissors';
}
Это логически то же самое, что вы уже использовали в своем коде. Разница в том, что он позволяет восстанавливать выбор столько раз, сколько вам нужно, без дублирования кода . Вместо if
-условий я использовал троичный оператор condition ? truthy : falsy
, и вместо сохранения выбора в переменной он возвращает выбор в виде строки, которая отображается на отображение CHOICES
. [ 1121]
Вызывайте эту функцию каждый раз, когда вам нужно сгенерировать выбор для компьютерного «игрока». Внутри ваших функций обработчика событий вы можете теперь сделать что-то вроде этого, например:
var paper = document.querySelector("#paper header");
paper.addEventListener("click", function(userMove) {
paper.classList.toggle("header-special");
output.innerHTML = 'You Chose Paper'
var computer = getComputerChoice();
output.innerHTML += '<br>Computer has choosen ' + computer;
var winner = compareChoices('paper', computer);
if (winner === 'draw') {
winner = 'nobody';
}
output.innerHTML += '<br><strong>The winner is: ' + winner + '</strong>';
});
Дальнейшие улучшения
Этот код может быть улучшен несколькими способами. Прежде всего, вы могли бы придумать способ написать его менее повторяющимся. Подсказка: используйте ту же технику, которую мы использовали, чтобы «извлечь» суть функции getComputerChoice
из того, что у вас уже было. Есть ли способ абстрагироваться от DOM-запросов и добавления списков событий?
Было бы неплохо изменить пользовательский интерфейс вместо вместо того, чтобы просто отображать победителя. Под этим я подразумеваю скрывать выбранные элементы <div>
элементов от пользователя после того, как он щелкнет, и отображать результат, чтобы пользователь мог сыграть в следующем раунде.
Я знаю то, что Вы имеете в виду. Я не знаю, но смотрю на FxCop. Это могло бы иметь правило там где-нибудь, которое проверяет, не расположены ли объекты, реализовывая IDisposable. Просто догадка, ум.
ОБНОВЛЕНИЕ: Mitch Wheat пишет:
FxCop включает правило, это, говорит, что все типы, которые происходят из типов, которые реализуют IDisposable, должны реализовать Расположение () шаблон
Спасибо, Mitch.
Вы могли сделать это с ReSharper. С ReSharper можно переместиться по реализациям любого интерфейса легко при помощи Alt-End, но для популярного интерфейса такой как IDisposable
это не практично.
Вот то, что Вы могли сделать:
System.IDisposable
IDisposable
. Это полужирным - те, Вы хотите - они реализуют IDisposable
непосредственно.Надежда, которая помогает.
Правила использования CA2213 (DisposableFieldsShouldBeDisposed) и CA2215 (DisposeMethodsShouldCallBaseClassDispose) в FxCop поймают, где располагают, не назван правильно в Ваших собственных классах, но я не полагаю, что существует что-либо там для проверки, располагают, всегда называется, хотя иронически существует правило (CA2202) для DoNotDisposeObjectsMultipleTimes
Кроме того, в зависимости от того, используете ли Вы системы как этот при использовании контейнера МОК он мог бы пройти несколько слоев кода, прежде чем сервис будет возвращен Вам через интерфейс, и это не могло бы быть тривиально для обработки IDisposable в таком случае.
Возможно, интерфейс, который Вы разрешили, не наследовался IDisposable, но используемый класс практической эксплуатации делает? Как обработать это? и т.д.