I am trying to have two segues which are triggered by If statements. Here is the coding I have so far.
func prepareForSegue(segue: UIStoryboardSegue, AnyObject?) {
if segue.identifier == "SomeoneWon" {
var ThirdVC: WinnerViewController = segue.destinationViewController as! WinnerViewController
ThirdVC.WinnerName = Winner}
else if segue.identifier == "PopUp" {
var PopUpVC: PopUpViewController = segue.destinationViewController as! PopUpViewController
PopUpVC.RoundWinnerPop = RoundWinner}
The If statements are as follows:
if firstrandomnumber > secondrandomnumber && firstrandomnumber > thirdrandomnumber && firstrandomnumber > fourthrandomnumber {
Player1ScoreTotal += 1
self.Player1Score.text = String(Player1ScoreTotal)
Winner = receivedString1
RoundWinner = receivedString1
if Player1ScoreTotal == 5{
performSegueWithIdentifier("SomeoneWon", sender: UIButton())}
else {
performSegueWithIdentifier("PopUp", sender: UIButton()) }}
else if secondrandomnumber > firstrandomnumber && secondrandomnumber > thirdrandomnumber && secondrandomnumber > fourthrandomnumber {
Player2ScoreTotal += 1
self.Player2Score.text = String(Player2ScoreTotal)
Winner = receivedString2
RoundWinner = receivedString2
if Player2ScoreTotal == 5{
performSegueWithIdentifier("SomeoneWon", sender: UIButton())}
else {
performSegueWithIdentifier("PopUp", sender: UIButton())}}
else if thirdrandomnumber > firstrandomnumber && thirdrandomnumber > secondrandomnumber && thirdrandomnumber > fourthrandomnumber {
Player3ScoreTotal += 1
self.Player3Score.text = String(Player3ScoreTotal)
Winner = receivedString3
RoundWinner = receivedString3
if Player3ScoreTotal == 5{
performSegueWithIdentifier("SomeoneWon", sender: UIButton())}
else{
performSegueWithIdentifier("PopUp", sender: UIButton())}}
else if fourthrandomnumber > firstrandomnumber && fourthrandomnumber > secondrandomnumber && fourthrandomnumber > thirdrandomnumber {
Player4ScoreTotal += 1
self.Player4Score.text = String(Player4ScoreTotal)
Winner = receivedString4
RoundWinner = receivedString4
if Player4ScoreTotal == 5{
performSegueWithIdentifier("SomeoneWon", sender: UIButton())
}
else{
performSegueWithIdentifier("PopUp", sender: UIButton())}}
}
The segue works but the information for the variables does not get transferred i.e. the label which is suppose to show the values for "Winner" and "RoundWinner" remain blank. I am new so I hope the mistake is simple. Thanks.
Related
The entire code for my Tic Tac Toe game has been pasted below. It doesn't run due to an error in the Declare Winner function being added after its use. How do I correct this?
Do I simply create it earlier?
Use of local variable 'DeclareWinner' before its declaration. This is what it says. What am I supposed to do?
import UIKit
class GameViewController: UIViewController {
#IBOutlet weak var MainTitle: UILabel!
#IBOutlet weak var Player1Label: UILabel!
#IBOutlet weak var Player2Label: UILabel!
#IBOutlet weak var PlayerTurnLabel: UILabel!
#IBOutlet weak var GameONLabel: UILabel!
var matrix: [[Int]] = [[0,0,0],[0,0,0],[0,0,0]] // 0 - Nothing, 1 - X, 2 - O
var WhosTurn = 0 // 1- Player1, 2- Player2
var Player1 = 0 // 0 - Nothing, 1 - X, 2 - O
var Player2 = 0 // 0 - Nothing, 1 - X, 2 - O
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
StartGame()
}
func StartGame(){
matrix = [[0,0,0],[0,0,0],[0,0,0]] // 0 - Nothing, 1 - X, 2 - O
displayMat(matrix: matrix)
WhosTurn = Int.random(in: 1...2)
if (WhosTurn == 1){ // Player1's Turn and He's X
Player1 = 1
Player2 = 2
Player1Label.text = "Player 1: X"
Player2Label.text = "Player 2: O"
PlayerTurnLabel.text = "Turn: Player 1"
}else {// Player2's Turn and He'll be O
Player1 = 2
Player2 = 1
Player1Label.text = "Player 1: O"
Player2Label.text = "Player 2: X"
PlayerTurnLabel.text = "Turn: Player 2"
}
}
func displayMat(matrix: [[Int]]) {
var TempTag = 1
for i in 0...2 {
for j in 0...2 {
if (matrix[i][j] == 0 ) {
let TempButton = self.view.viewWithTag(TempTag) as? UIButton
TempButton?.setBackgroundImage(nil, for: .normal)
} else if (matrix[i][j] == 1) { //Display X
let TempButton = self.view.viewWithTag(TempTag) as? UIButton
TempButton?.setBackgroundImage(UIImage(named: "X"), for: .normal)
}else if (matrix[i][j] == 2) { //Display O
let TempButton = self.view.viewWithTag(TempTag) as? UIButton
TempButton?.setBackgroundImage(UIImage(named: "O"), for: .normal)
}else {
}
TempTag += 1
}
}
}
#IBAction func ButtonClickedXorO(_ sender: Any) {
var TempObject = 0
if (WhosTurn == 1){ // Player1's Turn and He's X
TempObject = Player1
Player1 = 1
Player2 = 2
Player1Label.text = "Player 1: X"
Player2Label.text = "Player 2: O"
PlayerTurnLabel.text = "Turn: Player 1"
}else {// Player2's Turn and He'll be O
TempObject = Player2
PlayerTurnLabel.text = "Turn: Player 2"
}
guard let button = sender as? UIButton else {
return
}
switch button.tag {
case 1:
if (matrix[0][0] == 0) {
matrix[0][0] = TempObject
JustPlayed()
}
case 2:
if (matrix[0][1] == 0) {
matrix[0][1] = TempObject
JustPlayed()
}
case 3:
if (matrix[0][2] == 0) {
matrix[0][2] = TempObject
JustPlayed()
}
case 4:
if (matrix[1][0] == 0) {
matrix[1][0] = TempObject
JustPlayed()
}
case 5:
if (matrix[1][1] == 0) {
matrix[1][1] = TempObject
JustPlayed()
}
case 6:
if (matrix[1][2] == 0) {
matrix[1][2] = TempObject
JustPlayed()
}
case 7:
if (matrix[2][0] == 0) {
matrix[2][0] = TempObject
JustPlayed()
}
case 8:
if (matrix[2][1] == 0) {
matrix[2][1] = TempObject
JustPlayed()
}
case 9:
if (matrix[2][2] == 0) {
matrix[2][2] = TempObject
JustPlayed()
}
default:
print("Error")
}
}
func JustPlayed(){
displayMat(matrix: matrix)
Winner()
if (WhosTurn == 1) {
WhosTurn = 2
PlayerTurnLabel.text = "Turn: Player 2"
}else {
WhosTurn = 1
PlayerTurnLabel.text = "Turn: Player 1"
}
}
func Winner(){
var Counter = true
if ((matrix[0][0] == matrix[1][1] && matrix[1][1] == matrix[2][2] && matrix[1][1] != 0))
DeclareWinner(WhoWon: matrix[1][1])
}else if ((matrix[2][0] == matrix[1][1] && matrix[1][1] == matrix[0][2] && matrix[1][1] != 0)) {
DeclareWinner(WhoWon: matrix[1][1])
}else {
for i in 0...2{
if (matrix[i][0] == matrix[i][1] && matrix[i][1] == matrix[i][2] && matrix[i][0] != 0){
DeclareWinner(WhoWon: matrix[i][0])
Counter = false
}
}
if Counter{
for i in 0...2{
if (matrix[0][i] == matrix[1][i] && matrix[1][i] == matrix[2][i] && matrix[0][i] != 0){
DeclareWinner(WhoWon: matrix[0][i])
}
}
}
}
func DeclareWinner(WhoWon: Int){
if (WhoWon == Player1) {
// Player1 Won
GameONLabel.text = "Player 1 Won!"
}else if (WhoWon == Player2){
//Player2 Won
GameONLabel.text = "Player 2 Won!"
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
#IBAction func GoBack(_ sender: Any) {
dismiss(animated: true, completion:nil)
}
}
I have this code that gives the wrong result. The combination EE and Aa sometimes gives "black" if I press Aa after selecting EE... Other times it gives the correct result. Any tips?
This is my code:
//genotype
var ext = "ee"
var ago = "aa"
var gre = "gg"
func checkPicture() {
//Base coat regular
if ext == "EE" || ext == "Ee" && ago == "aa" {
baseLayer.image = #imageLiteral(resourceName: "black")
base = String("black")
}
if ago == "Aa" || ago == "AA" && ext == "EE" || ext == "Ee" {
baseLayer.image = #imageLiteral(resourceName: "bay")
base = String("bay")
}
if ext == "ee" {
baseLayer.image = #imageLiteral(resourceName: "chestnut")
base = String("chestnut")
}
//buttons
#IBAction func `extension`(_ sender: UIButton) {
ext = String(sender.titleLabel!.text ?? "ee")
genotype.text = checkGenotype()
eeno.isSelected = false
eema.isSelected = false
eeye.isSelected = false
sender.isSelected = true
checkPicture()
}
#IBAction func agouti(_ sender: UIButton) {
ago = String(sender.titleLabel!.text ?? "aa")
genotype.text = checkGenotype()
aano.isSelected = false
aama.isSelected = false
aaye.isSelected = false
sender.isSelected = true
}
#IBAction func grey(_ sender: UIButton) {
gre = String(sender.titleLabel!.text ?? "gg")
genotype.text = checkGenotype()
ggno.isSelected = false
ggma.isSelected = false
ggye.isSelected = false
sender.isSelected = true
}
It's Simple your condition's are bit confusing
func checkPicture() {
//Base coat regular
if (ext == "EE" || ext == "Ee") && ago == "aa" { // added bracket
baseLayer.image = #imageLiteral(resourceName: "black")
base = String("black")
}
if (ago == "Aa" || ago == "AA") && (ext == "EE" || ext == "Ee") {
baseLayer.image = #imageLiteral(resourceName: "bay")
base = String("bay")
}
if ext == "ee" {
baseLayer.image = #imageLiteral(resourceName: "chestnut")
base = String("chestnut")
}
}
This should resolve your problem. you forgot to add bracket at required places.
Could anyone tell me what is wrong with the logic?
I make a game of Fifteen and faced a problem.
I need to be sure all the fifteen buttons are arranged in a proper way:
logic:
Every time a button is touched
1. function makeMove() changes the position of a button .
2. function checkGameOver() checks whether all the button are arranged properly,
if yes, then function showAlert() make a pop-up window appear.
problem:
when all the buttons are placed, showAlert() does not fire and
I need to touch again any button to get the pop-up window
Thank you.
func makeMove(button: UIButton) {
var currentButtonNumber = button.tag - 1
if ( currentButtonNumber >= 0 && currentButtonNumber <= 15 ) && button.tag != 4 && button.tag != 8 && button.tag != 12 {
guard buttons[button.tag - 1].backgroundColor != .none else {
buttons[button.tag - 1].backgroundColor = .yellow
buttons[button.tag - 1].setTitle(button.titleLabel?.text, for: .normal)
buttons[button.tag].backgroundColor = .none
button.setTitle("", for: .normal)
return
}
}
currentButtonNumber = button.tag + 1
if ( currentButtonNumber >= 0 && currentButtonNumber <= 15 ) && button.tag != 3 && button.tag != 7 && button.tag != 11 {
guard buttons[button.tag + 1].backgroundColor != .none else {
buttons[button.tag + 1].backgroundColor = .yellow
buttons[button.tag + 1].setTitle(button.titleLabel?.text, for: .normal)
buttons[button.tag].backgroundColor = .none
button.setTitle("", for: .normal)
return
}
}
currentButtonNumber = button.tag - 4
if currentButtonNumber >= 0 && currentButtonNumber <= 15 {
guard buttons[button.tag - 4].backgroundColor != .none else {
buttons[button.tag - 4].backgroundColor = .yellow
buttons[button.tag - 4].setTitle(button.titleLabel?.text, for: .normal)
buttons[button.tag].backgroundColor = .none
button.setTitle("", for: .normal)
return
}
}
currentButtonNumber = button.tag + 4
if currentButtonNumber >= 0 && currentButtonNumber <= 15 {
guard buttons[button.tag + 4].backgroundColor != .none else {
buttons[button.tag + 4].backgroundColor = .yellow
buttons[button.tag + 4].setTitle(button.titleLabel?.text, for: .normal)
buttons[button.tag].backgroundColor = .none
button.setTitle("", for: .normal)
return
}
}
}
func showAlert() {
var minutes = 0
var seconds = 0
if timerCounter < 60 {
seconds = timerCounter
} else if timerCounter == 60 {
minutes = 1
seconds = 0
} else {
seconds = timerCounter % 60
minutes = (timerCounter - seconds) / 60
}
let alert = UIAlertController(title: "Congratulations!",
message: "You spent \(minutes) minutes and \(seconds) seconds", preferredStyle: .alert)
let action = UIAlertAction(title: "OK",
style: .default, handler: {
action in
self.setNewGame()
})
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
func checkGameOver() -> Bool {
var isGameOver = false
var rightOrderCounter = 0
for number in 0...14 {
if (buttons[number].titleLabel?.text == String(number + 1)) {
rightOrderCounter += 1
} else {
rightOrderCounter = 0
break
}
}
if rightOrderCounter == 15 {
isGameOver = true
}
return isGameOver
}
#IBAction func moveButton(button: UIButton) {
makeMove(button: button)
if self.checkGameOver() {
self.stopTimer()
self.showAlert()
}
}
Your mistake is using the button's titles as your model. The problem is that setting a button's title with setTitle(:for:) doesn't necessarily happen until after you leave the main thread. So when you check the current titleLabel, it hasn't been updated yet and reflects the previous state.
A better approach is to use an array of Int to model your puzzle, and update the button's titles using this array. Your checkGameOver() method should check the order of this array instead of the button's titles.
The general rule of thumb is: Never use UI elements to store your state
Can someone please add the code to this so I'm able to add a decimal point button?
This is what I have so far, can someone please fill in the code required for the decimal point button. so I can learn from it. please view over the code and let me know what you think.
import UIKit
class ViewController: UIViewController {
var numberOnScreen:Double = 0;
var previousNumber:Double = 0;
var preformingMath = false
var operation = 0;
#IBOutlet weak var label: UILabel!
#IBAction func numbers(_ sender: UIButton)
{
if preformingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Double(label.text!)!
preformingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Double(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton)
{
if label.text != "" && sender.tag != 11 && sender.tag != 16
{
previousNumber = Double(label.text!)!
if sender.tag == 12 //Divide
{
label.text = "/";
}
else if sender.tag == 13//Multiply
{
label.text = "x";
}
else if sender.tag == 14 //Minus
{
label.text = "-";
}
else if sender.tag == 15 //Plus
{
label.text = "+";
}
operation = sender.tag;
preformingMath = true;
}
else if sender.tag == 16
{
if operation == 12
{
label.text = String(previousNumber / numberOnScreen)
}
else if operation == 13
{
label.text = String(previousNumber * numberOnScreen)
}
else if operation == 14
{
label.text = String(previousNumber - numberOnScreen)
}
else if operation == 15
{
label.text = String(previousNumber + numberOnScreen)
}
}
else if sender.tag == 11
{
label.text = ""
previousNumber = 0;
numberOnScreen = 0;
operation = 0;
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Add this #IBAction to your code and hook it to your . button.
If the user presses . before any numbers, the display will be set to 0..
If there are numbers in the display, then . will be appended to the display if there isn't already a decimal point in the number.
Finally, the numberOnScreen will be updated.
#IBAction func decimal(_ sender: UIButton) {
if preformingMath || label.text!.isEmpty
{
label.text = "0."
preformingMath = false
}
else
{
if !label.text!.contains(".") {
label.text = label.text! + "."
}
}
numberOnScreen = Double(label.text!)!
}
I built an binary calculator app, For the numbers I have two variables. previousNumber and numberOnScreen. The idea is to convert the binary numbers to decimals, do the calculation and convert the answer back.
Lets say the first (previousNumber)number I pick is 1010 and the second (numberOnScreen) 10100
var numberOnScreen:Int = 0;
var previousNumber:Int = 0;
var doingMath = false
var operation = 0;
var decimal = 0;
var decimal1 = 0;
var binary:String = ""
var binary1:String = ""
#IBOutlet weak var label: UILabel!
#IBAction func Numbers(_ sender: UIButton) {
if doingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Int(label.text!)!
doingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Int(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
if operation == 3 //adding
{
print(previousNumber, numberOnScreen, decimal, decimal1)
It prints [ 1010, 10100, 10, 10 }
Any ideas why this is happening?
When you hit the = key, you need to update the calculation of decimal1. Move that code to the place where you are processing =:
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
if operation == 3 //adding
{
print(previousNumber, numberOnScreen, decimal, decimal1)
Also, I recommend that you get rid of the magic numbers in your code and replace them with constants. For your key tags, you could define a struct like this:
struct Key {
static let clear = 6
static let equals = 8
static let plus = 3
}
and then your code would read:
if label.text != "" && sender.tag != Key.clear && sender.tag != Key.equals {
which is much clearer.