Swift var score does not increase - swift

var players : [Player]?
var currentplayerIndex = 0
var currentQuestion : QuestionObject!
var questions = Questions()
var score = 0
var currentQuestionPos = 0
func updateUi() {
if let score = players?[currentplayerIndex].score {
playerPoints.text = "Points: \(score)"
}
}
func loadnextQuestion () {
if(currentQuestionPos < questions.questions.count) {
currentQuestionPos += 1
if currentplayerIndex < players!.count - 1 {
currentplayerIndex += 1
} else {
currentplayerIndex = 0
}
playerTurn.text = (players?[currentplayerIndex].name)
currentQuestion = questions.questions[currentQuestionPos]
questionText.text = currentQuestion.question
}
}
#IBAction func submitButtonPressed(_ sender: UIButton) {
let i = pickerView.selectedRow(inComponent: 0)
if(currentQuestion.answer == i) {
players?[currentplayerIndex].score += 1
loadnextQuestion()
updateUi()
} else {
updateUi()
loadnextQuestion()
}
}
}
My score displays only 0 all the time.
Does not increase when the answer is right.
All the added players get 1 question each but the sore is still 0 for all the players.

Your code doesn't work because you are doing this series of things when the answer is correct:
players?[currentplayerIndex].score += 1
loadnextQuestion()
updateUi()
The player's score is indeed incremented. But notice that the next thing you do is loadnextQuestion(), which increments currentplayerIndex. This causes updateUi to update the label's text to the score of the next player, not of the player that just answered the question correctly.
One way to fix this is to swap the last two lines:
players?[currentplayerIndex].score += 1
updateUi()
loadnextQuestion()
Notice that this is the same order as in the else branch, which you wrote correctly.
This causes the label to always display the score of the last player, which might not be desirable. Assuming there's not like 100 players or something crazy like that, I think it would be a much better UX if you display all the player's scores:
func updateUi() {
if let scores = players?.map({ "\($0.score)" }) {
playerPoints.text = "Points: \(scores.joined(separator: ", "))"
}
}

You can replace the button action work
#IBAction func submitButtonPressed(_ sender: UIButton) {
let i = pickerView.selectedRow(inComponent: 0)
if(currentQuestion.answer == i) {
players?[currentplayerIndex].score += 1
updateUi()
loadnextQuestion()
} else {
updateUi()
loadnextQuestion()
}
}

Related

In Swift, I got EXC_BAD_ACCESS (code=1, address=0x1fedad19a120) while executing Peterson's Algorithms

circumstance
I executed below code for checking Peterson's Algorithms in sample app not playgrounds.
If code will correctly be executed, I will get sum as 0
But instead, I got error message 😭
⬇️ error message
🤔 Question
I can't understand why this message popped up.
Could you help me teach some reason about why this happen?
⬇️ Code
class ViewController: UIViewController {
var group = DispatchGroup()
var sum = 0
var flag = [false, false,false , false ]
var turn = 0
override func viewDidLoad() {
super.viewDidLoad()
var queue = DispatchQueue(label: "producer")
var queue2 = DispatchQueue(label: "consumer")
queue.async(group: group) {
self.producer()
}
queue2.async(group: group) {
self.consumer()
}
group.notify(queue: .main) {
print(self.sum)
}
}
func producer() {
for i in 0..<10000 {
flag[0] = true
turn = 1
while flag[1] && turn == 1 { }
sum += 1
flag[0] = false
}
}
func consumer() {
for i in 0..<10000 {
flag[1] = true
turn = 0
while flag[0] && turn == 0 { }
sum -= 1
flag[1] = false
}
}
}

Setting random element to a variable in Swift

I'm trying to make a game where you press the back of a card, it displays a random card and then removes that card from the card deck array. When I simulate the program it runs for a random amount of times and then gives me the Index out of range error.
Does anyone see where I have done something wrong?
var cardDeck = [card1, card2, card3 etc....]
var randomCard: Int = 0
#IBAction func row1card5tap(_ sender: UITapGestureRecognizer) {
randomCard = Int.random(in: 0...51)
if cardDeck.contains(cardDeck[randomCard]) {
row1card5.image = cardDeck[randomCard+1]
cardDeck.remove(at: randomCard)
print("removed:" + "\(cardDeck[randomCard])")
} else {
print("card already removed")
}
}
You should make sure the array count is bigger than the requestedIndex + 1 before subscripting
var cardDeck = [card1, card2, card3 etc....]
var randomCard: Int = 0
#IBAction func row1card5tap(_ sender: UITapGestureRecognizer) {
randomCard = Int.random(in: 0...51)
if cardDeck.count > randomCard + 1 {
row1card5.image = cardDeck[randomCard+1]
cardDeck.remove(at: randomCard)
print("removed:" + "\(cardDeck[randomCard])")
} else {
print("card already removed")
}
}
If you want
it displays a random card and then removes that card from the card deck array
then the upper bound of the random array should be always the current number of cards in the deck
var cardDeck = [card1, card2, card3 etc....]
#IBAction func row1card5tap(_ sender: UITapGestureRecognizer) {
if cardDeck.isEmpty { return }
let randomIndex = Int.random(in: 0..<cardDeck.count)
row1card5.image = cardDeck[randomIndex]
cardDeck.remove(at: randomIndex)
}

using a swift loop that waits on functions to complete

I'm new and trying to learn and code my first app. A simple app to get started...So I'm trying to make a loop that will perform a series of functions completely for a certain number of times (rounds). I've figured out the body of code and I'm trying to implement DispatchGroup() to wait on the functions to perform:
#IBAction func buttonPush(_ sender: Any) {
let group = DispatchGroup()
while rounds >= 0 {
group.enter()
DispatchQueue.main.async {
if self.isGameStarted == 0 {
self.setTimer()
self.resetVariables()
self.runClock()
self.roundLabel.text = String(self.self.rounds)
group.leave()
} else if self.isGameStarted >= 1{
self.self.isGameStarted = 0
self.timer.invalidate()
group.leave()
}
}
group.notify(queue: .main) {
self.rounds -= 1
}
}
}
Here was the original body pre DispatchGroup(). The issue was that the while loop was completing before the functions could run, I think (best guess). I'm using the latest version of swift as of 11/19/17.
#IBAction func buttonPush(_ sender: Any) {
while rounds >= 0 {
if isGameStarted == 0 {
setTimer()
resetVariables()
runClock()
roundLabel.text = String(rounds)
} else if isGameStarted >= 1{
isGameStarted = 0
timer.invalidate()
rounds -= 1
}
}
}
12/13/17 edit. This works for each button press and while loop commented out. However, with while loop uncommented it goes into infinite loop...
#IBAction func buttonPush(_ sender: Any) {
//while rounds >= 0 {
if isGameStarted == 0 {
setTimer()
resetVariables()
runClock()
roundLabel.text = String(rounds)
DispatchQueue.main.asyncAfter(deadline: .now() + Double(timeRoundTot){
self.rounds -= 1
} else if isGameStarted >= 1{
isGameStarted = 0
timer.invalidate()
}
}
//}
}

UILabel.text is not being set

In my code I am attempting to just set the text of a UILabel. The function doing this is being called, and everything inside it executes as expected, except for the UILabel.text assignment. Below is the gist of the code being run:
override func viewDidAppear(animated: Bool) {
var count2 = count
ref.child(String(count2-3)).observeSingleEventOfType(.Value, withBlock: { (snapshot2) in
var hitterRef = snapshot2.childSnapshotForPath("/Hitter")
var pitcherRef = snapshot2.childSnapshotForPath("/Pitcher")
var playRef = snapshot2.childSnapshotForPath("/Play")
var play = String(playRef.childSnapshotForPath("/Name").value!)
var outs = playRef.childSnapshotForPath("/Outs").value! as! Int
var rbi = playRef.childSnapshotForPath("/RBI").value! as! Int
assignScore(play, outs: outs, rbis: rbi, pitcherSelected: pitcherSelected, ResultsLabel: ResultsLabel, playName: playName, pointDiff: pointDiff)
})
print("successful delay")
count2++
}
func assignScore(play:String, outs:Int, rbis:Int, pitcherSelected:Bool, ResultsLabel: UILabel, playName: UILabel, pointDiff: UILabel){
var playScore = 0.0
print("assign score is running")
if(pitcherSelected == true) {
/*
*Below section covers the outs of the batter selected
*/
//below means that the user has selected the batter
if(outs == 0){
if(play == "Walk") {
//this means that the pitcher walked the batter
playScore -= 0.5
}else {
//means just a regular out
//nothing happens
}
}
}
ResultsLabel.text = "Test Text"
print("Below text test")
}

Swift 2 Counter and reset

I am trying to create a very simple counter where the user taps a button and the text box displays in sequence 1 followed by 2 followed by 3 then resets to 1 and then counts again all using the same button.
My code so far:
class Counter: UIViewController {
var count = 1
#IBOutlet weak var sectors: UITextField!
#IBAction func numberSectors(sender: UIButton) {
if count < 3 {
count+=1
sectors.text = "\(count)"
}
else {
sectors.text = "0"
}
}
}
#IBAction func numberSectors(sender: UIButton) {
if count < 3 {
count += 1
} else {
count = 1
}
sectors.text = "\(count)"
}