Фильтрация массива по индексам и значениям соответствия
Я привязываю, чтобы отфильтровать шаблон для игрового автомата, в этом случае я хочу, чтобы следующие индексы были выбраны, если они имеют одинаковое значение.
Если индексы 0, 2 и 6 имеют одинаковое значение, если они должны выводиться.
Я думал о чем-то вроде вызова функции, может быть, как это
if (win_filter([0, 2, 6] == "slot-2") {
console.log("You won");
}
Мой код приведен ниже.
var final_score = new Array();
$(".shoot").click(function() {
//var numbers_array = ["slot-1", "slot-1", "slot-1", "slot-1", "slot-1", "slot-2", "slot-2", "slot-2", "slot-2", "slot-3", "slot-3", "slot-3", "slot-4", "slot-4", "slot-5"];
var numbers_array = ["slot-1", "slot-2", "slot-3", "slot-4", "slot-5"];
var target = $("div.window table");
target.find("tr td > div").each(function() {
$(this).fadeOut(function() {
$(this).removeAttr('class');
$(this).addClass(numbers_array[Math.floor(Math.random() * numbers_array.length)]);
$(this).fadeIn();
final_score.push($(this).attr("class"));
});
});
function filterResults(arr) {
return final_score.filter(function(el) {
return arr.some(function(e) {
return el.timeframe == e;
});
});
}
var result = filterResults(['0','2','6']);
console.log(result);
$.each(numbers_array, function(index, value) {
if (result == value) {
$(".notice").html("You have won.").addClass("success").show();
console.log("You won!");
}
});
console.log(final_score);
});
Edit
Если это было неясно, я имел в виду индексы в массиве, в случае, если я выбрал индексы 0, 2 и 6 из этого сгенерированного массива, это значение будет (даже если они не совпадают).
0 => "slot-2", 2 => "slot-5", 6 => "slot-1"
Цель состоит в том, чтобы проверить, имеет ли выбранные индексы одинаковые значения.
И количество индексов не должно быть жестко запрограммированным, это может быть что угодно: от трех индексов до 5 запросов индекса.
jsFiddle.net
Array[0]
0 : "slot-2"
1 : "slot-3"
2 : "slot-5"
3 : "slot-5"
4 : "slot-4"
5 : "slot-3"
6 : "slot-1"
7 : "slot-4"
8 : "slot-1"
9 : "slot-2"
10 : "slot-2"
11 : "slot-4"
12 : "slot-5"
13 : "slot-1"
14 : "slot-4"
Ответы
Ответ 1
Прежде всего, я избегал делать какие-либо серьезные изменения в вашем коде, поэтому в jsfiddle я написал проверку точно там, где вы ожидали его (внутри on('click')
).
Что я сделал:
Прежде чем рассчитывать что-либо, нам нужны данные слотов. Вы уже сохранили его внутри final_score
, но функция, которая делала это, была обратным вызовом. Стоит ли ждать ответа? - Я так не думаю, потому что это простая анимация css (fadeOut
).
const classVal = numbers_array[Math.floor(Math.random() * numbers_array.length)];
$(this.fadeOut(function() { // Rest of your code }
final_score.push(classVal);
Рассчитайте длину каждой строки, вы знаете, что все они будут одинаковой длины, и у вас есть все они внутри массива (final_score
), поэтому достаточно простого деления на количество строк.
const lines = 3;
const lineLength = final_score.length/lines;
Для каждой строки мы проверяем, совпадают ли другие значения строк с этим. Учитывая, что ваш порядок массива не основан на порядке отображения, а скорее на том порядке, который вы их создали, мы можем просто проверить те с тем же индексом (но итерации по каждой строке).
final_score[i] === final_score[i+lineLength] && final_score[i] === final_score[i+lineLength*2]
Результат:
const lineLength = final_score.length/3;
for(let i=0; i<lineLength; i++) {
if (final_score[i] === final_score[i+lineLength] && final_score[i] === final_score[i+lineLength*2]) {
console.info(`win col ${i}`);
}
}
Если вам это нужно, вы можете легко n-ify
это.
const lineLength = final_score.length/3;
for(let i=0; i<lineLength; i++) {
const lineOneSlot = final_score[i];
let allEqual = true;
for (let j=1; j<lines; j++) {
console.info(`Comparing ${i} ${i+lineLength*j}`);
if (lineOneSlot !== final_score[i+lineLength*j]) {
allEqual = false;
break;
}
}
if (allEqual) {
console.info(`win col ${i}`);
}
}
Поскольку вы также запросили диагональную проверку, это будет выглядеть так:
Однако вы должны убедиться, что сетка является квадратом, чтобы получить ожидаемые результаты. В противном случае вам придется переопределить, что именно делать в этих случаях.
final_score[i] === final_score[i+1+lineLength] && final_score[i] === final_score[i+line+lineLength*line]
https://jsfiddle.net/qjp7g0qL/3/
Ответ 2
Прочитав ваши комментарии и комментарии, вы получите представление о том, что вы пытаетесь создать какой-либо игровой автомат, где центральная строка используется для соответствующей оценки. Таким образом, изменилось несколько строк в коде, чтобы сделать это. JS FIDDLE DEMO
ПРИМЕЧАНИЕ. Я попытался использовать два подхода для состояния WINNER.
1. Все элементы CENTER ROW должны быть одинаковыми.
2. Все предметы CENTER ROW должны быть выложены так же, как и PATTERN
FYI: COMMENTED LINE 21 в JS для легкого тестирования...
/* checks if selected items are matching the winning pattern ... */
function areItemsMatchingWinningPattern(selectedItems, winningItemsPattern) {
return !!selectedItems && !!winningItemsPattern && (selectedItems.length == winningItemsPattern.length) && selectedItems.every(function (elm, idx) {
return elm === winningItemsPattern[idx];
})
}
/* checks if all selected items are same .... */
function areAllItemsMatching(source) {
return !!source && source.length > 0 && source.every(function (elm, idx, array) {
return idx === 0 || array[idx - 1] == elm;
});
}
Ответ 3
Эта схема может проверять условия выигрыша, заданные непустым списком произвольных длин действительных индексов. Вот рабочий JSFiddle.
var win_filter = function(indexes, allValues) {
// assumes all indexes are valid
// gather all the values from the slot machine by index.
var values = [];
for (var i = 0; i < indexes.length; i++)
values.push(allValues[indexes[i]]);
// if every value matches the others, then all values match the first
if (values.every(function(x) { return x == values[0]; }))
return values[0]; // return the value that was the same
// No match found, return null to signify that no winning condition was found.
return null;
}
$(".shoot").on('click', function() {
var final_score = [];
var numbers_array = ["slot-1", "slot-2", "slot-3", "slot-4", "slot-5"];
// ...
// Instead of iterating through the possible winning values, if there was any match, it means they won, and winningMatch will contain that matching value. ie 'slot-1'
var winningMatch = win_filter([0, 2, 6], final_score);
if (winningMatch) {
$(".notice").html("You have won.").addClass("success").show();
}
});
Обратите внимание, что если выигрывает какой-либо сопоставимый набор любого доступного имени класса, то нам не нужно перебирать список возможных выигрышных случаев, чтобы определить, что игра была выиграна, потому что не выиграет ни один матч?
Ответ 4
Вы запросили функцию сравнения, вот она:
function compareMultiple(sourceArray, indexesArray, compareToValue){
for (let i = 0; i < indexesArray.length; i++){
let index = indexesArray[i]
if (!sourceArray[index] || sourceArray[index] !== compareToValue) {
return false
}
}
return true
}
Он принимает три аргумента: массив значений, массив индексов для выбора элементов и значения для соответствия условию. Функция возвращает a true / false
. Вы можете называть это следующим образом:
let isWin = compareMultiple(
['slot-1','slot-2','slot-1','slot-3','slot-4', 'slot-2', 'slot-1'],
[0, 2, 6],
'slot-1'
)
console.log(isWin); // true
Вот пример (я уменьшил number_array
, чтобы увеличить шанс выиграть и переписать немного кода только для демонстрации), В этом примере я также использовал promises, чтобы ждать завершения анимации jquery fadeOut
, и мы можем проверить, будет ли новая комбинация слотов win (поскольку вы добавили новые значения в final_score
только при полном асинхронном обратном вызове fadeOut, но проверьте его сразу после $.each, ваша скрипка не будет работать, как ожидалось).
Ответ 5
Fiddle: https://jsfiddle.net/q3eh0n9f/4/
var options = [
"slot-2",
"slot-3",
"slot-5",
"slot-5",
"slot-4",
"slot-3",
"slot-1",
"slot-4",
"slot-1",
"slot-2",
"slot-2",
"slot-4",
"slot-5",
"slot-1",
"slot-4"
];
// convert selections to usable values and filter unique elements
function buildResults (arr) {
return arr.map(function (index) {
return options[index];
}).filter(function (value, i, arr) {
return arr.indexOf(value) === i;
});
}
// if array has been reduced to the length of 1 it is a winner
function checkResults (results) {
if (results.length === 1) return true;
if (results.length !== 1) return false;
}
var result = checkResults(buildResults([0, 2, 3]));
console.log(result); // false