Фильтрация массива по индексам и значениям соответствия

Я привязываю, чтобы отфильтровать шаблон для игрового автомата, в этом случае я хочу, чтобы следующие индексы были выбраны, если они имеют одинаковое значение.

Если индексы 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