0

I am following a Udemy tutorial on app development, and worked on a Tic Tac Toe game. I am absolutely loving my time with app development and have coded in several other languages outside of swift. My issue comes in when I allow the user to enter his/her name on one screen (shown below in first image) and when the "Play" button is hit, it saves the names typed into the text fields and concatenates it with "'s turn" on the second view controller in order to state which users turn it is. At the end of the game I also wish to display who the winner is by name. If I figure out how to use the user data from the first view controller in the second I will be able to figure the coding part out on my own. I have referenced: Accessing variables from another ViewController in Swift but I still am not understanding how this works or if it the same problem I am having. I will attach a picture of both view controllers below and their code. Thanks for the help in advance!

both view controllers

code to the view controller that takes user input:

// MainViewController.swift
// Tic Tac Toe
// main menu/player select

import UIKit

class MainViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var playerOneName: UITextField!
    @IBOutlet weak var playerTwoName: UITextField!

    @IBAction func play(_ sender: Any) {

    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        return true
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

}

code to the actual game:

// ViewController.swift
// Tic Tac Toe
// View Controller game screen

import UIKit

class ViewController: UIViewController {

    // 1 is noughts, 2 is crosses
    var activePlayer:Int = 1
    var activeGame:Bool = true
    @IBOutlet weak var turnLabel: UILabel!
    var gameState = [0, 0, 0, 0, 0, 0, 0, 0, 0] // 0 = empty, 1 = nought, 2 = cross
    let winningCombination = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8],[0, 4, 8], [2, 4, 6]]

    @IBAction func buttonPressed(_ sender: AnyObject) {
        let activePosition = sender.tag - 1

        if gameState[activePosition] == 0  && activeGame{
            gameState[activePosition] = activePlayer

            if activePlayer == 1 {
                (sender).setImage(UIImage(named: "nought.png"), for: [])
                activePlayer = 2
            } else {
                (sender).setImage(UIImage(named: "cross.png"), for: [])
                activePlayer = 1
            }

            for combination in winningCombination {
                if gameState[combination[0]] != 0 && gameState[combination[0]] == gameState[combination[1]] && gameState[combination[1]] == gameState[combination[2]] {
                    // We have a winner!
                    activeGame = false
                    print(gameState[combination[0]])
                }
            }
        }// the spot will only be taken by the player if it is not taken yet

    }


    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.
    }

}

also note that I had tried saving the data on the users device using:

UserDefaults.standard.set(playerOneName.text forKey: "playerone")

I also saw a similar question on here that stated that variables are public and can be used throughout, my issue is I want the names saved when the button is pressed and declaring them public/static there does not work either.

B2Fq
  • 876
  • 1
  • 8
  • 23
  • what exactly you need to store value publicly or only for two vc ? – Pravin Tate Jun 29 '18 at 02:02
  • @PravinTate a bit confused by your question, but I want to save the two names the players type in on the first VC and use them in the second. Let me know if you still need explaining. – Jeremy McArthur Jun 29 '18 at 02:06
  • So after getting two players name in first vc and tap on play button, create one Modal which stored both player name using array and write init method for second vc and pass it that modal. – Pravin Tate Jun 29 '18 at 02:09
  • @PravinTate Okay this all makes sense to me, but the init method. Anything you know of that I can familiarize myself with this to use it? Thanks for your help by the way! – Jeremy McArthur Jun 29 '18 at 02:11
  • check below answer which I tried to explain you. – Pravin Tate Jun 29 '18 at 02:13

1 Answers1

0

I'd suggest a 3rd class to abstract Player info and make it Singleton. Something like this:

class Players {
    static let shared = Players()

    var one: String {
        get {
            return UserDefaults.standard.object(forKey: "playerone") as? String ?? ""
        }
        set(newValue) {
            UserDefaults.standard.set(newValue, forKey: "playerone")
        }
    }
}

And access/set same like this:

Players.shared.one = "Name one"
print(Players.shared.one)
Sunil
  • 728
  • 5
  • 7
  • Would this class be in the VC for the main menu, or the game? If it is in the main menu like I assume, I will be able to access it with: Players.shared.one = "Name one" print(Players.shared.one) like you stated? – Jeremy McArthur Jun 29 '18 at 02:13
  • You can declare/access this class anywhere in your project: A new file or end of the file of your VC class – Sunil Jun 29 '18 at 02:14
  • also just a side question since im still new, should setter/getter methods be used in app dev too? – Jeremy McArthur Jun 29 '18 at 02:15
  • Thanks a ton! I'll work with this. This will help solve a lot of problems in the future and is good to know. Much appreciation to the both of you for your help! – Jeremy McArthur Jun 29 '18 at 02:15
  • @JeremyMcArthur You can use getter/setter wherever you think they might help. There's no restriction otherwise – Sunil Jun 29 '18 at 02:16