Page 2 of 3

Re: Card Game

Posted: Wed Feb 08, 2012 11:53 pm
by Mud
Robin wrote:Yes. It's called modules, not classes. Technically, you don't have any classes in your code.
Well, you don't instantiate multiple instances of a module, like he does with Card and Player. His classes don't support inheritance, but inheritance is orthogonal to the concept of a class. So while they are limited and not idiomatic Lua, but I'd still say they're classes:
Wikipedia wrote:A class is a construct that is used as a blueprint to create instances of itself. A class defines constituent members which enable these class instances to have state and behavior. Data field members (member variables or instance variables) enable a class object to maintain state. Other kinds of members, especially methods, enable a class object's behavior.
Side note: I saw some Lua code in a Corona app that did classes entire via closures. Very wasteful of memory, and not supporting inheritance, but allowing for truly private state. Something like:

Code: Select all

function Point_new(_x,_y)
    return { 
        getPosition = function() return _x, _y end,
        setPosition = function(x,y) _x, _y = x, y end,
    }
end

Re: Card Game

Posted: Thu Feb 09, 2012 10:07 am
by ston
Rather than having to search through a possible set of attributes for each card, from what I remember of shithead a card either has a specifc attribute, or not.

So, you could have a single attribute field for each card, one of; "none", "burn", "ace", "reverse", "perm_reverse", etc...

Could be strings, an enumeration, bit-wise values, whatever suits best. Alternatively, you could use an attibute lookup table keyed by the card's value:

attribute = attribute_loookup_table[<card_value>]

Then just switch on the attribute for the card:

if (attribute == "none")
do_nothing()
elseif (attribute == "burn")
do_burn()
elseif...

HTH :)

Re: Card Game

Posted: Thu Feb 09, 2012 10:17 am
by Robin
Ah, OK. Then I would just use:

Code: Select all

function Card.Create(Suit, Number, Colour)
	local card_obj = {};
	--assign any default vars
	card_obj.suit 		= Suit;
	card_obj.number		= Number;
	card_obj.colour 	= Colour;
	-- what follows is the same

Code: Select all

function Deck.Init()
	--Initialise, and pass through arguments.
	
	--SUIT and NUMBER are tables in Constants
	for i = 1, #SUIT do
		for j = 1, #NUMBER do
			table.insert(Deck.cards, Card.Create(SUIT[i], NUMBER[j] ));
			--Card.Print(Deck.cards[((i-1)*13)+j]);
		end
	end

	Deck.cards[23].attribute = "burn"
	Deck.cards[14].attribute = "reverse"
	--etc.

	--once inited completed, set to true
	Deck.inited = true;
end
For cards that don't have a magic attribute, the attribute property is nil, and you can just ignore it:

Code: Select all

if card.attribute == "burn" then
	do_burn()
elseif card.attribute == "ace" then
	do_ace()
elseif ...
OR, more elegantly, have an attributes table, in Constants.lua or something:

Code: Select all

ATTR = {
	burn = do_burn,
	ace = do_ace,
}

Code: Select all

if card.attribute then
	ATTR[card.attribute]
end

Re: Card Game

Posted: Thu Feb 09, 2012 12:14 pm
by ston
Looks fine to me.

I like that last bit, would that actually invoke the do_ace, do_burn etc. function(s)? (I'm still q. new to Lua in general).

I was wondering what would be a good (efficient) way of shuffling a deck of cards?

One idea:

Code: Select all

shuffled_deck = {}
for i = 1, 52, 1 do	
	table.insert(shuffled_deck, math.random(1, i), i)	
end
Instead of just inserting 'i', a number, you could use a modulo 13 operation to pick suit and card number etc.

Re: Card Game

Posted: Thu Feb 09, 2012 1:46 pm
by Robin
ston wrote:I like that last bit, would that actually invoke the do_ace, do_burn etc. function(s)? (I'm still q. new to Lua in general).
D'oh! I typo'd. It should have been:

Code: Select all

if card.attribute then
	ATTR[card.attribute]() -- parentheses for function call
end
ston wrote:I was wondering what would be a good (efficient) way of shuffling a deck of cards?

One idea:
Yeah, that should work fine.

Re: Card Game

Posted: Thu Feb 09, 2012 3:24 pm
by ston
Robin wrote: D'oh! I typo'd. It should have been:

Code: Select all

if card.attribute then
	ATTR[card.attribute]() -- parentheses for function call
end
Now that is pretty neat. Good to know - thx!

Re: Card Game

Posted: Thu Feb 09, 2012 10:57 pm
by tdc5013
Hey thanks, I hadn't considered a function call from Constants, totally forgot you could do that in Lua. :P

EDIT:

Just so I know I'm understanding all this properly... That If() statement I could drop that in the main loop and replace card.attributes with: cardpile.cards.attributes (as the in-play cards are inserted into the cardpile table, which is declared in the main.lua file) and drop that if statement in main.lua, or (probably more elegant) Rulebook.lua which would basically be the game engine?

Re: Card Game

Posted: Fri Feb 10, 2012 11:09 am
by Robin
tdc5013 wrote:Just so I know I'm understanding all this properly... That If() statement I could drop that in the main loop and replace card.attributes with: cardpile.cards.attributes (as the in-play cards are inserted into the cardpile table, which is declared in the main.lua file) and drop that if statement in main.lua, or (probably more elegant) Rulebook.lua which would basically be the game engine?
Not sure what you mean. You can use it whenever you need the attribute, which I guess would usually be when the card is played. It seems to me cardpile.cards will point to a table of cards rather than a card itself, am I right? If so, you need to take a single card who's attribute is needed at that moment. If you need to "activate" all cards in the cardpile at the same time, you'll need to put the code in a for-loop, like this:

Code: Select all

for i, card in ipairs(cardpile.cards) do
    if card.attribute then
      ATTR[card.attribute]()
   end
end

Re: Card Game

Posted: Sat Feb 11, 2012 4:33 pm
by tdc5013
Yeah you're right, meant just Cardpile. Is there a good learning resource about ipairs that I could look up? I haven't used it much, but I'm guessing I'm gonna need it a fair bit for this.

Re: Card Game

Posted: Sat Feb 11, 2012 5:16 pm
by MarekkPie
ipairs is just iterating through a table in order. It is exactly the same as a normal for-loop:

Code: Select all

table = {"a", "e", "i", "o", "u"} -- <= These are assigned numerical keys, starting from 1 and increasing by 1
for i = 1, #table do
    print(i,table[i])
end
for k,v in ipairs(table) do
    print(k,v)
end

-- Both return...
1    a
2    e
3    i
4    o
5    u
The only caveat is that, like a normal for-loop, if you have non-numerical keys, then it will skip over them, as it does not know the "order" of those.

Code: Select all

u = {"a", "e", i = "i", "o", u = "u"} -- <= The items without keys are assigned numerical keys like above
for k,v in ipairs(u) do
    print(k,v)
end

-- Returns
1    a
2    e
3    o