xInMourning
xInMourning

Reputation: 65

Making and using an object-style Module in Lua

I've been trying to take a module in Lua and use it to imitate an object. i.e. I made a deck of cards:

local Card = require("Card")

local function firstCard()
    Card.newDeck()
    Card.drawCard()
    return Card.getCard()
end

local function secondCard()
    Card.newDeck()
    Card.drawCard()
    return Card.getCard()
end

first = firstCard()
second = secondCard()

print(first)
print(second)

I set first = firstCard() and second = secondCard() but when I print the two variables second occasionally results as nil. I'm honestly lost. Here's the actual module itself.

local Card = {}

local deck
local value
local number, suit
local index = 0
local getCard
local getValue

function Card.newDeck()
   deck = {}
   value = {}
   for x = 1, 13 do
      if x == 1 then
         number = "Ace"
      elseif x == 11 then
         number = "Jack"
      elseif x == 12 then
         number = "Queen"
      elseif x == 13 then
         number = "King"
      else
         number = x
      end
      for x1 = 1, 4 do
         if x1 == 1 then
            suit = "Clubs"
         elseif x1 == 2 then
            suit = "Diamonds"
         elseif x1 == 3 then
            suit = "Hearts"
         else
            suit = "Spades"
         end
         index = index + 1
         deck[index] = number.." of "..suit
         value[index] = x
      end
   end
end

function Card.drawCard()
   index = math.random(52)
   getCard = deck[index]
   getValue = value[index]
end

function Card.getCard()
   return getCard
end

function Card.getValue()
   return getValue
end

function Card.getIndex()
   return index
end

return Card

I have limited knowledge of Lua when it comes to Object-Oriented programming and to be honest, I typically only use it for calculations or small games to keep me occupied I'm class- I'm only 16. I'm more used to Java, even though I started using Lua well before I picked up Java. I just want to know if and how I can make this work. For the most part it works, just those occasional nil values.

Upvotes: 3

Views: 140

Answers (2)

das
das

Reputation: 557

Try to use this instead, seems to work fine, it should print "ERROR NO VALUE" if there is some issue with the index, if that occurs (it shouldn't though), just print the index (in the generateCard() function).

This is the test

local Card = require("Card");
local function firstCard()
    Card.newDeck()
    return Card.generateCard(); -- two parameters, deck and value
end
local function secondCard()
    Card.newDeck()
    return Card.generateCard();
end
first = firstCard()
second = secondCard()
print(first)
print(second)

This is the module

local Card = {deck={};value={};};
function Card.newDeck()
    local self = Card
    local deck = self.deck;
    local value = self.value;
    local cards = {[1]="Ace",[11]="Jack",[12]="Queen",[13]="King"};
    local types = {[1]="Clubs",[2]="Diamonds",[3]="Hearts",[4]="Spades"};
    for x = 1, 13 do
        for i = 1, 4 do
            local _card,_type=(cards[x] or x),types[i];
            deck[#deck+1] = _card.." of ".._type
            value[#deck+1] = x
        end
    end
end
function Card.generateCard()
    local self = Card;
    if(not math.round) then
        math.round = function(value) local mi,ma=math.floor(value),math.ceil(value)return(mi+0.5>value and mi or ma)end;
    end
    local index = math.round(math.random(1000, 52000)/1000);
    return (self.deck[index] or "NO VALUE FOR CARD"),(self.value[index] or "NO DECK FOR CARD");
end
return Card

Upvotes: 0

catwell
catwell

Reputation: 7020

The problem is that you have declared the index variable local at the top level of your module. That means that the random value of index that you have calculated in your first drawCard() is reused in your second call to newDeck(). You can add print(index) at the start of newDeck() to see what I mean.

There are several ways to solve the problem. One would be to add index = 0 at the top of newDeck(). A better one would be to declare your variables with smaller scoping, i.e. make index local to each function that uses it.

Upvotes: 2

Related Questions