穿过Hexagon

时间:2018-02-03 02:10:59

标签: javascript

我可以轻松地从左到右遍历以下内容,但是我遇到了很多麻烦(2天,没有进展),从右上角开始运行公式。右下角。

enter image description here

基本上,我正在寻找可以检索以下值的公式:

let topRight = [
    [ h[2][4], h[3][3], h[4][2] ],
    [ h[1][3], h[2][3], h[3][2], h[4][1] ],
    [ h[0][2], h[1][2], h[2][2], h[3][1], h[4][0] ],
    [ h[0][1], h[1][1], h[2][1], h[3][0] ],
    [ h[0][0], h[1][0], h[2][0] ]
]

let bottomRight = [
    [ h[2][4], h[1][3], h[0][2] ],
    [ h[3][3], h[2][3], h[1][2], h[0][1] ],
    [ h[4][2], h[3][2], h[2][2], h[1][1], h[0][0] ],
    [ h[4][1], h[3][1], h[2][1], h[1][0] ],
    [ h[4][0], h[3][0], h[2][0] ]
]

我能够工作的唯一部分是topRight x值:

function hexagonArraySize(row) {
  if (row < this.size) {
    return (this.size + row)
  } else {
    return (this.size * 2 - (row % this.size) - 2)
  }
}

for (var i = 0, l = this.size * 2 - 1, j = l % size; i < l; ++i, ++j) {
  this.h[j] = new Array(this.hexagonArraySize(i)).fill().map((_, b) => {
    let x = (i > Math.floor(this.size / 2)) ? b : b + (this.size - i - 1)
    let y = 0 // didn't found the formula for this one...
  }, []).join("")
}

我在这里提供了一个小提琴:https://jsfiddle.net/0qwf8m1p/12/

仍有topRight y,bottomRight x&amp;你会被发现。

2 个答案:

答案 0 :(得分:5)

好的,所以你制定了You have entered 3 arguments: ./myprogram hello world topRight坐标。

xtopRight bottomRight坐标具有相同的等式:

  • 您从y
  • 开始
  • 第一个值始终等于(size - 1) * 2(其中(size - 1) * 2 - i)是序列索引)
  • 然后重复第一个值i次,但最多i

这包含以下公式:

size

接下来,您必须为let y = (size - 1) * 2 - i - Math.max(0, b - Math.min(i, size - 1)) | | | | first value | repeat at most size times | 计算x值。你有两种情况:

  • 如果bottomRight小于i,则值等于序列长度 - size / 2(项目索引)
  • 否则值等于b

这包含以下公式:

(size - 1) * 2 - b

<强> Working fiddle here

答案 1 :(得分:0)

这是两种方法的可能实现。它们通过初始化转换后的六边形中每行的x,y坐标开始工作,然后根据x值是否通过y有条件地迭代size值。六边形,其中索引“弯曲”:

function hexagon (size) {
  const height = size * 2 - 1;
  
  return Array.from({ length: height }, (_, y) => {
    const width = size + Math.min(y, height - y - 1);
    
    return Array.from({ length: width }, (_, x) => [y, x]);
  })
}

const h = hexagon(3);

function topRight (h) {
  const height = h.length;
  const size = (height + 1) / 2;
  const t = [];
  
  for (let i = height; i > 0; i--) {
    const width = size + Math.min(i - 1, height - i);
    const row = Array.from({ length: width });
    
    let y = Math.max(i - size, 0);
    let x = i - 1;
    
    for (let j = 0; j < width; j++) {
      row[j] = h[y++][y >= size ? x-- : x];
    }
    
    t.push(row);
  }
  
  return t;
}

function bottomRight (h) {
  const height = h.length;
  const size = (height + 1) / 2;
  const t = [];
  
  for (let i = 0; i < height; i++) {
    const width = size + Math.min(i, height - i - 1);
    const row = Array.from({ length: width });
    
    let y = height - Math.max(size - i, 1);
    let x = height - i - 1;
    
    for (let j = 0; j < width; j++) {
      row[j] = h[y][y-- < size ? x-- : x];
    }

    t.push(row);
  }
  
  return t;
}

console.log('topRight');
topRight(h).forEach(row => console.log(JSON.stringify(row)));
console.log('bottomRight');
bottomRight(h).forEach(row => console.log(JSON.stringify(row)));

如果您想要更面向对象的方法,可以选择以下方法:

class Hexagon extends Array {
  constructor (size, map = (row, column) => [row, column]) {
    const length = size * 2 - 1;
    
    super(length);
    
    this.fill();
    this.size = size;
    this.forEach((_, row, hexagon) => {
      const width = size + Math.min(row, length - row - 1);
      hexagon[row] = Array.from({ length: width }, (_, column) => map(row, column));
    });
  }
  
  topRight () {
    const { length, size } = this;
    return new Hexagon(size, (row, column) => {
      const upper = Math.max(row * 2 - length, 0) + 1;
      const y = Math.max(size - 1 - row, 0) + column;
      const x = Math.max(Math.min(length - 1 - row, length - upper - column), 0);
      return this[y][x];
    });
  }
  
  bottomRight () {
    const { length, size } = this;
    return new Hexagon(size, (row, column) => {
      const upper = Math.max(row * 2 - length, 0) + 1;
      const y = Math.min(size + row, length) - 1 - column;
      const x = Math.max(Math.min(length - 1 - row, length - upper - column), 0);
      return this[y][x];
    });
  }
}

let h = new Hexagon(3);
console.log('topRight');
h.topRight().forEach(row => console.log(JSON.stringify(row)));
console.log('bottomRight');
h.bottomRight().forEach(row => console.log(JSON.stringify(row)));