модель

Одно время в App Store была доступна версия Color Lines от Piston Games. У них взял идею что можно использовать несколько пачек M&Ms и попробовать игру в оффлайне.

На данном этапе у нас стоит задача построить математическую модель игры. Поэтому вы можете воспользоваться тем, чем вам удобней и привычней решать задачи, ручкой и листком бумаги, M&Ms или шахматной доской и шашками, либо сразу писать код.  Тем более, что наша программа уже умеет расставлять красные шарики на игровом поле. Причем вы можете загрузить программу на iPhone или iPad и моделировать игровые ситуации там.

struct Lines {
    var cells = Array(repeating: Array(repeating: 0, count:9), count: 9)
}

добавим переменную

var game = Lines()

и изменим код

        game.cells[row][column] = 1
        gameFieldView.cells = game.cells

Сейчас наша программа может расставлять на игровом полем шарики красного цвета. Поставим себе задачу: при выставлении шарика проверять сколько шариков находится по соседству.

Эту задачу у нас будет выполнять функция:

    mutating func dropBall(row: Int, column: Int, color: Int) -> Int {
        var total = 0
        cells[row][column] = color
        total += 1
        return total
    }

и изменим строчку

        let k = game.dropBall(row: row, column: column, color: 1)
        print("raw: \(row), column: \(column), balls: \(k)")

 

 

[row + k * y][column + k* x]
К примеру для шариков, находящихся с права х = 1, y = 0
для шариков, находящихся по диагонали в право и в них: х = 1, y = 1 и т.д.
всего 8 направлений. Напрашивается решение сохранить, соответствующие значения x и y в массив:

    let dir = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1)]

подсчет будем производить в массиве:

var counts = [0, 0, 0, 0, 0, 0, 0, 0]

тогда координаты соседних клеток будут вычисляться по формуле:

[row  + (counts[i] + 1) * dir[i].0][column + (counts[i] + 1) * dir[i].1]

Вопрос с выходом за пределы массива можно решить за счет дополнительного массива test, у которого на два столбца и две строки больше чем у cells, где test[i+1][j+1] = cells[i][j], а первая и последняя строка, первый и последний столбец состоят из -1, т.е значение, которые не может принимать массив cells. Образно говоря, мы, перед тем как проводить проверку массива cells, обставили его вспомогательными значениями.

var test = Array(repeating: Array(repeating: -1, count:11), count: 11)

добавим функцию

    mutating func makeTest() {
        for i in 0..<9 {
            for j in 0..<9 {
                test[i+1][j+1] = cells[i][j]
            }
        }
    }

и посчитаем:

        makeTest()
        for i in 0..<8 {
            while color == test[row + 1 + (counts[i] + 1) * dir[i].0][column + 1 + (counts[i] + 1) * dir[i].1] {
                counts[i] += 1
            }
        }
        print("row: \(row), column: \(column)")
        print("\(counts[0]) \(counts[1]) \(counts[2])")
        print("\(counts[7])   \(counts[3])")
        print("\(counts[6]) \(counts[5]) \(counts[4])")

Текущая весия проекта 02.zip

Посчитаем:

        for i in 0..<4 {
            if counts[i] + counts[i+4] < 4 {
                counts[i] = 0
                counts[i+4] = 0
            } else {
                total += counts[i] + counts[i+4]
            }
        }

и удалим:

        if total > 0 {
            total += 1
            for i in 0..<8 {
                for j in 0..<counts[i] {
                    cells[row + (1 + j) * dir[i].0][column + (1 + j) * dir[i].1] = 0
                }
            }
        } else {
            cells[row][column] = color
        }

Текущая весия проекта 03.zip

    mutating func makeWays(row: Int, column: Int) {
        for i in 0..<9 {
            for j in 0..<9 {
                test[i+1][j+1] = (cells[i][j] == 0) ? -2 : -1
            }
        }
        test[row+1][column+1] = 0
        var k = 0
        var done = false
        repeat {
            done = false
            for i in 1..<10 {
                for j in 1..<10 {
                    if test[i][j] == -2 {
                        if (test[i-1][j] == k) || (test[i][j-1] == k) || (test[i+1][j] == k) || (test[i][j+1] == k) {
                            test[i][j] = k + 1
                            done = true
                        }
                    }
                }
            }
            if done {
                k += 1
            }
        } while done
    }

 

let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center
        let attrs = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Thin", size: 18)!, NSAttributedStringKey.paragraphStyle: paragraphStyle]
        
        var str = "20"
str="\(test[i+1][j+1])"
str.draw(with: imageRect, options: .usesLineFragmentOrigin, attributes: attrs, context: nil)

 

 

Вывод игрового поля Начало Playground