How do I iterate through one array and move every other element to two new arrays in Swift? - arrays

I do realize similar questions have been asked before, I looked at them before seeking help. But they were either not in Swift or too complex for me to decipher. My question is different from How do I shuffle an array in Swift? in that I have already done some of the work, like shuffling. The title was actually different from the question asked, which was "How do I randomize or shuffle the elements within an array in Swift?" I am only interested in iterating the resulting array and I couldn't separate that part from the rest of the code in the answers given for a question that encompassed so much more. That said, there are some great suggestions on that page so I think people like me will benefit from having both pages available. Maybe someone can set up a reciprocal link on that page as I have done here.
Admittedly, I am new to Swift and not a seasoned programmer in any language, but please don't assume I am coming here seeking help without trying to figure it out on my own. I am spending many hours learning the fundamentals of all C based languages and reading the Swift literature at developer.apple.com.
So the question will be more obvious, I and attempting to build the card game War. Thus far I have accomplished constructing the (an array) deck of cards and randomized it (shuffled). I am stuck at looping through the resulting array of 52 objects and assigning (moving) them to the two players hands (two new arrays). I'm not sure how much of my code I should display in order to help me but if you need more, I'll gladly provide it. Please note that this is only an exercise, practice for me to learn how to write complex programs, and some code, like the function to randomize, is not mine, I found it right here at stackoverflow. I'd almost prefer if you didn't just hand me the code that will work, I'm not likely going to learn as much that way, but if providing steps in plain English so I can figure out the syntax is too much trouble, so be it, provide an example, I'm sure I'll get plenty of chances to write/use the syntax later.
One more note, I'm only working in a playground at the moment, when and if I can get all the code working, I'll move to the UI stuff.
Thanks in advance, Rick
/* Skipping past everything I did to get here,
the array (shuffledDeck) has 52 shuffled cards (elements) in it.
The array is NSMutableArray and contains strings like
2Hearts, 5Spades, 14Clubs, etc. Each suit has 14 cards.*/
shuffledDeck
// create vars to hold shuffled hands
var playerOneHand = []
var playerTwoHand = []
/* Started a for loop to assign cards to each hand
but don't know which method(s) is/are best to use
to remove the first or last card and alternately
append (move) it to the (hopefully) initialized
variables playerOneHand and PlayerTwoHand.
Optionally, since the cards are already shuffled,
I could just split the deck using the range method,
whichever is easier. I tried and failed at both ways.*/
var i = 0
for dealtCard in shuffledDeck {
}

var shuffledDeck:[String] = ["2Hearts", "5Spades", "14Clubs", "etc"]
//shuffledDeck will of course be your shuffled deck
var playerOneHand:[String] = []
var playerTwoHand:[String] = []
for (index, cardString) in enumerate(shuffledDeck) {
if index % 2 == 0 {
playerOneHand.append(cardString)
}else{
playerTwoHand.append(cardString)
}
}
I’m looping through every item in the shuffledDeck, but with that I use the index of the array to get a number. I use this number to see if that number devided by 2 is equal to 0 (the number is even) or not (uneven) if a number is even, I get the item that is in the array at the given index and add that item to the hand of player one. If the index is uneven I add the item to the second player’s hand. This means the first item goed to player one’s hand, the second item goes to the hand of the second player. the third Item goes back to the first player and so on.

As mentioned by Martin R you can use the range method to assign the first half of the deck to the first player and the second to the second player as follow:
let cards:[String] = ["2♦️","3♦️","4♦️","5♦️","6♦️","7♦️","8♦️","9♦️","T♦️","J♦️","Q♦️","K♦️","A♦️","2♠️","3♠️","4♠️","5♠️","6♠️","7♠️","8♠️","9♠️","T♠️","J♠️","Q♠️","K♠️","A♠️","2♥️","3♥️","4♥️","5♥️","6♥️","7♥️","8♥️","9♥️","T♥️","J♥️","Q♥️","K♥️","A♥️","2♣️","3♣️","4♣️","5♣️","6♣️","7♣️","8♣️","9♣️","T♣️","J♣️","Q♣️","K♣️","A♣️"]
extension Array {
var shuffled:[T] {
var elements = self
for index in 0..<elements.count - 1 {
swap(&elements[index], &elements[Int(arc4random_uniform(UInt32(elements.count - 1 - index))) + index])
}
return elements
}
}
let cardsShuffled = cards.shuffled
let playerOneHand = cardsShuffled[0...25]
let playerTwoHand = cardsShuffled[26...51]
Note: The shuffle extension was created using this answer as reference

Related

Swift Similar Element Array

If I have an array with elements linked to xassets with names like "card1", "card2", etc up to "card100" is there a quicker way to write these elements in the array format without having to write out all 100?
Also if this has been answered already please let me know or link to it. About 2 days into trying to teach myself to program.
Not exactly sure what you're asking but you may want to look at loops - Swift Loops. You can add items to an array in a for loop from 1 to 100.
Is this what you are looking for ?
let cards = Array(1...100).map({"card\($0)"})

AS3: Array Guidance

Ok so I'll start off with what I am trying to do here with an Array. So I have a grid of 1-59, Now the user gets to pick 5 numbers. When the user picks a number it goes into a box in the top corner of the screen. So what I am trying to make an Array for is a user selects a number it goes into the first box then the second number goes into the second one and so on.
I am still new to AS3 and I have been reading about Arrays, but I'm still stuck on how to do this or even start it. Thanks for the help guys.
Well, you know you need five elements in the array, so:
private var m_arr:Array = new Array(5);
That'll get you an array with five elements, which can be filled later.
Next, it sounds like you need to keep track of which number gets picked first, which number gets picked second, and so on. So let's make a place-holder and initialize it to 0:
private var m_iNextElement:int = 0;
Then whenever they select a number, just say:
m_arr[m_iNextElement] = theNumber;
m_iNextElement++;
As Fygo already mentioned, you could just do this instead:
private var m_arr:Array = new Array();
.
.
.
m_arr.push(number1);
.
.
.
m_arr.push(number2); // and so on
Whichever is better depends on the situation. Last, you need to find some way to tie each element of the array to a graphical element of some sort. There are many ways you could do this, but if you're using MXML, you could consider making the array bindable:
[Bindable]
private var m_arr:Array = new Array(5);
Then you could have in the MXML:
<local:Box id="box1" text="{m_arr[0]}" />
<local:Box id="box2" text="{m_arr[1]}" /> <!-- etc. -->
var nums:Array = [];
//when the user picks whatever number, you call:
nums.push(the_number_that_the_user_selected);
Is that all you wanted to achieve?
Actionscript offers your basic index array [] and associative array {} as well as some fancier ones like vector. It sounds like you simply need to do something with an index array.
Check out this tutorial, it's all about shuffling arrays. http://code.tutsplus.com/tutorials/quick-tip-how-to-randomly-shuffle-an-array-in-as3--active-8776

AS3: No hittest detection after a certain amount of movieclips in an array

I realise the description is a bit vague, I couldn't explain the issue without showing the code!
Basically I have made a game in AS3 which incorporates a character moving around a platform style level collecting items. The items are all seperate movieclips of the same instance (vinyl1a).
References to each item in the level are stored in an array as shown:
vinylArray=[mapbg.misc.vinyl1, mapbg.misc.vinyl2, mapbg.misc.vinyl3, mapbg.misc.vinyl4,...]
The actual array goes up to 40 items. Collision detection is done through a for loop as shown here:
var i:int;
for (i=0; i < maxVinyl; i++){ //iterate from 0 to maximum amount of vinyl
if (woody.hitTestObject(vinylArray[i])) { //checks if woody collides with vinyl
if (vinylArray[i].visible == true) { //checks if the vinyl has already been taken
vinylArray[i].visible = false; //removes vinyl from map
vinylCollected++; //adds to score
updateScore();
}
}
}
In this scenario 'woody' is the character. Now, the issue is, I have had it working perfectly fine for up to 10 'vinyl' items, which covers the first 3 levels of the game. Now I have progressed into the 4th level and I have added more 'vinyl' movieclips to the map (the array has always had 40 values but the for loop only iterates up to 'maxVinyl' which is set for each individual level) and for some reason the collision detection just isn't working.
There are no error messages, and the first 10 movieclips are still detected correctly, but 11 onwards isn't.
Any help would be greatly appreciated - and if you need more information on the problem please ask!
Cheers
EDIT: Forgot to mention, I tested more than 10 vinyl on the first level and the detection works - the situation is that all of the vinyl movieclips are stored in seperate key frames for each level, within a movieclip called misc. So I can do 10+ on the first level but that seems to be it..
I would imagine what is happening is that maxVinyl is not set to the correctly length of the array.
A simple :
maxVinyl = vinylArray.length;
BEFORE the for loop should ensure that all objects in that array are hitTest as desired.
Based on some of the comments, it sounds like there are some other issues with your approach that might be the larger issue.

How can I create arrays within a loop (within another loop) and pass them back out in Javascript?

I'm using Google Docs Spreadsheet API to keep track of a competition between some of my friends. I have some big ideas, but I'm stumped right now. I'm trying to create 20 different arrays inside of loops (see below) and then evaluate each one outside of the loop, and I really don't want to write 20 "if...then" statements.
NOTE: the following SUMMARY may or may not help you answer my question. You might want to skip down to the code, then read this if you need it :)
Summary of the program: Each player assigns point values in favor of one possible outcome of a set of binary-outcome events. As the events happen, players either gain the points assigned if their outcome occurs, or gain no points if the opposite outcome occurs. My goal is to 1) figure out exactly when a player is eliminated, and 2) highlight all remaining events that must be won for them to have a chance at tying for first.
Instead of trying to somehow evaluate all possibilities (5 players picking, 2^16 outcomes... I have zero computer science knowledge, but this seems like an incredibly huge task even for the modern computer) I've come up with an alternate idea. The script loops through each player, against each other opponent. It calculates the maximum number of points a player can score based on their value assignments and the already determined game. For one player and one opponent, it checks the best possible outcome by the player against that opponent, and if there is any opponent he cannot beat, even in the best case, then he is eliminated.
This part is easy-- after the loop runs inside the loop, I just adjust a global variable that I created earlier, and when the outer loop is done, just grab those variables and write them to the sheet.
Unfortunately, this misses the case of where he could have a best case against each individual opponent, but not against multiple opponents at once.
So the next step is what I'm trying to do now. I'm not even sure I can give a good explanation without just showing you the entire spreadsheet w/script, but I'll try. So what I want to do now is calculate the "value" of each event for each player against a given other player. If both player and opponent assigned points in favor of the same event outcome for one event, the event's value is the difference between the picks (positive if player picked higher, negative if lower), and it's the SUM if they picked opposite event outcomes. Now, I do the same thing as before-- take a best-case scenario for a player against a given opponent-- but now I check by how much the player can beat the opponent in a best-case scenario. Then I evaluate the (absolute value of the) event value against this difference, and if it's greater, then the event is a must win (or must lose if the event value is negative). And, if an event is both a "must-win" and a "must lose" event, then the player is eliminated.
The problem is that this second step requires me to create a new array of values for each player-opponent combination, and then do things with the values after they're created.
I realize one approach would be to create 20 different arrays, and throughout the entire loops, keep checking "if (player == "1" && opponent == 2){}" and populate the arrays accordingly, but this seems kind of ridiculous. And more importantly, this entire project is my attempt at learning javascript, so what's the point in using a time-intensive workaround that doesn't teach me anything new?
I'm trying to understand square bracket notation, since it seems to be the answer to my question, but a lot of people are also suggesting that it's impossible to create variable names by concatenating with the value of another variable... so anyway, here's what I'm trying. I'd really appreciate either a fix to my approach, or a better approach.
for (var player=1; player<6; player++){
if(player==1){look up certain columns in the spreadsheet and save them to variables}
//ditto for other players
for(var opponent=1; opponent<6; opponent++){
if(player!=opponent){
if(opponent==1){save more values to variables}
//ditto for other players
for(var row=9; row<24; row++) {
//Now the script goes down each row of an array containing the original
//spreadsheet info, and, based on information determined by the variables
//created above, get values corresponding to the player and opponent.
//So what I'd like to do here is create "array[1,2]==" and then "array[1,3]=="
//and so forth, creating them globally (I think I understand that term by now)
//so I can refer to them outside of the loops later to do some evaluatin'.
}
}}
//get array[1,2]...array[5,4] and do some operations with them.
Thanks for getting through this little novel... really looking forward to your advice and ideas!
How can I create arrays within a loop (within another loop)?
Code update 2
As you said: "i am trying to understand square bracket notation" You may take a look at my new demo and the code:
function getTeam(){
var array = [[1,2,3],[4,5,6],[7,8,9]]; // arrays within arrays
// array myTeam
var myTeam = [[],[],[],[]];
var playerNames = ["John", "Bert", "Dave", "Milton"];
var ages =[];
var weight = 104;
// loop over the team arrayadd each player (name, age and weight) to the team
for (i=0; i < myTeam.length; i++){
// fill the age array in a loop
for (j=0;j<myTeam.length;j++) {
ages[j] = 23 + j;
}
myTeam[i].push([playerNames[i], ages[i], weight]);
}
return myTeam;
}
And pass them back out in Javascript
Could you elaborate on this part?
Update
var valuesOfPlayers=[];
for (var player=1; player<6; player++){
// look up certain columns in the spreadsheet and save them to variables
// you could call a funcntion and return the values you
// collected in an array within an array as in the demo above
valuesOfPlayers[player] = lookupColumnValues(player);
for(var opponent=1; opponent<6; opponent++){
if(player!=opponent){
// save more values to variables
valuesOfPlayers[player] = addValuesToVar(player);
}
for(var row=9; row<24; row++) {
// if you collect the values in your first and second if clause
// what other information do you want to collect
// Please elaborate this part?
}
}}
One workaround:
I could create an array before the execution of the loops.
At the start of each loop, I could push a string literal to the array containing the value of player and opponent.
After the loops are done, I could split the array into multiple arrays, or just evaluate them in one big array using regular expressions.
I'd still rather create new arrays each time-- seems like it is a more universal way of doing this, and learning how would be more educational for me than using this workaround.

Explaining nested arrays to a programmer [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
How have you explained nested arrays to a programmer. I'm thinking someone that has an entry level understanding of programming, but is trying to do more complicated coding.
The array with array works, but they can't quite get their mind around the idea.
Edit: example of a nested array:
array(
'array1' => array(
'key1' => 'val1',
'key2' => 'val2',
),
'array2' => array(
'key1' => 'val1',
'key2' => 'val2',
),
);
Of course, they are usually more complicated than this and maybe that's the problem.
Tell them to think of an array as a list- it helps to give them something less abstract, like a grocery list. Then, a nested array is simply a list of lists.
Maybe I have a todo list, a grocery list, and a wishlist at amazon.com . Now I have a list of all of my lists, and I can look at all of those elements in each list by stepping through them.
A nested array is a set within a set. So, a library has a set of books, a book has a set of chapters. A chapter has a set of paragraphs, a paragraph has a set of sentences. A sentence has a set of words.
For each book in library
For each chapter in book
For each paragraph in chapter
etc...
How have you explained it? It doesn't seem like a big jump for someone that understands one dimensional arrays to be able to grasp the concept that instead of an int or a string that each array element contains another array instead.
Perhaps an analogy comparing directories will help, a one dimensional array would be analogous to a directory that contains a bunch of files, a two-dimensional array to a directory which contains several other directories, each containing a bunch of files, etc.
Draw it.
A variable is a box
1 dimensional array is a row of boxes.
2 dimensional array is a grid of boxes.
3 dimensional array is a cube of boxes.
If they have having trouble with the general concept, don't attempt to visually explain 4 dimensions.
Use a bitmap as an example. In C, you can make a bitmap of an X like this:
int x[5][5] = {
{ 1,0,0,0,1 },
{ 0,1,0,1,0 },
{ 0,0,1,0,0 },
{ 0,1,0,1,0 },
{ 1,0,0,0,1 }
};
Then show them how to use nested for loops to display the bitmap.
Examples always help, and this also gets them to think of nested arrays as multi-dimensional arrays. Actually it's probably better to understand multi-dimensional arrays in a language like C before learning about the "nested" arrays in languages like Python where you can have different levels of nesting in the same array.
Sports can provide appropriate analogies to describe applying nested arrays. A team is an array of people, a competition is an array of teams that play against each other.
However its a case of finding the analogy that clicks with the learner. Find the right analogy and you'll get even the slowest of learners to understand. Just ensure you're analogies are water tight. Like abstractions, they are leaky.
A concrete example is the index at the back of a book. A list of words, each word associated with a list of page numbers.
apples - 1, 2, 3-4
bears - 32-35, 79, 83
cats - 14, 15
If you are looking at C type, non-ragged, arrays, comparing it to numbers, the base 10 part, and there digits might help. Another good source for this same effect would be time as it has a non uniform base 60s = 1m, 60m = 1h, 24h = 1day, 7day = 1week
2 dimensions is easy to explain. Just think of a table. 3 dimensions just think of a cube or other 3d image. 4 dimensions think of a series of images like a movie with the 4th dimension being time.
4+ dimensions is hard to visualize using that model. But think of it as a filing cabinet with another file cabinet inside helps. You open the drawer and out pops a filing cabinet. You find the drawer you want and open that drawer and out pops another filing cabinet....over and over until finally you get your paper.
Perhaps you are explaining it from the context of someone who understands an array of arrays. I would attempt to trick them into realizing that they already understand them by starting at the smallest(read inner array)...and slowly expanding out, giving them plenty of time to ask questions until they are done.
Drawing helps, but you need to give the student in this case some information and go slowly, most programmers I know tend to go to fast and to like to explain things EVEN when the listener no longer is tracking what is being said.
I am a metaphor guy, so I would probably cook something up about a series of boxes with each one numbered, each box then containing a similiar(but much smaller series) also numbered. I would take this to only two levels get understanding and then perhaps talk about 3 dimensions for confirmation. But I would avoid 4 dimensions on the grounds that they may get hung in the idea that there is no such thing as 4 dimensions, or you can't measure time, or other such metaphorical landmines/distractions...cause that's the other problem, programmers tend to be ADD and enjoy getting side tracked.
Also why aren't you using a hash of hashes, much easier to reference. :)
Bottom line, baby steps.
an array is just an object - a thing. everything should be simple to understand once they get that

Resources