Протокол Swift с членом, имеющим ObjectSetType

В настоящее время я пишу игру по-быстрому и пытаюсь использовать протоколы для определения таких вещей, как главы и уровни и т. Д.

Таким образом, глава может иметь следующую структуру:

   protocol Chapter {
       var title:String {get}
       var levels:[Level] {get}
       var choices:[OptionSetType]
   }

Каждая глава состоит из нескольких уровней, и к каждому уровню можно получить доступ, только если были выполнены определенные "варианты".

Для этого я буду отслеживать эти варианты и использовать битовую маску, чтобы увидеть, были ли выполнены условия. Тем не менее, выбор может быть разным для каждой главы, но я хочу построить свою игровую механику, чтобы им не пришлось беспокоиться о том, над какой главой на самом деле находится пользователь.

Идея состоит в том, что каждый уровень имеет значение "Points", и я просто работаю, если значение "Points" содержит битовую маску соответствующего выбора.

Поэтому для "Уровня" я попытался определить протокол, такой как

   protocol Level {
    var text:String {get}
    var score:OptionSetType {get} // this is what determines if a level can be shown if the right chapter 'choices' have been set
   }

который дает ошибку

 Protocol 'OptionSetType' can only be used as a generic constraint because it has Self or associated type requirements

Теперь теоретически каждая глава будет иметь свой собственный набор опций, но мне интересно, как я могу сделать это достаточно универсальным, чтобы я мог практически кодировать движок вокруг этого, а не кодировать каждую конкретную главу. Вот почему я думал, что создам протоколы. Беда в том, как я могу выполнить работу с битовой маскировкой, когда мне нужно будет определить установленные значения OptionSetType и не могу сказать, что свойства будут иметь тип OptionSetType. Надеюсь, что имеет смысл?

1 ответ

Решение

[В Swift 3, OptionSetType сейчас OptionSet.] Ваша ошибка происходит потому, что OptionSet является протоколом и не может использоваться напрямую (он имеет Self или... требования).

Ваш дизайн, вероятно, выиграет, создавая абстракции для Choice а также Score - так же, как вы создали абстракцию для Level, Затем, если вы решите реализовать Score как OptionSet"Собственное требование" будет выполнено. Вроде такой:

struct Score : OptionSet { ... }
struct Choice : OptionSet { ... }

а потом:

protocol Chapter {
  var title:String {get}
  var levels:[Level] {get}
  var choices:[Choice]
}

protocol Level {
  var text:String {get}
  var score:Score {get}
}
Другие вопросы по тегам