code: func (b *Board) Move(dir Dir) error {
  	for t := range b.tiles {
  		t.stopAnimation()
  	}
  	if !MoveTiles(b.tiles, b.size, dir) {
  		return nil
  	}
  	b.tasks = append(b.tasks, func() error {
  		for t := range b.tiles {
  			if t.IsMoving() {
  				return nil
  			}
  		}
  		return taskTerminated
  	})
  	b.tasks = append(b.tasks, func() error {
  		nextTiles := map[*Tile]struct{}{}
  		for t := range b.tiles {
  			if t.IsMoving() {
  				panic("not reach")
  			}
  			if t.next.value != 0 {
  				panic("not reach")
  			}
  			if t.current.value == 0 {
  				continue
  			}
  			nextTiles[t] = struct{}{}
  		}
  		b.tiles = nextTiles
  		if err := addRandomTile(b.tiles, b.size); err != nil {
  			return err
  		}
  		return taskTerminated
  	})
  	return nil
  }
docs: // Move enqueues tile moving tasks.