I'm trying to implement a simple game, in iOS using swift. game is turn bases; first player moves, then second player, then first, ... I'm using a protocol for this:
class PersonAgent: AgentProtocol {
let agentType: AgentType = .person
let color: UIColor
var points: Int = 0
private var tappedLine: Line?
init(color: UIColor) {
self.color = color
}
func action() async -> Line {
while self.tappedLine == nil {}
guard let tappedLine = self.tappedLine else { fatalError() }
self.tappedLine = nil
return tappedLine
}
func tapped(line: Line) {
self.tappedLine = line
}
}
when a user taps on a button, view controller calls to tapped function and after that, action method can return something. the problem is phone is getting over heated for a simple game like this. can I reach same functionality without using while? any suggestion to make things more efficient cpu and memory vise?
for making things more clear, I have this code in my view controller:
extension BoardViewController {
private func game() {
print(#function)
Task {
print("inside task")
while self.shouldResumeGame() {
print("Turn Iteration")
var shouldChangeTurn = true
let currentAgent: AgentProtocol
switch self.turn {
case .first:
currentAgent = self.firstAgent
case .second:
currentAgent = self.secondAgent
}
let actionResult = await currentAgent.action()
// some logic here
}
let message: String
if self.firstAgent.points > self.secondAgent.points {
message = "First Player Won"
} else if self.firstAgent.points < self.secondAgent.points {
message = "Second Player Won"
} else {
message = "Draw"
}
// MARK: Game finished
let alert = UIAlertController(title: "Game Finished", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { [weak self] _ in
self?.navigationController?.popViewController(animated: true)
}))
self.present(alert, animated: true)
}
}
private func shouldResumeGame() -> Bool {
return self.firstAgent.points + self.secondAgent.points != 60
}
}
Don't use a
whileloop. This is pollingModern apps use an event-driven approach where events such as user-interaction or a timer firing trigger actions.
For example,
while self.tappedLine == nil {}will execute millions of times per second.You haven't given enough information for me to give you a complete answer, but one way of refactoring your
PersonAgentis to use aCheckedContinuation:Now there is no polling for the line. The
actionfunction creates a continuation and awaits for it to be resumed. Thetappedfunction resumes the continuation with the tapped line.