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.
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