SabakiHQ / Sabaki

An elegant Go board and SGF editor for a more civilized age.
https://sabaki.yichuanshen.de/
MIT License
2.41k stars 377 forks source link

Compressed point lists sometimes don't resolve properly when editing #856

Open rooklift opened 2 years ago

rooklift commented 2 years ago

Load this SGF file, which afaik is legal:

(;AB[ba:ra][ab:ar][sb:sr][bs:rs])

If you edit it (I mean with the editor, not normal moves) and add a black stone to the board, Sabaki tries to resolve the compressed points into individual points, but the process partially fails, and you get a bunch of nonsense properties containing comma-joined lists...

rooklift commented 2 years ago

The issue I guess is around here.

If one pulls together the relevant code from across the repos one gets this minimal reproduction of the problem...

let alpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

let data = ["ba:ra", "ab:ar", "sb:sr", "bs:rs"]

let parseVertex = function(input) {
  if (input.length !== 2) return [-1, -1]
  return input.split('').map(x => alpha.indexOf(x))
}

let stringifyVertex = function([x, y]) {
  if (Math.min(x, y) < 0 || Math.max(x, y) >= alpha.length) return ''
  return alpha[x] + alpha[y]
}

let parseCompressedVertices = function(input) {
  let colon = input.indexOf(':')
  if (colon < 0) return [parseVertex(input)]

  let [x1, y1] = parseVertex(input.slice(0, colon))
  let [x2, y2] = parseVertex(input.slice(colon + 1))
  let vertices = []

  for (let i = Math.min(x1, x2); i <= Math.max(x1, x2); i++) {
    for (let j = Math.min(y1, y2); j <= Math.max(y1, y2); j++) {
      vertices.push([i, j])
    }
  }

  return vertices
}

// Inside useTool() this happens:

let foo = data.map(value => parseCompressedVertices(value).map(stringifyVertex))
              .reduce((list, x) => [...list, x])

console.log(foo)
rooklift commented 2 years ago

I guess one can use flat() at the end of the statement, so this line in sabaki.js...

.reduce((list, x) => [...list, x])

Becomes:

.flat(Infinity)

And this likely fixes it. But I don't understand all this code so I leave it to you.

yishn commented 2 years ago

It should be

.reduce((list, x) => [...list, ...x])

But .flat() should also do the trick.