Помогите найти правильно решение задачи часть 3, глава 9 ?

swift

#1

Создайте псевдоним Chessman для типа словаря [String:( alpha:Character,num:Int)?]. Данный тип описывает шах- матную фигуру на игровом поле. В ключе словаря должно храниться имя фигуры, например «Белый король», а в значе- нии — кортеж, указывающий на координаты фигуры на игро- вом поле. Если вместо кортежа находится nil, это означает, что фигура убита (не имеет координат на игровом поле).
2. Создайте переменный словарь Chessmans типа Chessman и добавьте в него три произвольные фигуры, одна из которых не должна иметь координат.
3. Создайте конструкцию if-else, которая проверяет, убита ли переданная ей фигура (элемент словаря Chessmans), и выводит на консоль информацию либо о координатах фигуры, либо о ее отсутствии на игровом поле.
4. Для получения координат переданной фигуры используйте опциональное связывание.
5. Сохраните данную программу, так как мы вернемся к ней в последующем.

Я решил так, но это не совсем по заданию. Не могу понять как сюда применить опциональное связывание, ругается на код.

typealias Chessman = [String:( alpha:Character,num:Int)?]
var chessmans: Chessman = ["Белый король": (alpha: "A", num: 4), "Белый ферзь": (alpha: "B", num: 7), "Черная пешка": (nil)]
 if chessmans["Белый король"] != nil {
    print(chessmans["Белый король"])
    }
    if chessmans["Белый ферзь"] != nil {
       print(chessmans["Белый ферзь"])
}
if chessmans["Черная пешка"] != nil {
   var chessmans1 = chessmans.keys
    print("Черная пешка нет на игровом поле")
}


//Забегая чуть вперед еще такое решение придумал
typealias Chessman = [String: (alpha:Character,num:Int)?]
var chessmans: Chessman = ["Белый король": (alpha: "A", num: 4), "Белый ферзь": (alpha: "B", num: 7), "Черная пешка": (nil)]

    for var chessmansValues in chessmans.values {
    if (chessmansValues != nil) {
        print(chessmansValues)
    } else {
        print("\(chessmansValues) нет на поле")
    }
}

#2

Наверно что то вроде этого:

typealias Chessman = [String: (alpha:Character, num:Int)?]

let chessmans: Chessman = ["Белый король": (alpha: "A", num: 4), "Белый ферзь": (alpha: "B", num: 7), "Черная пешка": nil]

for (key, value) in chessmans {
    if let coordinates = value {
        print("\(key): \(coordinates)")
    } else {
        print("\(key) нет на игровом поле")
    }
}

#3

Согласен, так правильнее. Но это с использованием for in. А по заданию без него еще нужно решить и применить опциональное связывание.


#4

if let и есть опциональное связывание, на сколько я понял в данном контексте. Если не использовать for, то еще придется проверять есть ли в словаре значение по заданному ключу:

typealias Chessman = [String: (alpha:Character, num:Int)?]   
let chessmans: Chessman = ["Белый король": (alpha: "A", num: 4), "Белый ферзь": (alpha: "B", num: 7), "Черная пешка": nil]
        
if let value = chessmans["Белый король"], let coordinates = value {
    print("Белый король: \(coordinates)")
} else {
    print("Белый король нет на игровом поле")
}

if let value = chessmans["Белый ферзь"], let coordinates = value {
    print("Белый ферзь: \(coordinates)")
} else {
    print("Белый ферзь нет на игровом поле")
}

if let value = chessmans["Черная пешка"], let coordinates = value {
    print("Черная пешка: \(coordinates)")
} else {
    print("Черная пешка нет на игровом поле")
}

Или так:

typealias Chessman = [String: (alpha:Character, num:Int)?]
let chessmans: Chessman = ["Белый король": (alpha: "A", num: 4), "Белый ферзь": (alpha: "B", num: 7), "Черная пешка": nil]

if let coordinates = chessmans["Белый король"] ?? nil {
    print("Белый король: \(coordinates)")
} else {
    print("Белый король нет на игровом поле")
}

if let coordinates = chessmans["Белый ферзь"] ?? nil {
    print("Белый ферзь: \(coordinates)")
} else {
    print("Белый ферзь нет на игровом поле")
}

if let coordinates = chessmans["Черная пешка"] ?? nil {
    print("Черная пешка: \(coordinates)")
} else {
    print("Черная пешка нет на игровом поле")
}

#5

спасибо за мысли и помощь


#6

Пожалуйста, подскажите что такое alpha?


#7

Обозначение буквенных координат шахматной доски.


#8


#9

Меня уже пару дней мучает вопрос, подскажите кто разбирается пожалуйста.
Каким образом пропадает опционал у второй константы в строках
if let value = chessmans["Белый король"], let coordinates = value
value” присваивается опциональное значение “(alpha: "A", num: 4)?
Объявляется новая локальная константа “coordinates” , она получает значение от константы “value” и почему-то это значение уже НЕ опциональное, как так то ? За счёт чего ? Зачем вообще нужна 2-я константа…
Уснуть спокойно не смогу, пока не узнаю =)


#10

Здесь value уже не опционал. Посмотрите внимательно на выражение if: оно получит true, только если произойдёт присвоение значения (если оно есть) константе value.
Это называется optional binding , те “привязывание/развязывание” опционального значения к обычной переменной, если значение опционала не nil. Если опционал будет nil, то сработает ветка else и, соотвественно, value не создастся. Изучите тему подробнее с опционалами - это необходимость.

Урок по опционалам

Ну и присваивать уже неопциональную переменную другой не понятно зачем, если coordinates всё равно внутри области видимости if else. Если нужен доступ за областью видимости if else, то биндите через guard let.

Совершенно правильный вопрос и тут сразу у вас должен возникнуть вопрос об уровне того, кто писал такой код )))

ЗЫ для подсветки кода на форуме используйте кнопку </> - так намного удобнее читать ваш код :wink:


#11

Абсолютно неверно. Мы проверяем словарь по ключу и попали бы в else, если бы такого ключа не было бы.
Тем более вам выше написали:

Если говорить образно, то при if let value = chessmans[“Белый король”] мы проверяем существование такой фигуры вообще в шахматах, а проверкой let coordinates = value смотрим, есть ли эта фигура на поле.

Xcode не дал бы собраться такому коду.

А так да —


#12

Спасибо большое, из ваших ответов понял больше чем из главы книги =)
Нужно будет побольше почитать про опционалы.
Если константу “value” создать вне конструкций “if-else” или “for-in” глобальной, то ей присваивается значение с двумя знаками ?? (подсказка по нажатию Аlt), внутри конструкции уже с одним ? а при передаче значения 2-й константе “coordinates” знак вопроса пропадает. Если для “value” работает правило опциональной привязки, то что происходит с “coordinates” ? Второй уровень опциональной привязки, где отрезается по одному “?” за раз ?

И да, если второй константы нет, Xcode выдает ошибку и не работает, так-же в моей версии кода (скриншот выше) для извлечения значения координат приходится ставить ! иначе Xcode ругается на попытку извлечения опционала.


#13

Да, вы правы, не обратил внимание, что там словарь. Биндится то во второй константе ))) Тут вопрос о моём уровне внимания :rofl: