ID:179233
 
I'm not exactly using a deck of cards, but the idea is similar. I'm working on a game which has about 70 tiles (some unique, some occur as many as 10 times), which I want the players to be able to draw randomly from a stack.

I was wondering if anyone could give me some good sample code for handling this, or even some general suggestions if you don't have code?

Thanks!
Put all of the tiles into a list. Rather than shuffling the list, just use pick() to grab one at random each time you need one from the list, then remove that from the list.

example:
var/list/deck = list("Queen of Hearts", "King of Spades", "9 of Clubs")
mob/verb/draw_card()
var/card = pick(deck)
deck -= card
usr << "You drew a [card]."

In actual practice, you'll probably want deck to contain objects rather than text strings, and most likely more than three.... but the idea is basically the same.

-AbyssDragon
In response to AbyssDragon
Thanks for the help. I have a few more questions:

- The compiler is complaining when I try to include obj's within the list() command. What is the proper way to do this?

- do i need to create an instance of each "tile" obj (ie. using new() ) when it is entered into the list, or only when a player draws it?

- I have a var called "freq" associated with each tile which indicates how many of that particular tile should exist in the game. How can I use this var to efficiently load the list?

Thanks!


AbyssDragon wrote:
Put all of the tiles into a list. Rather than shuffling the list, just use pick() to grab one at random each time you need one from the list, then remove that from the list.

example:
var/list/deck = list("Queen of Hearts", "King of Spades", "9 of Clubs")
mob/verb/draw_card()
var/card = pick(deck)
deck -= card
usr << "You drew a [card]."

In actual practice, you'll probably want deck to contain objects rather than text strings, and most likely more than three.... but the idea is basically the same.

-AbyssDragon
In response to Dramstud
- do i need to create an instance of each "tile" obj (ie. using new() ) when it is entered into the list, or only when a player draws it?

You should populate it with individual objects. There is a shortcut in DM for this purpose:

var/list/list = newlist(/obj/tile1, /obj/tile2)

Or, if you make it a list of obj types (not vars)/:

var/list/list = list(/obj/tile1, /obj/tile2)

...you can create the object when it is drawn from the stack.


- I have a var called "freq" associated with each tile which indicates how many of that particular tile should exist in the game. How can I use this var to efficiently load the list?

Oof, that's a tough one... my recommendation would be to try:

var/list/cards = list()

world/New()
..()
var/list/cards_to_make = newlist(/obj/type1, /obj/type2) //etc.
for(var/obj/card in cards_to_make) //loop through all of the cards to make
while(card.freq--) //and create 'freq' cards in the global deck
cards += new card.type
In response to Dramstud
To put objects into the list you'll have the generate the list at run time rather than compile time; you can do this in any proc. If the list is global and needs to be used right away, world/New() is one place to put it.

There's no simple, direct way to use a variable in each object type to determine how many to create. One way would be to create a new one of each type you want, then loop from 1 to its freq variable, each time creating one of that type in the list.

An example:

var/obj/type1/a = new()
var/obj/type2/b = new()
var/list/mylist = list()
for(var/x in 1 to a.freq)
mylist += new/obj/type1
for(var/x in 1 to b.freq)
mylist += new/obj/type2

-AbyssDragon
I can show you what I did in Una this Sunday, contact Bootyboy for time and location.
In response to Air Mapster
These lucky people!
In response to Spuzzum
Thanks for the advice.

While it wouldn't be too painful to create the additional list of tile types, I'm wondering if there might be a shortcut. I defined all the tiles as children of /obj/tiles. Could I loop on all obj within /obj/tiles instead of creating another list?

ie. for(/obj/tiles/T in /obj/tiles)
while (T.freq > 0)
tile_stack += new T
T.freq -= 1



Spuzzum wrote:
- do i need to create an instance of each "tile" obj (ie. using new() ) when it is entered into the list, or only when a player draws it?

You should populate it with individual objects. There is a shortcut in DM for this purpose:

var/list/list = newlist(/obj/tile1, /obj/tile2)

Or, if you make it a list of obj types (not vars)/:

var/list/list = list(/obj/tile1, /obj/tile2)

...you can create the object when it is drawn from the stack.


- I have a var called "freq" associated with each tile which indicates how many of that particular tile should exist in the game. How can I use this var to efficiently load the list?

Oof, that's a tough one... my recommendation would be to try:

var/list/cards = list()

world/New()
..()
var/list/cards_to_make = newlist(/obj/type1, /obj/type2) //etc.
for(var/obj/card in cards_to_make) //loop through all of the cards to make
while(card.freq--) //and create 'freq' cards in the global deck
cards += new card.type
In response to Nadrew
A valuable lesson in life: it's not always what you know, but who you know.
In response to Air Mapster
One of these days I'm moving over there...
In response to Air Mapster
Thanks, Mike. I was hoping to get a peek at your code ;)

Perhaps I can even show you the incredibly addictive board game that my first byond creation is based on.