import Foundation struct ImageGrid: Codable { struct Position { let x: Int let y: Int } struct Item: Identifiable { let id: Int let cap: Int } let columns: Int /** The place of each cap. The index is the position in the image, where `x = index % columns` and `y = index / columns` */ var capPlacements: [Int] /// All caps currently present in the image var caps: Set { Set(capPlacements) } var items: [Item] { capPlacements.enumerated().map { .init(id: $0, cap: $1) } } var capCount: Int { capPlacements.count } func index(of position: Position) -> Int? { return index(x: position.x, y: position.y) } func index(x: Int, y: Int) -> Int? { let index = y * columns + y guard index < capCount else { return nil } return capPlacements[index] } mutating func switchCaps(at x: Int, _ y: Int, with otherX: Int, _ otherY: Int) { guard let other = index(x: x, y: y), let index = index(x: otherX, y: otherY) else { return } switchCaps(at: index, with: other) } mutating func switchCaps(at position: Position, with other: Position) { guard let other = index(of: other), let index = index(of: position) else { return } switchCaps(at: index, with: other) } mutating func switchCaps(at index: Int, with other: Int) { guard index < capCount, other < capCount else { return } let temp = capPlacements[index] capPlacements[index] = capPlacements[other] capPlacements[other] = temp } static func mock(columns: Int, count: Int) -> ImageGrid { .init(columns: columns, capPlacements: Array(0..