将ruby方法移植到javascript

Porting a ruby method to javascript

本文关键字:javascript ruby 方法      更新时间:2023-09-26

我正试图将一些ruby代码移植到javascript,但有一行很吃力

Ruby代码如下:它删除了俄罗斯方块游戏中的所有完整行:

  # removes all filled rows and replaces them with empty ones, dropping all rows
  # above them down each time a row is removed and increasing the score.  
  def remove_filled
    (2..(@grid.size-1)).each{|num| row = @grid.slice(num);
      # see if this row is full (has no nil)
      if @grid[num].all?
        # remove from canvas blocks in full row
        (0..(num_columns-1)).each{|index|
          @grid[num][index].remove;
          @grid[num][index] = nil
        }
        # move down all rows above and move their blocks on the canvas
        ((@grid.size - num + 1)..(@grid.size)).each{|num2|
          @grid[@grid.size - num2].each{|rect| rect && rect.move(0, block_size)};
          # I can't port this line
          @grid[@grid.size-num2+1] = Array.new(@grid[@grid.size - num2])
        }
        # insert new blank row at top
        @grid[0] = Array.new(num_columns);
        # adjust score for full flow
        @score += 10;
      end
    }
    self
  end

其中@grid是二维数组,初始化如下:

@grid = Array.new(num_rows) {Array.new(num_columns)}

到目前为止,我所做的javascript低于

我在评论中注意到,这是我无法计算的行

removeFilled() {
            for (var i = 2; i < this.grid.length; i++) {
                var row = this.grid.slice(i);
                var allFull = true;
                for (var g = 0; g < this.grid[i].length; g++ ) {
                    if (this.grid[i][g] == undefined) {
                        allFull = false;
                        break;
                    }
                }
                if (allFull) {
                    for (var j = 0; j < this.numColumns; j++) {
                        this.grid[i][j].remove();
                        this.grid[i][j] = undefined;
                    }
                    for (var k = this.grid.length - i + 1; k <= this.grid.length; k++) {
                        var rects = this.grid[this.grid.length - k];
                        for(var l = 0; l < rects.length; l++) {
                            var rect  = rects[l];
                            if (rect) {
                                rect.move(0, this.blockSize);
                            }
                        }
                        // ***this is the line I can't port
                        this.grid[this.grid.length - k + 1] = new Array(this.grid[this.grid.length - k]);
                    }
                    this.grid[0] =  new Array(this.numColumns);
                    this.score += 10;
                }
            }
        }

有什么想法吗?

如果我理解正确,您希望将数组放在给定的位置,并将其向前复制一个位置。

你可以这样做:

  this.grid[this.grid.length - k + 1] =  this.grid[this.grid.length - k].slice(0);

TL;DR@raam86给出了正确答案。不同之处在于,在ruby中,Array.new old_arr将创建数组的副本。在JS中,您可以使用old_arr.slice() 实现相同的功能

据我所知,你的代码片段可以变成这样:

function falsy(val) {
  return undefined === val || null === val || false === val;
}
function all(arr) {
  return arr.reduce(function (a, b) { return a && !falsy(b); }, true);
}
// removes all filled rows and replaces them with empty ones, dropping all rows
// above them down each time a row is removed and increasing the score.
function removeFilled() {
  var i, j, k, rects,
      _grid       = this.grid,
      _numColumns = this.numColumns,
      _blockSize  = this.blockSize;
  for (i = 2; i < _grid.length; i++) {
    // see if this row is full (has no nil)
    if (all(_grid[i])) {
      // remove from canvas blocks in full row
      for (j = 0; j < _numColumns; j++) {
        _grid[i][j].remove();
        _grid[i][j] = undefined;
      }
      // move down all rows above and move their blocks on the canvas
      for (j = _grid.length - i + 1; j < _grid.length; j++) {
        rects = _grid[_grid.length - j];
        for (k = 0; k < rects.length; k++) {
          if (!falsy(rects[k])) {
            rects[k].move(0, _blockSize);
          }
        }
        _grid[_grid.length - j + 1] = _grid[_grid.length - j].slice();
      }
      _grid[0] = new Array(_numColumns);
      this.score += 10;
    }
  }
  return this;
}

PS你真的应该检查一下你正在使用的逻辑并考虑重构它。例如,在一个地方你使用num_columns,在另一个地方,你中继行的元素数量。当您通过数组进行迭代时,我建议您考虑对数组的副本进行操作,在这种情况下,您的代码将变得不那么复杂。