I'm trying to create a game that shuffles and deals cards to each player, stores a deck to draw new cards from and stores a discard pile.
Think of it like a game of poker. Fifty two cards are randomly arranged in a draw pile, then the cards are distributed to the players.
My lack of coding knowledge leads me to ask the following:
- How do I create a system that knows each card (ace of spades, seven of diamonds, etc) and randomizes them into some variable or array in a way that does not duplicate or leave out cards? organized deck > shuffled deck
- How do I manipulate this variable/array/record/datatable to order the cards from top to bottom as they are drawn. So the game isn't just randomly drawing out of the (already randomized) stack but rather in a set order. top card = jack of hearts & second card = two of clubs > draw > top card = two of clubs.
- After these cards are used and all cards are either in the players hands or in the discard pile (which also must be organized) how do I then shuffle the cards from the discard pile (which will be less than 52) into a new draw pile. #cards in deck = 0, #cards in players hands = 15, #cards in discard = 37. > shuffle > #cards in deck = 37, #cards in players hands = 15, #cards in discard = 0.
I'd like to keep the data tidy. So a system containing a variable for your draw pile, one for your discards and one for each players hand is ideal. The system must also be flexible since more cards will be added to the game as I update it. The number of cards each player can carry will vary based on events within the game and all sorts of crap occurs as the cards are played. Sometimes the players will need to take stuff out of the discards, sometimes the game needs to search through the draw stack for a specific card.
something basic I just threw together, it has a sort of draw function and a shuffle function.
map is directly runnable, it has a complete set of cards. (2 through 9, jack, queen, king, ace of each spades, clubs, hearts, diamonds)
-draw draws a card and displays it. it also says when the deck is empty.
-reset deck: restores the deck to the starting data.
-shuffle deck: shuffles the deck.
the deck isn't standardly shuffled. it is just a list of cards from 2 through 9 then Ace, Jack, Queen, King. all suits together.
Thanks Helral. I'm having a bit of trouble reading your map file but I can see some of the triggers and will try to understand it.
I've just figured out how to shuffle an array of intergers within itself. Which could theoretically be used with other triggers to resemble various cards (i.e. 1 = ace of clubs, 2 = two of clubs, 3 = three of clubs, 14 = ace of diamonds etc.)
What I did was fill an array of 100 with numbers ranging from 1 - 100 so it is like such: CardDeck(1) = 1, CardDeck(2) = 2, CardDeck(41) = 41 etc.
-Then create a Array of 3 to fill temporary numbers.
-Then take two of random numbers from the array of 100 and swap them.
Since there is no real 'swap' integer action I used the first two variables in the secondary array to generate two random numbers between 1 and the number of cards in the deck.
Those two numbers are then picked out of the CardDeck(1-100) array and swapped with each other using the third extra variable to temporarily store the value of the first CardDeck variable before it is destroyed.
So it looks like so:
Shuffle
Events
UI - Player Any Player presses Up key Down with shift Allow, control Allow, alt Allow
Local Variables
Conditions
Actions
General - Repeat (Actions) 10000 times
Actions
Variable - Set TempShuffleInt[1] = (Random integer between 1 and 100)
Variable - Set TempShuffleInt[2] = (Random integer between 1 and 100)
Variable - Set TempShuffleInt[3] = DoorCardDeck[TempShuffleInt[1]]
Variable - Set DoorCardDeck[TempShuffleInt[1]] = DoorCardDeck[TempShuffleInt[2]]
Variable - Set DoorCardDeck[TempShuffleInt[2]] = TempShuffleInt[3]
My machine is pretty good but doing this 10000 times doesn't generate a pip of lag and yields indistinguishably random results.
lots of programming classes have you deal with decks of cards. Lots of options for shuffling and managing them. It really depends on how you are using them and how you prefer to work with them... easiest way to randomize the cards is to make a second array of cards, loop through the first array and insert the card randomly into the second one inserting at a random point in the second array (aka, if you have 4 cards in the second array, you will insert the fifth element as element 0-5, when you get to the 6th element, insert it between 0-6, seventh between 0-7). This is nice if your deck is being shuffled when it is not full as you can skip empty elements. It runs in O=n time and isn't complicated. It's not a "truely random" shuffle however...
Another fun way if memory is a problem or just as an exercise, is to loop through the array of cards and swaping each card with a random card in the deck. it doesn't seem like random placement but it is (or at least close enough). this method doesn't work well if random members of the "deck" are missing when you shuffle, but is very quick and memory efficient. You can make modifications to the algorhythm to ensure the deck is "pushed' all the way to the beginning of the array very simply though.
These ways work well if you are doing something like creating a record and having it hold a suit and a rank. These "virtual decks" are fine, and intuitive, but a lot of the time it is easier to deal with a simulated card system.
Use an array of 52 bools (or even better a bit array), and simply use the mod 13 of the card for the suit, and the mod 4 of the card for the rank. When you put a card in a players hand, simply turn the bool off, and insert the array element # into the player's hand as an int. A bit rougher to get your head around, but just as simple and much lighter of a system in terms of coding. This method has it's advantages and disadvantages though.
Out of these three, I'd probably suggest the middle one... it seems the closest to what you are doing and need.
seeing as you've figured out the shuffle idea, you can shuffle then the "array indices" of an card array, so the card array itself is always in the same order, but in the deck array, they aren't sorted. like your shuffle shuffles the array.
You can now just create functions to remove a number from the array and shove the rest up, or let the array remain the same and remove the highest index card remaining. Just use an additional integer to keep track of the available cards. This integer you could also use in your random shuffle bit to prevent your deck from having holes in them. so instead of random 1 to 100 you'll get, random 1 to decksize.
you add the removed number above to a players hand, and retrieve the card information out of an array you have defined at the side. this way you'll just be using an integer to pass about. the card information will stay nice together, if you use a record (or struct for those who use galaxy code). in this record you can e.g. set the following data: Value (A,2,5,K,etc.), Type (Spades, Hearts,etc.) Display Text(Ace of Spades, Two of Hearts, etc.)
Thanks Anthius. The second seemed to be the easiest to make a trigger for so I went ahead and did that one.
*note* while I was writing this Helral posted exactly this information. But alas.
I've also figured out how to remain aware of the top card and shuffle however many cards are in the discard back into the draw stack.
Using a few tools to move cards either to my hand or to the discards (the ones in my hand will not appear again in the draw stack.) I just had to make a reshuffle trigger which looked a lot like the original one but with more crap.
ShuffleDiscards
Events
UI - Player Any Player presses Num Pad 4 key Down with shift Allow, control Allow, alt Allow
Local Variables
Conditions
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Abs(#DoorCardsInDeck)) == 0
Then
General - While (Conditions) are true, do (Actions)
Conditions
(Abs(#DoorCardsInDiscard)) > 0
Actions
Variable - Modify #DoorCardsInDeck: + 1
Variable - Set DoorCardDeck[#DoorCardsInDeck] = DoorDiscardDeck[#DoorCardsInDiscard]
Variable - Set DoorDiscardDeck[#DoorCardsInDiscard] = 0
Variable - Modify #DoorCardsInDiscard: - 1
General - Repeat (Actions) 10000 times
Actions
Variable - Set TempShuffleInt[1] = (Random integer between 1 and #DoorCardsInDeck)
Variable - Set TempShuffleInt[2] = (Random integer between 1 and #DoorCardsInDeck)
Variable - Set TempShuffleInt[3] = DoorCardDeck[TempShuffleInt[1]]
Variable - Set DoorCardDeck[TempShuffleInt[1]] = DoorCardDeck[TempShuffleInt[2]]
Variable - Set DoorCardDeck[TempShuffleInt[2]] = TempShuffleInt[3]
Else
Do nothing
The trick was to always keep track of how many cards are in each deck. The # of cards in each is always equal to the highest-level variable in the arrays that hasn't been taken already (set to zero). So the # of cards will always be the next one you want to take.
When I call the cue, if the draw stack is at zero the discards will get returned one at a time and then reshuffled. I just set the randomization parameters to 1 - #of cards in the draw stack.
I hope this helps anyone else who wants to do something like this :/
seeing as you've figured out the shuffle idea, you can shuffle then the "array indices" of an card array, so the card array itself is always in the same order, but in the deck array, they aren't sorted. like your shuffle shuffles the array.
You can now just create functions to remove a number from the array and shove the rest up, or let the array remain the same and remove the highest index card remaining. Just use an additional integer to keep track of the available cards. This integer you could also use in your random shuffle bit to prevent your deck from having holes in them. so instead of random 1 to 100 you'll get, random 1 to decksize.
you add the removed number above to a players hand, and retrieve the card information out of an array you have defined at the side. this way you'll just be using an integer to pass about. the card information will stay nice together, if you use a record (or struct for those who use galaxy code). in this record you can e.g. set the following data: Value (A,2,5,K,etc.), Type (Spades, Hearts,etc.) Display Text(Ace of Spades, Two of Hearts, etc.)
----
I like the sound of the first paragraph but am a tad confused. Do you mean rather than shuffling the contents of the array around I shuffle the containers?
*edit*
The plan right now is to have the backbone of the game operate purely on integers and math. So even though card 3 is the mace of unruliness it's just the number 3 as it's being drawn, discarded, played, cursed and such is just the displacement of a number.
Hopefully the cards and actions therein can be treated on a modular basis using if/then/ors and action definitions.
So:
event:
a card is played
condition:
a player is in combat
that card is the number 3
action:
the player in combat gets maced by the player who had that card
Next up, learning dialogues and the math behind combat.
The plan right now is to have the backbone of the game operate purely on integers and math.So even though card 3 is the mace of unruliness it's just the number 3 as it's being drawn, discarded, played, cursed and such is just the displacement of a number.
That's basicly what I said in the first alinea XD.
You can create a seperate array of strings or records which contain the name/info of each card. So for example the string array position 3 would read: "mace of unruliness".
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
Hey guys.
I'm trying to create a game that shuffles and deals cards to each player, stores a deck to draw new cards from and stores a discard pile.
Think of it like a game of poker. Fifty two cards are randomly arranged in a draw pile, then the cards are distributed to the players.
My lack of coding knowledge leads me to ask the following:
- How do I create a system that knows each card (ace of spades, seven of diamonds, etc) and randomizes them into some variable or array in a way that does not duplicate or leave out cards? organized deck > shuffled deck
- How do I manipulate this variable/array/record/datatable to order the cards from top to bottom as they are drawn. So the game isn't just randomly drawing out of the (already randomized) stack but rather in a set order. top card = jack of hearts & second card = two of clubs > draw > top card = two of clubs.
- After these cards are used and all cards are either in the players hands or in the discard pile (which also must be organized) how do I then shuffle the cards from the discard pile (which will be less than 52) into a new draw pile. #cards in deck = 0, #cards in players hands = 15, #cards in discard = 37. > shuffle > #cards in deck = 37, #cards in players hands = 15, #cards in discard = 0.
I'd like to keep the data tidy. So a system containing a variable for your draw pile, one for your discards and one for each players hand is ideal. The system must also be flexible since more cards will be added to the game as I update it. The number of cards each player can carry will vary based on events within the game and all sorts of crap occurs as the cards are played. Sometimes the players will need to take stuff out of the discards, sometimes the game needs to search through the draw stack for a specific card.
Thanks to whoever can figure this out.
something basic I just threw together, it has a sort of draw function and a shuffle function.
map is directly runnable, it has a complete set of cards. (2 through 9, jack, queen, king, ace of each spades, clubs, hearts, diamonds)
-draw draws a card and displays it. it also says when the deck is empty.
-reset deck: restores the deck to the starting data.
-shuffle deck: shuffles the deck.
the deck isn't standardly shuffled. it is just a list of cards from 2 through 9 then Ace, Jack, Queen, King. all suits together.
Thanks Helral. I'm having a bit of trouble reading your map file but I can see some of the triggers and will try to understand it.
I've just figured out how to shuffle an array of intergers within itself. Which could theoretically be used with other triggers to resemble various cards (i.e. 1 = ace of clubs, 2 = two of clubs, 3 = three of clubs, 14 = ace of diamonds etc.)
What I did was fill an array of 100 with numbers ranging from 1 - 100 so it is like such: CardDeck(1) = 1, CardDeck(2) = 2, CardDeck(41) = 41 etc.
-Then create a Array of 3 to fill temporary numbers.
-Then take two of random numbers from the array of 100 and swap them.
Since there is no real 'swap' integer action I used the first two variables in the secondary array to generate two random numbers between 1 and the number of cards in the deck.
Those two numbers are then picked out of the CardDeck(1-100) array and swapped with each other using the third extra variable to temporarily store the value of the first CardDeck variable before it is destroyed.
So it looks like so:
Shuffle
Events
UI - Player Any Player presses Up key Down with shift Allow, control Allow, alt Allow
Local Variables
Conditions
Actions
General - Repeat (Actions) 10000 times
Actions
Variable - Set TempShuffleInt[1] = (Random integer between 1 and 100)
Variable - Set TempShuffleInt[2] = (Random integer between 1 and 100)
Variable - Set TempShuffleInt[3] = DoorCardDeck[TempShuffleInt[1]]
Variable - Set DoorCardDeck[TempShuffleInt[1]] = DoorCardDeck[TempShuffleInt[2]]
Variable - Set DoorCardDeck[TempShuffleInt[2]] = TempShuffleInt[3]
My machine is pretty good but doing this 10000 times doesn't generate a pip of lag and yields indistinguishably random results.
lots of programming classes have you deal with decks of cards. Lots of options for shuffling and managing them. It really depends on how you are using them and how you prefer to work with them... easiest way to randomize the cards is to make a second array of cards, loop through the first array and insert the card randomly into the second one inserting at a random point in the second array (aka, if you have 4 cards in the second array, you will insert the fifth element as element 0-5, when you get to the 6th element, insert it between 0-6, seventh between 0-7). This is nice if your deck is being shuffled when it is not full as you can skip empty elements. It runs in O=n time and isn't complicated. It's not a "truely random" shuffle however...
Another fun way if memory is a problem or just as an exercise, is to loop through the array of cards and swaping each card with a random card in the deck. it doesn't seem like random placement but it is (or at least close enough). this method doesn't work well if random members of the "deck" are missing when you shuffle, but is very quick and memory efficient. You can make modifications to the algorhythm to ensure the deck is "pushed' all the way to the beginning of the array very simply though.
These ways work well if you are doing something like creating a record and having it hold a suit and a rank. These "virtual decks" are fine, and intuitive, but a lot of the time it is easier to deal with a simulated card system. Use an array of 52 bools (or even better a bit array), and simply use the mod 13 of the card for the suit, and the mod 4 of the card for the rank. When you put a card in a players hand, simply turn the bool off, and insert the array element # into the player's hand as an int. A bit rougher to get your head around, but just as simple and much lighter of a system in terms of coding. This method has it's advantages and disadvantages though.
Out of these three, I'd probably suggest the middle one... it seems the closest to what you are doing and need.
@Hikury: Go
seeing as you've figured out the shuffle idea, you can shuffle then the "array indices" of an card array, so the card array itself is always in the same order, but in the deck array, they aren't sorted. like your shuffle shuffles the array.
You can now just create functions to remove a number from the array and shove the rest up, or let the array remain the same and remove the highest index card remaining. Just use an additional integer to keep track of the available cards. This integer you could also use in your random shuffle bit to prevent your deck from having holes in them. so instead of random 1 to 100 you'll get, random 1 to decksize.
you add the removed number above to a players hand, and retrieve the card information out of an array you have defined at the side. this way you'll just be using an integer to pass about. the card information will stay nice together, if you use a record (or struct for those who use galaxy code). in this record you can e.g. set the following data: Value (A,2,5,K,etc.), Type (Spades, Hearts,etc.) Display Text(Ace of Spades, Two of Hearts, etc.)
Thanks Anthius. The second seemed to be the easiest to make a trigger for so I went ahead and did that one.
*note* while I was writing this Helral posted exactly this information. But alas.
I've also figured out how to remain aware of the top card and shuffle however many cards are in the discard back into the draw stack.
Using a few tools to move cards either to my hand or to the discards (the ones in my hand will not appear again in the draw stack.) I just had to make a reshuffle trigger which looked a lot like the original one but with more crap.
ShuffleDiscards
Events
UI - Player Any Player presses Num Pad 4 key Down with shift Allow, control Allow, alt Allow
Local Variables
Conditions
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Abs(#DoorCardsInDeck)) == 0
Then
General - While (Conditions) are true, do (Actions)
Conditions
(Abs(#DoorCardsInDiscard)) > 0
Actions
Variable - Modify #DoorCardsInDeck: + 1
Variable - Set DoorCardDeck[#DoorCardsInDeck] = DoorDiscardDeck[#DoorCardsInDiscard]
Variable - Set DoorDiscardDeck[#DoorCardsInDiscard] = 0
Variable - Modify #DoorCardsInDiscard: - 1
General - Repeat (Actions) 10000 times
Actions
Variable - Set TempShuffleInt[1] = (Random integer between 1 and #DoorCardsInDeck)
Variable - Set TempShuffleInt[2] = (Random integer between 1 and #DoorCardsInDeck)
Variable - Set TempShuffleInt[3] = DoorCardDeck[TempShuffleInt[1]]
Variable - Set DoorCardDeck[TempShuffleInt[1]] = DoorCardDeck[TempShuffleInt[2]]
Variable - Set DoorCardDeck[TempShuffleInt[2]] = TempShuffleInt[3]
Else
Do nothing
The trick was to always keep track of how many cards are in each deck. The # of cards in each is always equal to the highest-level variable in the arrays that hasn't been taken already (set to zero). So the # of cards will always be the next one you want to take.
When I call the cue, if the draw stack is at zero the discards will get returned one at a time and then reshuffled. I just set the randomization parameters to 1 - #of cards in the draw stack.
I hope this helps anyone else who wants to do something like this :/
Quote from Helral:
@Hikury: Go
seeing as you've figured out the shuffle idea, you can shuffle then the "array indices" of an card array, so the card array itself is always in the same order, but in the deck array, they aren't sorted. like your shuffle shuffles the array.
You can now just create functions to remove a number from the array and shove the rest up, or let the array remain the same and remove the highest index card remaining. Just use an additional integer to keep track of the available cards. This integer you could also use in your random shuffle bit to prevent your deck from having holes in them. so instead of random 1 to 100 you'll get, random 1 to decksize.
you add the removed number above to a players hand, and retrieve the card information out of an array you have defined at the side. this way you'll just be using an integer to pass about. the card information will stay nice together, if you use a record (or struct for those who use galaxy code). in this record you can e.g. set the following data: Value (A,2,5,K,etc.), Type (Spades, Hearts,etc.) Display Text(Ace of Spades, Two of Hearts, etc.)
----
I like the sound of the first paragraph but am a tad confused. Do you mean rather than shuffling the contents of the array around I shuffle the containers?
*edit*
The plan right now is to have the backbone of the game operate purely on integers and math. So even though card 3 is the mace of unruliness it's just the number 3 as it's being drawn, discarded, played, cursed and such is just the displacement of a number.
Hopefully the cards and actions therein can be treated on a modular basis using if/then/ors and action definitions.
So:
event:
a card is played
condition:
a player is in combat
that card is the number 3
action:
the player in combat gets maced by the player who had that card
Next up, learning dialogues and the math behind combat.
That's basicly what I said in the first alinea XD.
You can create a seperate array of strings or records which contain the name/info of each card. So for example the string array position 3 would read: "mace of unruliness".