Switch for rock-paper-scissors - swift

I'm trying to make a simple rock-paper-scissors game. To do it I used a switch statement but for some reason it doesn't work properly.
This is the structure I thought of to make this little game:
There are three buttons for Rock,Scissors,Paper, and you have to choose one.
There is a Label that tells what the opponent (computer) chose, and I named it opponentLabel.
There is a Label that tells what the result is ("you won" for example) and I named it resultLabel
and it works like this (this just the way it's structured):
var a = Int()
if the player chooses Rock ---> a = 0
if the player chooses Paper ---> a = 1
if the player chooses Scissors ---> a = 2
For the opponent (computer, not a person) there is a randomNumber which
could be 0,1,2, and same here, if 0->opponent chose rock, if
1->opponent chose paper, if 2-> opponent chose scissors
and then I wrote a switch statement that puts it all together.
The problem is that for some reason, when I run the app, if I choose rock everything works fine, but when I choose paper or scissors the results are wrong.
For example if I choose Paper (a = 1) and the opponent has paper (which means that the random number happened to be randomNumber = 1), the resultLabel is not "DRAW" as it would be supposed to be, but it is "You Lost": paper and scissors don't work !! What am I doing wrong?
Here is the full code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var opponentLabel: UILabel!
#IBOutlet weak var resultLabel: UILabel!
#IBOutlet weak var rockButton: UIButton!
#IBOutlet weak var paperButton: UIButton!
#IBOutlet weak var scissorsButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Hide()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Hide() {
opponentLabel.hidden = true
resultLabel.hidden = true
}
func unHide() {
opponentLabel.hidden = false
resultLabel.hidden = false
}
var a = Int()
var randomNumber = Int()
func randomChoice() {
randomNumber = Int(arc4random() % 3)
NSLog("randomNumber%ld", randomNumber)
}
func gameOn() {
switch(randomNumber) {
case 0:
opponentLabel.text = "The opponent chose : ROCK"
if a == 0 {
resultLabel.text = "DRAW"
} else {
if a == 1 {
resultLabel.text = "YOU WON!"
}
if a == 2 {
resultLabel.text = "YOU LOST!"
}
}
unHide()
break
case 1:
opponentLabel.text = "The opponent chose: PAPER"
if a == 0 {
resultLabel.text = "YOU LOST!"
} else {
if a == 1 {
resultLabel.text = "DRAW"
}
if a == 2 {
resultLabel.text = "YOU WON!"
}
}
unHide()
break
case 2:
opponentLabel.text = "The opponent chose: SCISSORS"
if a == 0 {
resultLabel.text = "YOU WON!"
} else {
if a == 1 {
resultLabel.text = "YOU LOST!"
}
if a == 2 {
resultLabel.text = "DRAW"
}
}
unHide()
break
default:
break
}
}
#IBAction func rockButton(sender: AnyObject) {
a == 0
randomChoice()
gameOn()
}
#IBAction func paperButton(sender: AnyObject) {
a == 1
randomChoice()
gameOn()
}
#IBAction func scissorsButton(sender: AnyObject) {
a == 2
randomChoice()
gameOn()
}
}

In your #IBAction functions, you are comparing 'a' with 0, 1 or 2 instead of giving 'a' that value.
Change your code so instead of a == 0, it's a = 0. Do this for the 3 #IBActions and try it again and it should work.

Related

How can I get the game to show the word after all guesses have been used up?

so I'm new to coding and I've been doing practice games a such to build my skills. I've created this word guessing game and I'm trying to make the game show the word after all guesses have been used up. However, the program doesn't read the code I write to set the label to display the answer. Here is the code I've written so far:
class ViewController: UIViewController {
var listOfWords = ["ladybug", "program", "computer", "language", "glorious", "incandescent"]
let incorrectMovesAllowed = 7
var totalWins = 0 {
didSet {
newRound()
}
}
var totalLosses = 0 {
didSet {
newRound()
}
}
#IBOutlet var letterButtons: [UIButton]!
#IBAction func buttonPressed(_ sender: UIButton) {
sender.isEnabled = false
let letterString = sender.title(for: .normal)!
let letter = Character(letterString.lowercased())
currentGame.playerGuessed(letter: letter)
updateUI()
updateGameState()
}
#IBOutlet weak var scoreLabel: UILabel!
#IBOutlet weak var correctWordLabel: UILabel!
#IBOutlet weak var treeImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
newRound()
// Do any additional setup after loading the view, typically from a nib.
}
func enableLetterButtons (_enable: Bool){
for button in letterButtons {
button.isEnabled = _enable
}
}
var currentGame : Game!
func newRound() {
if !listOfWords.isEmpty{
let newWord = listOfWords.removeFirst()
currentGame = Game (word: newWord, incorrectMovesRemaining: incorrectMovesAllowed, guessedLetters: [])
enableLetterButtons(_enable: true)
updateUI()
} else {
enableLetterButtons (_enable: false)
}
}
func updateUI() {
var letters = [String] ()
for letter in currentGame.formattedWord.characters {
letters.append(String(letter))
}
let wordWithSpacing = letters.joined(separator: " ")
correctWordLabel.text = wordWithSpacing
scoreLabel.text = "Wins: \(totalWins), Losses:\(totalLosses)"
treeImageView.image = UIImage (named: "Tree \(currentGame.incorrectMovesRemaining)")
}
func updateGameState(){
var letters = [String] ()
for letter in currentGame.word.characters {
letters.append(String(letter))
}
let theAnswer = letters.joined(separator: " ")
if currentGame.incorrectMovesRemaining == 0 {
correctWordLabel.text = theAnswer
Thread.sleep(forTimeInterval: 3)
totalLosses += 1
} else if currentGame.word == currentGame.formattedWord {
totalWins += 1
} else {
updateUI()
}
}
}
In addition, I have a structure that is written like this:
import Foundation
struct Game {
var word : String
var incorrectMovesRemaining : Int
var guessedLetters: [Character]
mutating func playerGuessed (letter: Character){
guessedLetters.append(letter)
if !word.characters.contains(letter){
incorrectMovesRemaining -= 1
}
}
var formattedWord: String {
var guessedWord = ""
for letter in word.characters {
if guessedLetters.contains(letter) {
guessedWord += "\(letter)"
} else {
guessedWord += "_"
}
}
return guessedWord
}
}
You need to redraw your UI, this is done with self.setNeedsDisplay(). It notifies the system that the view's contents needs to be redrawn. In your updateUI() you can add this.
Regarding setNeedsDisplay you can get more information here
class ViewController: UIViewController {
var listOfWords = ["ladybug", "program", "computer", "language", "glorious", "incandescent"]
let incorrectMovesAllowed = 7
var totalWins = 0 {
didSet {
newRound()
}
}
var totalLosses = 0 {
didSet {
newRound()
}
}
#IBOutlet var letterButtons: [UIButton]!
#IBAction func buttonPressed(_ sender: UIButton) {
sender.isEnabled = false
let letterString = sender.title(for: .normal)!
let letter = Character(letterString.lowercased())
currentGame.playerGuessed(letter: letter)
updateUI()
updateGameState()
}
#IBOutlet weak var scoreLabel: UILabel!
#IBOutlet weak var correctWordLabel: UILabel!
#IBOutlet weak var treeImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
newRound()
// Do any additional setup after loading the view, typically from a nib.
}
func enableLetterButtons (_enable: Bool){
for button in letterButtons {
button.isEnabled = _enable
}
}
var currentGame : Game!
func newRound() {
if !listOfWords.isEmpty{
let newWord = listOfWords.removeFirst()
currentGame = Game (word: newWord, incorrectMovesRemaining: incorrectMovesAllowed, guessedLetters: [])
enableLetterButtons(_enable: true)
updateUI()
} else {
enableLetterButtons (_enable: false)
}
}
func updateUI() {
var letters = [String] ()
for letter in currentGame.formattedWord.characters {
letters.append(String(letter))
}
let wordWithSpacing = letters.joined(separator: " ")
correctWordLabel.text = wordWithSpacing
scoreLabel.text = "Wins: \(totalWins), Losses:\(totalLosses)"
treeImageView.image = UIImage (named: "Tree \(currentGame.incorrectMovesRemaining)")
self.setNeedsDisplay()
}
func updateGameState(){
var letters = [String] ()
for letter in currentGame.word.characters {
letters.append(String(letter))
}
let theAnswer = letters.joined(separator: " ")
if currentGame.incorrectMovesRemaining == 0 {
correctWordLabel.text = theAnswer
Thread.sleep(forTimeInterval: 3)
totalLosses += 1
} else if currentGame.word == currentGame.formattedWord {
totalWins += 1
} else {
updateUI()
}
}
}
Create a variable that will keep track of how many times you have guessed wrong. Then you can do this:
Use a while statement:
while numberOfTimesGuessedWrong <= 7{
}
//when you have guessed incorrectly 7 times, the compiler will move here:
wordLabel.text = "\(correctAnswer)"
So when you guess incorrectly 7 times, on the 8th time, it will then show the correct answer.

How to have label text change to message after user types in textfield?

So I am very very new to coding in general and I am taking a class learning about creating apps in xcode. We were assigned to make our first app from scratch. My idea was to make a guessing game where the user is given a picture up close, and they are have to guess what it is. I want it where there's a label, textfield and button. They type their guess in the textfield, click the button to check their answer, and then the label text changes saying "you are wrong" or you are correct". I've looked all over and haven't found much on how to change a label's text depending on what is entered in the textfield. I assumed that I would use an if-else statement but it seems like that is only for integers. Any help on what to do? I've connected everything also. Thanks a lot in advance!
There you go:
import UIKit
import WebKit
class ViewController: UIViewController{
var dictionaryForQuestionAndAnswer = ["what is the best way to learn coding?":"trying","who is best person to ask question?":"Google"]
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var textField: UITextField!
var answerIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
questionLabel.text = ""
}
#IBAction func questionClicked(_ sender: Any) {
let random = randomInt(min: 1, max: 2)
if(random == 1)
{
answerIndex = 1
questionLabel.text = "what is the best way to learn coding?"
}
else
{
answerIndex = 2
questionLabel.text = "who is best person to ask question?"
}
}
#IBAction func answerClicked(_ sender: Any) {
if let answer = textField.text
{
if( answerIndex == 1 && answer == dictionaryForQuestionAndAnswer["what is the best way to learn coding?"])
{
questionLabel.text = "You are correct"
}
else if( answerIndex == 2 && answer == dictionaryForQuestionAndAnswer["who is best person to ask question?"])
{
questionLabel.text = "You are correct"
}
else
{
questionLabel.text = "You are wrong"
}
}
}
func randomInt(min: Int, max:Int) -> Int {
return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Output

Why won't swift recalculate the 'if' statement?

I'm trying to create a very simple 'guessing game' where the user has to guess how many fingers the computer has up (maximum 5 fingers).
Here's the thing. When the code executes and I press submit, even when the print logs registers a correct number, the app still prints the if statement for incorrect. Where am I going wrong?
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var fingerInput: UITextField!
#IBOutlet weak var fingerResult: UILabel!
#IBAction func fingerSubmit(sender: AnyObject) {
let realNumberofFingers = Int(arc4random_uniform(6))
print(realNumberofFingers)
if fingerInput != realNumberofFingers {
fingerResult.text = "Gosh darn, that's wrong!"
} else if fingerInput == realNumberofFingers {
fingerResult.text = "Thats right!"
}
}
}
You are comparing the actual UITextField fingerInput with the realNumberofFingers. That is wrong and will always yield false. What you should do instead is parse the string from the fingerInput and check if the integer contained in that string is equal to realNumberofFingers:
#IBAction func fingerSubmit(sender: AnyObject) {
let input = Int(fingerInput.text!)
if let enteredFingers = input {
let realNumberofFingers = Int(arc4random_uniform(6))
print(realNumberofFingers)
if enteredFingers == realNumberofFingers {
fingerResult.text = "Thats right!"
} else {
fingerResult.text = "Gosh darn, that's wrong!"
}
} else {
fingerResult.text = "Please enter a correct guess - an integer!"
}
}

Class 'ViewController' has no initializers - Similar questions couldn't resolve issue

I have searched for similar questions, but they could not resolve my issue, so I hope it's ok, that I am asking it again. Here is my code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var revealLabel: UILabel!
#IBOutlet weak var scoreLabel: UILabel!
#IBOutlet weak var textField: UITextField!
var userGuess: Int
var heldUpFingers: Int
var score: Int = 0
#IBAction func startGame(sender: UIButton) {
userGuess = Int(textField.text!)!
if textField.text == nil {
revealLabel.text = "Please enter a number from 1 to 5"
} else if userGuess > 5 {
revealLabel.text = "Please enter a number from 1 to 5"
} else {
heldUpFingers = Int(arc4random_uniform(5) + 1)
if heldUpFingers == userGuess {
revealLabel.text = "You guessed right!"
score += 1
scoreLabel.text = String(score)
} else {
revealLabel.text = "Wrong, it was \(heldUpFingers)"
}
}
}
}
It gives me the error "Class 'ViewController' has no initializers" in the 3rd line. Thanks in advance!
It is because userGuess and heldUpFingers aren't assigned yet. You can either make these optional by adding a ? after the Int or by setting a default value to them. So either:
var userGuess: Int?
var heldUpFingers: Int?
You will then need to unwrap them/check there not nil later in your code like this:
if userGuess != nil {
//now safely use userGuess!
}
Or
var userGuess: Int = 0
var heldUpFingers: Int = 0

Expected declaration of a conditional statement

I now set up my system of putting the answer in 1 of 4 choices but a weird error appeared:
var optionAnswer:UInt32 = arc4random_uniform(4)
if optionAnswer == 0 { // Expected declaration
optionA.text = secretAnsarrrrr.text
}
if optionAnswer == 1 {
optionB.text = secretAnsarrrrr.text
}
if optionAnswer == 2 {
optionC.text = secretAnsarrrrr.text
}
if optionAnswer == 3 {
optionD.text = secretAnsarrrrr.text
}
the error only appeared on the first conditional and it didn't specify what I needed to do. How do I fix this?
full code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var numA: UILabel!
#IBOutlet var operation: UILabel!
#IBOutlet var numB: UILabel!
#IBOutlet var secretAnsarrrrr: UILabel!
#IBOutlet var optionA: UILabel!
#IBOutlet var optionB: UILabel!
#IBOutlet var optionC: UILabel!
#IBOutlet var optionD: UILabel!
#IBOutlet var level: UILabel!
#IBAction func startTest(sender: UIButton) {
var question:Int = 1
func generateQuestion() {
var answer:Float = 0.0
var randomoperation:UInt32 = arc4random_uniform(4)
if randomoperation == 0 {
operation.text = "+"
}
if randomoperation == 1 {
operation.text = "-"
}
if randomoperation == 2 {
operation.text = "X"
}
if randomoperation == 3 {
operation.text = "/"
}
var randomNumber:UInt32 = arc4random_uniform(1000)
var randomNumber2:UInt32 = arc4random_uniform(1000)
// 1000 is my maximum number for now.
randomNumber += 1
randomNumber2 += 1
func identifyVal() {
if randomNumber < randomNumber2 {
var between:UInt32 = 1000 - randomNumber2
randomNumber = randomNumber2 + arc4random_uniform(between - 1)
//making sure that randomNumber is not smaller than randomNumber2, therefore all results are positive.
}
}
if operation.text == "/" {
identifyVal()
answer = round(Float(randomNumber)/Float(randomNumber2))
}
if operation.text == "+" {
answer = Float(randomNumber + randomNumber2)
}
if operation.text == "-" {
identifyVal()
answer = Float(randomNumber - randomNumber2)
}
if operation.text == "x" {
answer = Float(randomNumber * randomNumber2)
}
secretAnsarrrrr.text = "\(answer)"
numA.text = String(Int(randomNumber))
numB.text = String(Int(randomNumber2))
}
generateQuestion()
}
var optionAnswer:UInt32 = arc4random_uniform(4)
if optionAnswer == 0 {
optionA.text = secretAnsarrrrr.text
}
if optionAnswer == 1 {
optionB.text = secretAnsarrrrr.text
}
if optionAnswer == 2 {
optionC.text = secretAnsarrrrr.text
}
if optionAnswer == 3 {
optionD.text = secretAnsarrrrr.text
}
var correct:Bool?
#IBAction func answerA(sender: UIButton) {
if optionAnswer == 0 {
correct = true
} else {
correct = false
}
}
#IBAction func answerB(sender: UIButton) {
if optionAnswer == 1 {
correct = true
} else {
correct = false
}
}
#IBAction func answerC(sender: UIButton) {
if optionAnswer == 2 {
correct = true
} else {
correct = false
}
}
#IBAction func answerD(sender: UIButton) {
if optionAnswer == 3 {
correct = true
} else {
correct = false
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Long shot- but did you erase a function on that line earlier? If so, comment out the first line, and then erase the "//". Xcode sometimes gets confused.
Side Note: using a switch may work better. Also, consider putting this inside a struct, this would allow you to define a method randomAnswer() that acts on the questions, and then just reference the method in your view. You could also put the different options as Enums as theres only ever 4 of them. :)