Generate Random Func with an array no repeats swift - arrays

I'm trying to learn swift by creating different short games or apps. while trying to test my new gain knowledge on a game, I realized that I need to create a func that I didnt know how to create. I've looked around and none of the answers I've found really helped me understand what I have to do.
I'll summarize my game:
Its a single view app.
I've got five func.
I want to randomly pick a function to be executed.
After the function is executed the user will press a button that runs the random pick function again to randomly pick a func, but this time only out of the four other func that are left, and so on. At the same time once the five functions have been executed I want to restart the pick a random func all over again. so the game goes on and on for ever.
I'm not sure how to place the func In an array to make it work.
For example I've been using the following script in the game.
Func one generates a Label that shows a random string.
I've used the following script to create a random word generator for a label with out repeats and once it runs through all the words in the array it restarts again randomly. (It works perfectly)
struct randword {
var wordstring : String! }
var stentenceword = [randword]
var stentecenumber = Int
func wordsinsentence (){
sentenceword = [randoword(wordstring:"House"), randoword(wordstring:"Truck"), randoword(wordstring:"Ladder")]
}
func pickword(){
if sentenceword.count > 0 {
sentencenumber = random () % sentenceword.count
wordlabel.text = sentecneword[sentencenumber].wordstring
sentenceword.removeAtIndex(sentencenumber)
); if sentenceword.count <= 0{
wordsinsentence() }
Func two generates a random Image using the same script as before, just slightly modified for images.
Func three is a timer game with another script... and so on..etc etc.
Now I want all five func to randomly be picked and removed then once there aren't anymore left to restart, as on the example script I placed above.
I've tried using the same script and modifying it to replace the string! array with a function array, but with no positive result.
Can anyone help me with a solution or showing me another option of how I should do it?

Your question is a little difficult to follow, but let's focus on your most clear questions:
I'm not sure how to place the func In an array to make it work.
I want to randomly pick a function to be executed.
no repeats
First, to pick values randomly with no repeats you take a list and shuffle it into a random order. There's no need to keep track of previously selected items. Shuffling in Swift is explained very well by Nate Cook at How do I shuffle an array in Swift?
So that brings us to the second question, how do we create an array of functions? That's the simplest part. You just make an array of functions.
func first() { print("first") }
func second() { print("second") }
func third() { print("third") }
let fs = [first, second, third]
That's all there is to it. Now let's put them together and call them in a random order:
for f in fs.shuffle() {
f()
}

I tried to copy paste your code to a playground and try to fix it but its kinda unreadable. Indentation is really good habit especially if someone else has to look at your code. Anyway imagine if you could just say Int.radomOutOf(5) and it just returns some random number between 0 and 5. well you can do just that by adding extension to the class Int or CGFloat or Double as you wish. and have function to keep track of your the games life time and call those random functions. here is how to do it (I hope I didn't forget anything)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textLabel: UILabel!
var randomIndex = Int()
let NumberOfFunctions = 4
var chosenIndexes: [Int] = []{
didSet{
if chosenIndexes.count == NumberOfFunctions { chosenIndexes.removeAll() }
}
}
#IBAction func buttonPressed(sender: UIButton) {
functionSelector()
}
func functionSelector(){
repeat{
randomIndex = Int.randomOutOf(NumberOfFunctions)
print("selected: \(randomIndex) \(chosenIndexes)")
} while chosenIndexes.contains(randomIndex)
chosenIndexes.append(randomIndex)
switch randomIndex {
case 0: function1()
case 1: function2()
case 2: function3()
case 3: function4()
default: break
}
}
func function1(){
textLabel.text = "sentence 1"
}
func function2(){
textLabel.text = "sentence 2"
}
func function3(){
textLabel.text = "sentence 3"
}
func function4(){
textLabel.text = "sentence 4"
}
}
//your extension to pick random
private extension Int {
static func randomOutOf(max:Int) ->Int{
print("max: \(max)")
return Int(arc4random() % UInt32(max)) // returns 0 - max
}
}

This is just to show the first answer runs just fine

Related

Using Go to avoid duplicates from existing array data when appending slices with user input

Forgive all my comments, I'm learning and that keeps me straight. Looking for a better solution to my conditional statement near the bottom and provided the rest for context. Tried out the loop comment suggested, but still not getting the right result as written here
// define the main package file
package main
//importing formatting features for the user I/O and string manipulation packages
//Parenthesis not needed if only importing 1 package
import (
"fmt"
"strings"
)
// defining the main function of the standalone app
func main() {
//initializing a string array
options := []string{"lemon", "orange", "strawberry", "banana", "grape"}
//creating a slice in the array to designate favorites
favFruits := options[0:3]
fmt.Println(options)
//initializing variable for user input
var fruit string
fmt.Print("Favorite Fruit Not Listed: ")
fmt.Scan(&fruit)
//convert response to lowercase
fruitConv := strings.ToLower(fruit)
//conditional statement example
for _, pick := range options {
if pick == fruitConv {
fmt.Println("You were supposed to pick something else")
break
} else {
fmt.Println("Response Accepted!")
break
}
break
}
//adding user inputed favorite fruit to the sliced array
favFruits = append(favFruits, fruitConv)
fmt.Print(favFruits)
}
I got your point. If you go to official Go packages section you will get slices package over there. Ref: slices
There is one function named contains inside the slices package, you can make use of that function. For your simplicity, I have created one example matching with your scenario.
func main() {
//initializing a string array
options := []string{"lemon", "orange", "strawberry", "banana", "grape"}
// assuming fruit as user input
fruit := "lemon"
//conditional statement example
if fruit == "coconut" || fruit == "coconuts" {
fmt.Println("Coconuts are nasty (except on your hair/skin)")
//**there has to be a way to simplify this code if the array grows server-side or something**
} else if slices.Contains(options, fruit) {
fmt.Println("You were supposed to pick something different...")
}
}
Here is the working link :- https://goplay.tools/snippet/bzSm_biR4Vr
Note: Since in your scenario there is lot of such contain checks, I would recommend to use map instead of slice. Internally if you deep dive in conatins function of slice you will get to know.

How can I tie independent values to strings in an array (Swift)?

So I'm practicing coding and I've set up an array of strings. What I want to happen is to have a function randomly select a string and if a certain string is selected, it would print out one message, and if any of the other strings are selected, it would print out a different one. I think setting up the messages could be done w/an if-else function, but I'm stuck on the earlier step of figuring out how to identify which string is called.
I did some searching and found this thread Get Random String from an Array and I copied the randomization code from it. I'm a bit overwhelmed with where to go from there.
What type of function/identifier etc would I need to set up so that the strings are uniquely identified?
class ViewController: UIViewController {
// Make collection of games and if Monsters is called, print "Take a break." If a diff string is called, print "Do your homework."
#IBAction func random(_ sender: UIButton) {
let games = ["Cards Against Humanity", "Mario Kart", "Halo", "Pixeljunk Monsters"]
let randomNumber = Int(arc4random_uniform(UInt32(games.count)))
_ = games[randomNumber]
}
} // end of class
Your expectation is not very clear from your question, but I guess you are beginner and need a help with processing randomly selected string.
#IBAction func random(_ sender: UIButton) {
let games = ["Cards Against Humanity", "Mario Kart", "Halo", "Pixeljunk Monsters"]
let randomNumber = Int(arc4random_uniform(UInt32(games.count)))
let randomlyPickedString = games[randomNumber]
if randomlyPickedString == "Cards Against Humanity" {
print("Print anything you want about Cards Against Humanity")
}
else if randomlyPickedString == "Mario Kart" {
print("Print anything you want about Mario Kart")
}
else if randomlyPickedString == "Halo" {
print("Print anything you want about Halo")
}
else {
print("Print anything you want about Pixeljunk Monsters")
}
}
If its a finite set of values in array, you can even decide to use switch

How can I use this function based on an array to change a label displaying a total of that array in another class?

I have developed a small Swift code that displays somebody's total likes. So I have one code based on a while loop to add up the amount of likes into one total. Then, I created a function that displays a short phrase including the result of that loop. Now, in my view controller I want to run that display function on a label I have created to finally display the all time likes on the screen. However, I can't seem to understand how I should run the display function on the label and have it display without it being a result of me clicking a button first. Keep in mind, this is my second day of coding, with only prior experience in the basic syntax of Java.
Here is the first code
import UIKit
class likesObject: NSObject {
// This is where I created the loop to solve for the total amount of likes
func complimentsLikeTotal() -> Void {
let monthlyLikes = [20, 15, 13, 32, 14, 38]
var totalLikes = 0
var runTotal = 0
while runTotal < monthlyLikes.count {
totalLikes += monthlyLikes[runTotal]
print(totalLikes)
runTotal += 1
}
}
/*
This is where I created the function to return how many all time likes there are in a phrase
I want to use this function in the viewcontroller code on the label
*/
func display() -> String {
return "\(complimentsLikeTotal) all time likes"
}
}
Here is the view controller code
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var inputLikesLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Here is where I don't know what to do with display and how to link it with the label
self.inputLikesLabel.text = display
}
}
Probably looking for something like this: (please make the class name start with capital as per convention)
var likesObject = LikesObject()
likesObject.complimentsLikeTotal()
let display = likesObject.display()
self.inputLikesLabel.text = display
I assume that the LikesObject class also has some global variables defined to hold the data.
P.s. in swift it is not necessary to explicitly state void return value, if you omit it the compiler implies void.

Swift UISlider that gets its values from an array of numbers

I'm a newbie to swift and believe me I've searched and searched for an answer already. I want to create UISliders that get their values from an array of numbers in Swift. Its a camera app so the example array should be obvious.
#IBAction func isoValueChanged(sender: UISlider) {
let isoArray = ["24", "32", "50","64","80","100","125","160","200","250","320","400","500","640","720","800","1000","1250","1600","1800"] // available iPhone 6s ISO settings I believe
let currentValue = // What do I need?
isoText.text = "\(currentValue)"
}
Even harder would be representing shutter speeds from 1/1000 - 32!
From what I see out there this is not an easy one because there is no mathematical representation to calc from the array. Is it even possible?
I'm not quite sure I understand what you want this for but I'm guessing this is right.
// Global Variable or something like this (accessible from multiple functions)
let isoArray = ["24", "32", "50","64","80","100","125","160","200","250","320","400","500","640","720","800","1000","1250","1600","1800"] // available iPhone 6s ISO settings I believe
func functionThatCreatesTheSliderYo(...) {
slider.minimumValue = 0
slider.maximumValue = isoArray.count
slider.continuous = false
}
#IBAction func isoValueChanged(sender: UISlider) {
// instead of Int(val) you may want to round(val) for a better UI
let currentValue = isoArray[Int(sender.value)]
isoText.text = "\(currentValue)"
}
This works for me
#IBAction func isoValueChanged(sender: UISlider) {
let isoArray = ["24", "32", "50","64","80","100","125","160","200","250","320","400","500","640","720","800","1000","1250","1600","1800"]
let currentValue = isoArray[Int(sender.value)]
isoText.text = "\(currentValue)"
}
So simple as it should be in Swift. Many thanks to Ty. Be sure to see the chat though.

Create a function to iterate and cycle through an array in Swift

I'm trying to create a function in Xcode that I can call every time I hit a button to iterate through an array in sequence which then updates the value of the button title.
I can't seem to crack the challenge. I've tried various iterations of while loops and if statements but everytime I run it I end straight up at the last value in the array. Here's the code I've got at the moment, I tried to add a break clause to stop the function from automatically iterating through the whole array but it's now throwing up an error message saying that the code after the return statement will never be executed:
So, I've created an instance of a button within my viewController as follows:
#IBAction func repCount() {
repCountButton.setTitle("\(repCounter.repCount())", forState: UIControlState.Normal)
I'm hoping that this will then update the title of the button with what I return from the repCount function that is called every time the button is pressed.
I've set up the function in a separate Swift file called repCounter and my code for the repCount function is as follows:
var repArray = [1,2,3,4,5]
var repArrayIndex: Int = 0
func repCount () -> String {
if repArrayIndex < repArray.count {
while repArrayIndex < repArray.count {
return "\(repArray[repArrayIndex])"
break
}
repArrayIndex++
} else {
return "\(repArray[0])"
}
}
What I'd like this to do is to cycle through the array every time it is called and once it's got to the end of the array to start cycling from the beginning of the array again.
Thanks in advance for any help!
I'm not at a computer where I can pull up XCode to test it, but I think the version below will do what you want. It isn't the most elegant code, but it is very straightforward. You have to do all the index juggling before the return statement since once the code hits a return, nothing following it will be executed.
I added some code to reset the index once it reaches the end of the array.
var repArray = [1,2,3,4,5]
var repArrayIndex: Int = 0
func repCount () -> String {
while repArrayIndex < repArray.count {
var curIndex = repArrayIndex
repArrayIndex = repArrayIndex + 1;
if repArrayIndex >= repArray.count {
repArrayIndex = 0
}
return "\(repArray[curIndex])"
}
return "\(repArray[0])"
}
Another option to getting this count, without iterating, is to do
// From Swift 1.2
func repCount () -> String {
return count(repArray)
}
// Before Swift 1.2
func repCount () -> String {
return countElements(repArray)
}
If you insist on iterating there are multiple options, see Iterating over an array, one which could be:
var count = 0
for rep in repArray {
count++
}
Or you could for the round trip iteration provided in the other answer, but why do it the hard way, when you don't need to? Or is there something you haven't told us?

Resources