Сделайте только один ход вправо в игре 2048

У меня есть матрица 4x4, как в игре 2048, и мне нужно вывести результат одного хода вправо. Например, у нас есть матрица:

0 0 2 2
4 4 8 4
64 64 8 4
16 8 64 8

Result is:

0 0 0 4
0 8 8 4
0 128 8 4
16 8 64 8

Мой код:

function solution(x){
  for (let i = 0; i < x.length; i++){
  	for (let j = 0; j < x.length; j++){
  	  if (x[i][j] == x[i][j+1]){
        x[i][j+1] = x[i][j+1] * 2;
        x[i][j] = 0;
      }
  	}
  }
  return JSON.stringify(x)
}
console.info(solution([[0,0,2,2], [4,4,8,4], [64,64,8,4], [16,8,64,8]]));
console.info(solution([[2,2,4,8],[8,8,64,64],[64,8,16,8],[8,8,8,8]]))
console.info(solution([[64,64,64,64],[8,8,8,8],[4,4,4,4],[2,2,2,2]]))
console.info(solution([[0,0,4,4],[4,8,4,8],[8,8,8,8],[64,8,16,8]]))
console.info(solution([[2,0,4,4],[4,4,4,4],[8,0,0,8],[0,64,64,64]]))

Во второй версии я получаю неправильный результат в первой строке [0,0,0,16], правильный результат [0, 4, 4, 8]

Каким должен быть результат, скажем, [4,4,4,4]?

Kaiido 27.05.2019 16:17

@Кайидо [0, 8, 0, 8]

Narek 27.05.2019 16:21

затем выполните итерацию справа налево, как это сделал @corschdi (они даже добавили выравнивание вправо, но если вы удалите его, вы получите ожидаемые результаты.

Kaiido 27.05.2019 16:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
127
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы изменяете числа впереди и тогда проверяете следующее. Таким образом, вы фактически создаете промежуточный результат и окончательный результат, поэтому, в некотором смысле, является правильный:

[ 2, 2, 4, 8] -> [ 0, 4, 4, 8 ] -> [ 0, 0, 8, 8 ] -> [ 0, 0, 0, 16 ]
  ^  ^                ^  ^                 ^  ^                  ^

Если вы хотите игнорировать изменения, сделанные в том же прогоне, вы можете увеличить j на 1, как только обнаружите изменение:

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

function solution(x) {
  for (let i = 0; i < x.length; i++) {
    for (let j = 0; j < x.length; j++) {
      if (x[i][j] == x[i][j + 1] && x[i][j] !== 0) {
        x[i][j + 1] = x[i][j] * 2;
        x[i][j] = 0;
        j += 1;
      }
    }
  }
  return JSON.stringify(x)
}

console.info(solution([[0,0,2,2], [4,4,8,4], [64,64,8,4], [16,8,64,8]]));
console.info(solution([[2,2,4,8],[8,8,64,64],[64,8,16,8],[8,8,8,8]]))
console.info(solution([[64,64,64,64],[8,8,8,8],[4,4,4,4],[2,2,2,2]]))
console.info(solution([[0,0,4,4],[4,8,4,8],[8,8,8,8],[64,8,16,8]]))
console.info(solution([[2,0,4,4],[4,4,4,4],[8,0,0,8],[0,64,64,64]]))

Если вы просто хотите 1 изменение в строке, вы можете использовать break

Пример с break, обновляется только 1 для каждой строки

function solution(x) {
  for (let i = 0; i < x.length; i++) {
    for (let j = 0; j < x.length; j++) {
      if (x[i][j] == x[i][j + 1] && x[i][j] !== 0) {
        x[i][j + 1] = x[i][j] * 2;
        x[i][j] = 0;
        // If you only want one move, you can break here
        break;
      }
    }
  }
  return JSON.stringify(x)
}

console.info(solution([[0,0,2,2], [4,4,8,4], [64,64,8,4], [16,8,64,8]]));
console.info(solution([[2,2,4,8],[8,8,64,64],[64,8,16,8],[8,8,8,8]]))
console.info(solution([[64,64,64,64],[8,8,8,8],[4,4,4,4],[2,2,2,2]]))
console.info(solution([[0,0,4,4],[4,8,4,8],[8,8,8,8],[64,8,16,8]]))
console.info(solution([[2,0,4,4],[4,4,4,4],[8,0,0,8],[0,64,64,64]]))

Они на самом деле хотят изменить на месте... [4,4,4,4] должно быть [0,8,0,8] (или [0,0,8,8] если выровнено)

Kaiido 27.05.2019 16:24

А, спасибо за наводку. Не видел этого дополнительного требования. Я быстро обновлю свой ответ.

user3297291 27.05.2019 16:26

@ user3297291 Спасибо!

Narek 27.05.2019 16:29

Если вы хотите переместить числа вправо, вам нужно пройти массив справа налево. Кроме того, в 2048 году вам нужно будет перемещать все числа вправо после каждого слияния.

Это будет работать:

function solution(x) {
  for (let i = 0; i < x.length; i++) {
    for (let j = x.length - 1; j >= 0; j--) {
      if (x[i][j - 1] == x[i][j]) {
        x[i][j] = x[i][j] * 2;

        // move all numbers on the left to the right by one
        if (j > 1) {
          for (let k = j - 1; k > 0; k--) {
            x[i][k] = x[i][k - 1];
          }
        }
        x[i][0] = 0;
      }
    }
  }
  return JSON.stringify(x)
}
console.info(solution([
  [0, 0, 2, 2],
  [4, 4, 8, 4],
  [64, 64, 8, 4],
  [16, 8, 64, 8]
]));
console.info(solution([
  [2, 2, 4, 8],
  [8, 8, 64, 64],
  [64, 8, 16, 8],
  [8, 8, 8, 8]
]))
console.info(solution([
  [64, 64, 64, 64],
  [8, 8, 8, 8],
  [4, 4, 4, 4],
  [2, 2, 2, 2]
]))
console.info(solution([
  [0, 0, 4, 4],
  [4, 8, 4, 8],
  [8, 8, 8, 8],
  [64, 8, 16, 8]
]))
console.info(solution([
  [2, 0, 4, 4],
  [4, 4, 4, 4],
  [8, 0, 0, 8],
  [0, 64, 64, 64]
]))

Вот простое, подробное решение. (Я уверен, что возможен гораздо более элегантный вариант):

function newState(oldState){
  // Defines an array to hold our result
  let result = [];
  // Examines each row of the old state separately
  for (let row of oldState){
    // Names the columns a, b, c, & d
    let a = row[0], b = row[1], c = row[2], d = row[3];
    // Checks for match in the rightmost pair
    if (d == c && d != 0){
      d = d * 2; // Combines matching cells
      // Checks for secondary match
      if (b == a && b != 0){
        // Traditional 2048 logic: combines matching cells *into 'c'* & shifts the rest
        c = b * 2; b = 0; a = 0;
        // For the alternative logic requested in a comment by OP,
        //   replace the above line with `c = 0; b = b * 2; a = 0;`
      }
      else{
        c = b; b = a; a = 0; // Shifts the rest
      }
    }
    else{
      // Checks for match in the middle pair
      if (c == b && c != 0){
        c = c * 2; b = a; a = 0; // Combines matching cells and shifts the rest
      }
      else{
        // Checks for match in the leftmost pair
        if (b == a && b != 0){
          b = b * 2; a = 0; // Combines matching cells and shifts the rest
        }
      }
    }
    // Populates the current row in the result matrix
    result.push([a, b, c, d]);
  }
  // Returns the result matrix
  return JSON.stringify(result);
}
  
console.info(newState([[0,0,2,2], [4,4,8,4], [64,64,8,4], [16,8,64,8]]));
console.info(newState([[2,2,4,8],[8,8,64,64],[64,8,16,8],[8,8,8,8]]));
console.info(newState([[64,64,64,64],[8,8,8,8],[4,4,4,4],[2,2,2,2]]));
console.info(newState([[0,0,4,4],[4,8,4,8],[8,8,8,8],[64,8,16,8]]));
console.info(newState([[2,0,4,4],[4,4,4,4],[8,0,0,8],[0,64,64,64]]));

Другие вопросы по теме