From 4961a6b4532147d9ae5eed6e796ec26b0014ec5b Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Tue, 17 Jan 2023 09:51:18 -0500 Subject: [PATCH] initial commit --- README.md | 48 +++++++++++++++++++++ init.lua | 114 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/test.lua | 43 +++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 README.md create mode 100644 init.lua create mode 100644 tests/test.lua diff --git a/README.md b/README.md new file mode 100644 index 0000000..65fe5fe --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Readme + +Simple library for managing a deck of cards + +Example: +```lua +math.randomseed(os.time()) +local deck, card = require("deck"):init() + +local play = deck:new("Playing cards") +local discard = deck:new("Discard") + +local suits = {"hearts", "diamonds", "clubs", "spades"} +local values = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"} + +local id = 0 +for i, suit in ipairs(suits) do + for j, value in ipairs(values) do + play:add(card:new(value .. " of " .. suit, {ID = id})) + id = id + 1 + end +end + +play:setDiscard(discard) -- Set discard pile, automatically puts "dealt" cards into the discard pile. Alternatively, you could just put the players hands ("decks") back into deck using shuffle(playerDeck) +print(play) +play:shuffle() + +print(play) +print("----") +print(play:draw(5)) +print("----") +print(play) + +while #play ~= 0 do + print(play:draw()) +end + +print("Play:", #play) +print("Discard:", #discard) + +play:shuffle(discard) + +print("Play:", #play) +print("Discard:", #discard) + +local c = play:peek() +print("Peeking:", c, "ID:", c.ID) +``` \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..cf5a674 --- /dev/null +++ b/init.lua @@ -0,0 +1,114 @@ +local deck = {} +deck.__index = deck +deck.__tostring = function(d) + local c = {} + for i = 1, #d do + c[#c + 1] = d[i].name + end + return "Cards in " .. d.name .. "(" .. #d .. "): " .. table.concat(c, ", ") +end +deck.Type = "deck" + +local card = {} +card.__index = card +card.__tostring = function(c) return c.name end +card.Type = "card" + +function card:new(name, data) + local c = {} + c.name = tostring(name) or error("You must supply a name for a card!") + -- copy data, don't reference it directly + if type(data) == "table" then + for i, v in pairs(data) do + c[i] = v + end + end + setmetatable(c, card) + return c +end + +local d_counter = 0 +function deck:new(name) + local d = {} + d.name = tostring(name) or "Unnamed deck " .. d_counter + d.discard = {} + setmetatable(d, deck) + d_counter = d_counter + 1 + return d +end + +function deck:setDiscard(deck) + self.discard = deck or deck:new("Discard pile") + return self.discard +end + +function deck:getDiscard() + return self.discard +end + +function deck:reset() + self:shuffle(self.discard) +end + +function deck:add(c) + if type(c) == "string" then c = card:new(c) end + table.insert(self, c) + return self +end + +function deck:shuffle(deck) + if type(deck) == "table" and deck.Type == "deck" then + while #deck ~= 0 do + self:add(deck:draw()) + end + end + local n = #self + while n > 2 do + local k = math.random(n) + self[n], self[k] = self[k], self[n] + n = n - 1 + end + return self +end + +function deck:draw(n) + if n then + local cards = deck:new("Draw") + for i = 1, n do + cards:add(self:draw()) + end + return cards + else + local card = table.remove(self, 1) + if card then + table.insert(self.discard, card) + end + return card + end +end + +local function findHelper(card1, card2) + return card1.name == card2.name +end + +function deck:find(card, func) + local func = func or findHelper + for i, v in ipairs(deck) do + if findHelper(v, card) then + return i + end + end + return nil +end + +function deck:peek(n) + if not n or n == 1 then return self[1] end + local cards = deck:new("Peek") + for i = 1, n do + cards:add(self[i]) + end + return cards +end + +-- init function +return {init = function() return deck, card end} \ No newline at end of file diff --git a/tests/test.lua b/tests/test.lua new file mode 100644 index 0000000..ee66504 --- /dev/null +++ b/tests/test.lua @@ -0,0 +1,43 @@ +package.path = "../?/init.lua;" .. package.path +math.randomseed(os.time()) +local deck, card = require("deck"):init() + +local play = deck:new("Playing cards") +local discard = deck:new("Discard") + +local suits = {"hearts", "diamonds", "clubs", "spades"} +local values = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"} + +local id = 0 +for i, suit in ipairs(suits) do + for j, value in ipairs(values) do + play:add(card:new(value .. " of " .. suit, {ID = id})) + id = id + 1 + end +end + +play:setDiscard(discard) + +print(play) +play:shuffle() + +print(play) +print("----") +print(play:draw(5)) +print("----") +print(play) + +while #play ~= 0 do + print(play:draw()) +end + +print("Play:", #play) +print("Discard:", #discard) + +play:shuffle(discard) + +print("Play:", #play) +print("Discard:", #discard) + +local c = play:peek() +print("Peeking:", c, "ID:", c.ID) \ No newline at end of file