Skip to content

Instantly share code, notes, and snippets.

@dhiyaulhaqZA
Created July 11, 2019 17:34
Show Gist options
  • Save dhiyaulhaqZA/618d5b06d558b58bb7aa011508c85ec0 to your computer and use it in GitHub Desktop.
Save dhiyaulhaqZA/618d5b06d558b58bb7aa011508c85ec0 to your computer and use it in GitHub Desktop.
class TheGunActivity: OnShootListener, OnReloadListener {
func onShootSucceed(message: String) {
print(message)
}
func onShootFailure(message: String) {
print(message)
}
func onReloadSucceed(message: String) {
print(message)
}
}
protocol OnShootListener {
func onShootSucceed(message: String)
func onShootFailure(message: String)
}
protocol OnReloadListener {
func onReloadSucceed(message: String)
}
struct GunSpecification {
let projectilePerShoot: Int
let maxProjectilePerReload: Int
let color: String
let type: String
}
protocol Gun {
var projectile: Int {get set}
var specification: GunSpecification {get set}
var activity: TheGunActivity {get set}
init(specification: GunSpecification, activity: TheGunActivity)
}
extension Gun {
mutating func shoot() -> Bool {
let isShootSucceed = projectile >= specification.projectilePerShoot
if isShootSucceed {
projectile -= specification.projectilePerShoot
activity.onShootSucceed(message: "Dorrr!. \(projectile) left")
} else {
activity.onShootFailure(message: "Shoot failure. Please reload")
}
return isShootSucceed
}
mutating func reload() {
projectile = specification.maxProjectilePerReload
activity.onReloadSucceed(message: "Reload succeed")
}
}
class Shootgun: Gun {
var projectile: Int
var specification: GunSpecification
var activity: TheGunActivity
required init(specification: GunSpecification, activity: TheGunActivity) {
self.projectile = 0
self.specification = specification
self.activity = activity
}
}
class Deagle: Gun {
var projectile: Int
var specification: GunSpecification
var activity: TheGunActivity
required init(specification: GunSpecification, activity: TheGunActivity) {
self.projectile = 0
self.specification = specification
self.activity = activity
}
}
class CurrentGun {
private var gun: Gun? = nil
func changeCurrentGun(gun: Gun) {
self.gun = gun
print("Weapon changed !")
}
func getSpecification() -> GunSpecification? {
return gun?.specification ?? nil
}
func shoot() -> Bool {
return gun?.shoot() ?? false
}
func reload() {
gun?.reload()
}
}
class TheGunShoot {
private func testTheGun(gun: Gun) {
let currentGun = CurrentGun()
currentGun.changeCurrentGun(gun: gun)
let specification = currentGun.getSpecification()
guard let spec = specification else {
print("You don't have a gun")
return
}
print("Type : \(spec.type)")
print("Color : \(spec.color)")
print("Max Ammo : \(spec.maxProjectilePerReload)")
print("Ammo per shoot : \(spec.projectilePerShoot)")
currentGun.reload()
for _ in 0 ... 4 {
let isShootSucceed = currentGun.shoot()
if !isShootSucceed {
currentGun.reload()
}
}
}
func start() {
let gunActivity = TheGunActivity()
//shotgun is take out one projectiles per shoot
let s12kSpec = GunSpecification(projectilePerShoot: 1 ,maxProjectilePerReload: 3,
color: "Brown", type: "S12K")
let shotgun: Gun = Shootgun(specification: s12kSpec, activity: gunActivity)
//Deagle is take out two projectiles in one shoot
let deagleSpec = GunSpecification(projectilePerShoot: 2 ,maxProjectilePerReload: 3,
color: "Red", type: "Deagle")
let deagle: Gun = Deagle(specification: deagleSpec, activity: gunActivity)
testTheGun(gun: shotgun)
testTheGun(gun: deagle)
}
}
func execute() {
let theGunShoot = TheGunShoot()
theGunShoot.start()
}
execute()
/*
PRINTED ->
Weapon changed !
Type : S12K
Color : Brown
Max Ammo : 3
Ammo per shoot : 1
Reload succeed
Dorrr!. 2 left
Dorrr!. 1 left
Dorrr!. 0 left
Shoot failure. Please reload
Reload succeed
Dorrr!. 2 left
Weapon changed !
Type : Deagle
Color : Red
Max Ammo : 3
Ammo per shoot : 2
Reload succeed
Dorrr!. 1 left
Shoot failure. Please reload
Reload succeed
Dorrr!. 1 left
Shoot failure. Please reload
Reload succeed
Dorrr!. 1 left
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment