I'm currently writing a game in swift and I'm trying to make use of protocols to define things such as Chapters and Levels etc.
So a chapter might have the following structure:
protocol Chapter {
var title:String {get}
var levels:[Level] {get}
var choices:[OptionSetType]
}
Each Chapter is composed of multiple levels and each level can only be accessed if certain 'choices' have been met.
To accomplish this I will track those choices and use a bit mask to see if conditions have been met. However the choices can be different for each Chapter but I want to build my game mechanics so they don't have to worry about working out which Chapter the user is actually on.
The idea being that each level has a 'Points' value and I just work out if the Points value contains the relevant choices bit mask.
So for 'Level' I tried to define a protocol such as
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
}
which gives an error of
Protocol 'OptionSetType' can only be used as a generic constraint because it has Self or associated type requirements
Now each chapter will in theory have it's own set of options, but I'm wondering how I can make this generic enough so that I can almost code the engine around this, rather than coding to each specific chapter. Which is why I thought I'd create the protocols. The trouble is how can I do the bit masking work when I will need to define set OptionSetType values and can't say the properties will be of a type of OptionSetType. Hope that makes sense?
[In Swift 3, OptionSetType
is now OptionSet
.] Your error occurs because OptionSet
is a protocol and can't be used directly (it 'has Self
or ... requirements).
Your design would likely benefit by creating abstractions for Choice
and Score
- just as you created an abstraction for Level
. Then, if you choose to implement Score
as an OptionSet
, the 'self requirement' will be met. Like such:
struct Score : OptionSet { ... }
struct Choice : OptionSet { ... }
and then:
protocol Chapter {
var title:String {get}
var levels:[Level] {get}
var choices:[Choice]
}
protocol Level {
var text:String {get}
var score:Score {get}
}