examples/2048/2048/board.go
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
}
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
}
// Move enqueues tile moving tasks.