Compare commits

...

10 Commits

Author SHA1 Message Date
0f2c617c49 Update ReadMe.md 2024-12-02 09:16:30 +00:00
Paul Liverman III
3941a7a5b8 made compatible with 0.10.x 2017-03-24 23:53:13 -07:00
Paul Liverman
67f8192d3a added inifile and a note on usage for later use 2015-12-07 09:20:57 -08:00
Paul Liverman
169cd5651e simple changes 2015-12-06 11:25:22 -08:00
Paul Liverman
32d9d1d753 has a ReadMe, must be good enough to publish, right? 2015-12-06 00:26:33 -08:00
Paul Liverman
a0ac914028 IT WORKS 2015-12-06 00:22:58 -08:00
Paul Liverman
072322f1d7 I DON'T KNOW HOW THIS IS BROKEN BUT IT IS 2015-12-05 23:53:38 -08:00
Paul Liverman
345bd58b3b fixed lack of ability to draw a card, added Decks collapsing into cards 2015-12-05 23:31:02 -08:00
Paul Liverman
ca487ecba1 fixed small bug, decided not to do alternate control thingy for now 2015-12-05 23:24:14 -08:00
Paul Liverman
1446b2bf95 works still, bout to fuck it up 2015-12-05 23:20:29 -08:00
7 changed files with 427 additions and 82 deletions

13
ReadMe.md Normal file
View File

@@ -0,0 +1,13 @@
# 52 Cards
Does what it says on the tin (including little notes at the bottom on how to use it!).
The only thing it won't tell you how to do is press M to generate a new deck (clipped in the top left corner). This is because that's not really intended, and this is a brand new super alpha project thing. (Oh, and press J to get 2 Jokers.)
---
This repo is hosted at https://gitea.tangentfox.com/tangent/52-cards and force-pushed to GitHub when commits are made.
Feel free to submit pull requests or whatever, but know that I would have to manage them over there.
Note for self: [Read more of this](https://en.wikipedia.org/wiki/Standard_52-card_deck).

10
inifile usage.txt Normal file
View File

@@ -0,0 +1,10 @@
inifile = require "lib.inifile"
something = inifile.parse("file.ini")
inifile.save("file.ini", something)
something = {
sections = {
keys = values
}
}

View File

@@ -35,23 +35,9 @@ function Card:draw(face, x, y, r)
if self.rank == "Joker" then if self.rank == "Joker" then
lg.print("Joker", cornerOffset - Card.static.width/2, cornerOffset - Card.static.height/2) lg.print("Joker", cornerOffset - Card.static.width/2, cornerOffset - Card.static.height/2)
-- I wanted this to be a symbol for a suit, but the Joker doesn't have one! -- I wanted this to be a symbol for a suit, but the Joker doesn't have one!
lg.print("#") --used to be "J" lg.print("#")
else else
lg.print(self.rank .. " of " .. self.suit, cornerOffset - Card.static.width/2, cornerOffset - height/2) lg.print(self.rank .. " of " .. self.suit, cornerOffset - Card.static.width/2, cornerOffset - Card.static.height/2)
-- I wanted these to be symbols for suits, but for some reason I made them ranks
--[[
if self.rank == "Ace" then
lg.print("A")
elseif self.rank == "Jack" then
lg.print("J")
elseif self.rank == "Queen" then
lg.print("Q")
elseif self.rank == "King" then
lg.print("K")
else
lg.print(self.rank)
end
--]]
if self.suit == "Clubs" then if self.suit == "Clubs" then
lg.print("") lg.print("")
elseif self.suit == "Diamonds" then elseif self.suit == "Diamonds" then
@@ -75,6 +61,10 @@ function Card:moveTo(x, y, r)
self.r = r or self.r self.r = r or self.r
end end
function Card:getPosition()
return self.x, self.y, self.r
end
function Card:flip() function Card:flip()
if self.face == "down" then if self.face == "down" then
self.face = "up" self.face = "up"

View File

@@ -45,6 +45,10 @@ function Deck:moveTo(x, y, r)
self.r = r or self.r self.r = r or self.r
end end
function Deck:getPosition()
return self.x, self.y, self.r
end
function Deck:flip() function Deck:flip()
if self.face == "down" then if self.face == "down" then
self.face = "up" self.face = "up"
@@ -64,28 +68,76 @@ function Deck:shuffleCards()
end end
function Deck:shuffleIn(card) --TODO make capable of handling multiple cards function Deck:shuffleIn(card) --TODO make capable of handling multiple cards
-- --insert(self.cards, random(1, #self.cards)) --no, we shuffle everything!
insert(self.cards, card)
self:shuffleCards()
end end
--TODO ? placeIn() to randomly place within without shuffling whole deck?
function Deck:drawCards(count) function Deck:drawCards(count)
if #self.cards < 2 then
--return self as card (may break!?)
--self = self.cards[1]
return self
end
if count and (count > 1) then if count and (count > 1) then
if count >= #self.cards then
return self
end
local new = {} local new = {}
while (count > 1) and (#self.cards > 1) do for i=1,count do
insert(new, remove(self.cards)) insert(new, remove(self.cards))
end end
return Deck(new) local deck = Deck(new)
deck.face = self.face
return deck
else else
return remove(self.cards) --[[
if #self.cards == 1 then
return self
end
--]]
local card = remove(self.cards)
card.face = self.face
return card
end end
--[[
if count and (count > 1) then
local new = {}
while (count > 1) and (#self.cards > 0) do
insert(new, remove(self.cards))
count = count - 1
end
local deck = Deck(new)
deck.face = self.face
return deck
else
local card = remove(self.cards)
card.face = self.face
self:update()
return card
end
--]]
end end
--on top of deck --on top of deck
function Deck:placeCardsOn(cards) function Deck:placeCardsOn(cards)
if type(cards) == "table" then --if type(cards) == "table" then
for _, card in ipairs(cards) do -- for _, card in ipairs(cards) do
insert(self.cards, card) -- insert(self.cards, card)
-- end
if cards:isInstanceOf(Deck) then
for i=1,#cards.cards do
insert(self.cards, cards.cards[i])
end end
else else
insert(self.cards, cards) insert(self.cards, cards)
@@ -94,13 +146,17 @@ end
--on bottom of deck --on bottom of deck
function Deck:placeCardsUnder(cards) function Deck:placeCardsUnder(cards)
if type(cards) == "table" then if cards:isInstanceOf(Deck) then
for _, card in ipairs(cards) do for i=1,#cards.cards do
insert(self.cards, card, 1) insert(self.cards, 1, cards.cards[i])
end end
else else
insert(self.cards, cards, 1) insert(self.cards, 1, cards)
end end
end end
function Deck:getCards()
return self.cards
end
return Deck return Deck

View File

@@ -1,3 +1,9 @@
function love.conf(t) function love.conf(t)
t.identity = "52cards"
t.console = true t.console = true
t.window.title = "52 Cards"
t.window.width = 960
t.window.height = 540
t.window.resizeable = true
end end

182
src/lib/inifile.lua Normal file
View File

@@ -0,0 +1,182 @@
local inifile = {
_VERSION = "inifile 1.0",
_DESCRIPTION = "Inifile is a simple, complete ini parser for lua",
_URL = "http://docs.bartbes.com/inifile",
_LICENSE = [[
Copyright 2011-2015 Bart van Strien. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY BART VAN STRIEN ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BART VAN STRIEN OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Bart van Strien.
]] -- The above license is known as the Simplified BSD license.
}
local defaultBackend = "io"
local backends = {
io = {
lines = function(name) return assert(io.open(name)):lines() end,
write = function(name, contents) assert(io.open(name, "w")):write(contents) end,
},
memory = {
lines = function(text) return text:gmatch("([^\r\n]+)\r?\n") end,
write = function(name, contents) return contents end,
},
}
if love then
backends.love = {
lines = love.filesystem.lines,
write = function(name, contents) love.filesystem.write(name, contents) end,
}
defaultBackend = "love"
end
function inifile.parse(name, backend)
backend = backend or defaultBackend
local t = {}
local section
local comments = {}
local sectionorder = {}
local cursectionorder
for line in backends[backend].lines(name) do
-- Section headers
local s = line:match("^%[([^%]]+)%]$")
if s then
section = s
t[section] = t[section] or {}
cursectionorder = {name = section}
table.insert(sectionorder, cursectionorder)
end
-- Comments
s = line:match("^;(.+)$")
if s then
local commentsection = section or comments
comments[commentsection] = comments[commentsection] or {}
table.insert(comments[commentsection], s)
end
-- Key-value pairs
local key, value = line:match("^([%w_]+)%s-=%s-(.+)$")
if tonumber(value) then value = tonumber(value) end
if value == "true" then value = true end
if value == "false" then value = false end
if key and value ~= nil then
t[section][key] = value
table.insert(cursectionorder, key)
end
end
-- Store our metadata in the __inifile field in the metatable
return setmetatable(t, {
__inifile = {
comments = comments,
sectionorder = sectionorder,
}
})
end
function inifile.save(name, t, backend)
backend = backend or defaultBackend
local contents = {}
-- Get our metadata if it exists
local metadata = getmetatable(t)
local comments, sectionorder
if metadata then metadata = metadata.__inifile end
if metadata then
comments = metadata.comments
sectionorder = metadata.sectionorder
end
-- If there are comments before sections,
-- write them out now
if comments and comments[comments] then
for i, v in ipairs(comments[comments]) do
table.insert(contents, (";%s"):format(v))
end
table.insert(contents, "")
end
local function writevalue(section, key)
local value = section[key]
-- Discard if it doesn't exist (anymore)
if value == nil then return end
table.insert(contents, ("%s=%s"):format(key, tostring(value)))
end
local function writesection(section, order)
local s = t[section]
-- Discard if it doesn't exist (anymore)
if not s then return end
table.insert(contents, ("[%s]"):format(section))
-- Write our comments out again, sadly we have only achieved
-- section-accuracy so far
if comments and comments[section] then
for i, v in ipairs(comments[section]) do
table.insert(contents, (";%s"):format(v))
end
end
-- Write the key-value pairs with optional order
local done = {}
if order then
for _, v in ipairs(order) do
done[v] = true
writevalue(s, v)
end
end
for i, _ in pairs(s) do
if not done[i] then
writevalue(s, i)
end
end
-- Newline after the section
table.insert(contents, "")
end
-- Write the sections, with optional order
local done = {}
if sectionorder then
for _, v in ipairs(sectionorder) do
done[v.name] = true
writesection(v.name, v)
end
end
-- Write anything that wasn't ordered
for i, _ in pairs(t) do
if not done[i] then
writesection(i)
end
end
return backends[backend].write(name, table.concat(contents, "\n"))
end
return inifile

View File

@@ -5,8 +5,22 @@ local insert = table.insert
local lg = love.graphics local lg = love.graphics
local lm = love.mouse local lm = love.mouse
local items = {} local LEFT_MOUSE, RIGHT_MOUSE
if love.getVersion then
local _, minor = love.getVersion()
if minor == 10 then
LEFT_MOUSE = 1
RIGHT_MOUSE = 2
else
LEFT_MOUSE = "l"
RIGHT_MOUSE = "r"
end
end
local inspect = require "lib.inspect" --NOTE DEBUG
local items = {}
local function makeDeck(jokers) local function makeDeck(jokers)
local cards = {} local cards = {}
@@ -28,12 +42,15 @@ local function makeDeck(jokers)
end end
function love.load() function love.load()
insert(items, makeDeck(true)) insert(items, makeDeck(false))
items[1]:shuffleCards() items[1]:shuffleCards()
items[1]:moveTo(lg.getWidth()/2, lg.getHeight()/2) items[1]:moveTo(lg.getWidth()/2, lg.getHeight()/2)
items[2] = Card("", "Joker") items[2] = Card("", "Joker")
items[2]:moveTo(100, 100) items[2]:moveTo(80, 100)
items[2]:flip() items[2]:flip()
items[3] = Card("", "Joker")
items[3]:moveTo(85, 105)
items[3]:flip()
end end
local holding = false -- we might be holding something! local holding = false -- we might be holding something!
@@ -69,7 +86,7 @@ function love.draw()
--All cards in a deck are facing the same way automatically. --All cards in a deck are facing the same way automatically.
if not holding then if not holding then
--not holading anything --not holading anything
lg.print("Left click to grab a card or deck. Scroll over a deck to shuffle it. Right click to flip a card or the cards in a deck.", 2, lg.getHeight() - 14) lg.print("Left click to grab a card or draw a card. Scroll down over a deck to shuffle it, scroll up to pick up a deck. Right click to flip a card or the cards in a deck.", 2, lg.getHeight() - 14)
else else
local hovering = false local hovering = false
@@ -99,7 +116,7 @@ function love.draw()
else else
if hovering == "Card" then if hovering == "Card" then
--deck over card --deck over card
lg.print("Left click to place deck (will not shuffle card underneath into the deck). Right click to flip cards in the deck.", 2, lg.getHeight() - 14) lg.print("Left click to place deck (will not interact with card underneath). Right click to flip cards in the deck.", 2, lg.getHeight() - 14)
elseif hovering == "Deck" then elseif hovering == "Deck" then
--deck over deck --deck over deck
lg.print("Left click to place deck (will not interact with deck underneath). Scroll up to add this deck on top, scroll down to add this deck on bottom. Right click to flip cards in this deck.", 2, lg.getHeight() - 14) lg.print("Left click to place deck (will not interact with deck underneath). Scroll up to add this deck on top, scroll down to add this deck on bottom. Right click to flip cards in this deck.", 2, lg.getHeight() - 14)
@@ -109,27 +126,105 @@ function love.draw()
end end
end end
end end
if not love.getVersion then
lg.print("This toy is probably not compatible with the version of LOVE you are using!!", 2, 2)
end
end
local function wheelUP(x, y)
if not holding then
for i=#items,1,-1 do --ABSTRACT THIS FOR, I DO IT TOO MUCH ?
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
--items[i]:shuffleCards() -- now we pick it up instead!
holding = table.remove(items, i)
break
end
end
elseif holding:isInstanceOf(Card) then
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:placeCardsOn(holding)
holding = false
break
end
end
elseif holding:isInstanceOf(Deck) then
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:placeCardsOn(holding:getCards())
holding = false
break
end
end
if holding then --if we didn't just get rid of it...
holding:shuffleCards()
end
end
end
local function wheelDOWN(x, y)
if not holding then
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:shuffleCards()
break
end
end
elseif holding:isInstanceOf(Card) then
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:placeCardsUnder(holding)
holding = false
break
end
end
elseif holding:isInstanceOf(Deck) then
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:placeCardsUnder(holding:getCards())
holding = false
break
end
end
if holding then --if we didn't just get rid of it...
holding:shuffleCards()
end
end
end
function love.wheelmoved(x, y)
if y > 0 then
wheelUP(love.mouse.getX(), love.mouse.getY())
elseif y < 0 then
wheelDOWN(love.mouse.getX(), love.mouse.getY())
end
end end
function love.mousepressed(x, y, button) function love.mousepressed(x, y, button)
--[[ ORIGINAL TEXT, NOT ACCURATE if button == LEFT_MOUSE then
Left click will grab a card or deck.
While holding a card: Left click will place it (as long as the mouse is not over a deck).
While holding a card over a deck: Scroll up to place it on top of the deck, scroll down to place it on the bottom of the deck. Right click to shuffle it into the deck.
While holding a deck: Left click will place it (as long as the mouse is not over a deck).
While holding a deck over a deck: Scroll up to place it on top of the deck, scroll down to place it on the bottom of the deck. Right click to shuffle the decks together.
While NOT holding anything: Right click a card to flip it, or right click a deck to flip the cards in it (does not flip order of cards). Scroll over a deck to shuffle it.
All cards in a deck are facing the same way automatically.
--]]
if button == "l" then
if not holding then if not holding then
for i=#items,1,-1 do for i=#items,1,-1 do
if isOnItem(x, y, items[i]) then if isOnItem(x, y, items[i]) then
holding = table.remove(items, i) if items[i]:isInstanceOf(Card) then
holding = table.remove(items, i)
else
holding = items[i]:drawCards(1)
end
break break
end end
end end
elseif holding:isInstanceOf(Deck) then elseif holding:isInstanceOf(Deck) then
--[[
local item = false
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) then
item = i
end
end
--]]
holding:moveTo(x, y) holding:moveTo(x, y)
insert(items, holding) insert(items, holding)
holding = false holding = false
@@ -139,6 +234,7 @@ function love.mousepressed(x, y, button)
for i=#items,1,-1 do for i=#items,1,-1 do
if isOnItem(x, y, items[i]) then if isOnItem(x, y, items[i]) then
item = i item = i
break
end end
end end
@@ -149,48 +245,23 @@ function love.mousepressed(x, y, button)
elseif items[item]:isInstanceOf(Card) then elseif items[item]:isInstanceOf(Card) then
local card = table.remove(items, item) local card = table.remove(items, item)
local deck = Deck({card, holding}) local deck = Deck({card, holding})
insert(items, deck) deck.face = card.face
holding = false holding = deck
elseif items[item]:isInstanceOf(Deck) then
--TODO shuffle it into the deck
end
end
--[[
--card on deck
"Scroll up to place card on top of deck, scroll down to place card on bottom of deck."
--deck over deck --deck:moveTo(card:getPosition())
"Scroll up to add this deck on top, scroll down to add this deck on bottom." --print(inspect(deck)) --NOTE DBEUG
--deck over nothing --insert(items, deck)
"Scroll to shuffle the deck." --holding = false
]] elseif items[item]:isInstanceOf(Deck) then
items[item]:shuffleIn(holding)
holding = false
end
end
elseif button == "wu" then --WU AND WD ARE ALMOST IDENTICAL, COLLAPSE THEM INTO ONE WHERE POSSIBLE elseif button == "wu" then --WU AND WD ARE ALMOST IDENTICAL, COLLAPSE THEM INTO ONE WHERE POSSIBLE
if not holding then wheelUP(x, y)
for i=#items,1,-1 do --ABSTRACT THIS FOR, I DO IT TOO MUCH ?
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:shuffleCards()
break
end
end
elseif holding:isInstanceOf(Card) then
--TODO easy
elseif holding:isInstanceOf(Deck) then
--TODO maybe harder
end
elseif button == "wd" then elseif button == "wd" then
if not holding then wheelDOWN(x, y)
for i=#items,1,-1 do elseif button == RIGHT_MOUSE then
if isOnItem(x, y, items[i]) and items[i]:isInstanceOf(Deck) then
items[i]:shuffleCards()
break
end
end
elseif holding:isInstanceOf(Card) then
--TODO easy
elseif holding:isInstanceOf(Deck) then
--TODO maybe harder
end
elseif button == "r" then
if holding then if holding then
holding:flip() holding:flip()
else else
@@ -202,12 +273,29 @@ function love.mousepressed(x, y, button)
end end
end end
end end
-- this is stupid and I shouldn't have to do it this way (I think)
for i=#items,1,-1 do
if items[i]:isInstanceOf(Deck) and (#items[i].cards < 2) then
items[i].cards[1].face = items[i].face
items[i].cards[1]:moveTo(items[i]:getPosition())
items[i] = items[i].cards[1] --should delete the Deck since no references..or at least hide it away forever..yay memory leaks?
end
end
end end
function love.keypressed(key) function love.keypressed(key)
if key == "escape" then if key == "escape" then
love.event.quit() love.event.quit()
end end
if key == "m" then
insert(items, makeDeck(false))
end
if key == "j" then
insert(items, Card("", "Joker"))
insert(items, Card("", "Joker"))
end
end end
-- ♣ ♦ ♥ ♠ A 2 3 4 5 6 7 8 9 10 J Q K Joker -- ♣ ♦ ♥ ♠ A 2 3 4 5 6 7 8 9 10 J Q K Joker