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
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!
lg.print("#") --used to be "J"
lg.print("#")
else
lg.print(self.rank .. " of " .. self.suit, cornerOffset - Card.static.width/2, cornerOffset - 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
--]]
lg.print(self.rank .. " of " .. self.suit, cornerOffset - Card.static.width/2, cornerOffset - Card.static.height/2)
if self.suit == "Clubs" then
lg.print("")
elseif self.suit == "Diamonds" then
@@ -75,6 +61,10 @@ function Card:moveTo(x, y, r)
self.r = r or self.r
end
function Card:getPosition()
return self.x, self.y, self.r
end
function Card:flip()
if self.face == "down" then
self.face = "up"

View File

@@ -45,6 +45,10 @@ function Deck:moveTo(x, y, r)
self.r = r or self.r
end
function Deck:getPosition()
return self.x, self.y, self.r
end
function Deck:flip()
if self.face == "down" then
self.face = "up"
@@ -64,28 +68,76 @@ function Deck:shuffleCards()
end
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
--TODO ? placeIn() to randomly place within without shuffling whole deck?
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 >= #self.cards then
return self
end
local new = {}
while (count > 1) and (#self.cards > 1) do
for i=1,count do
insert(new, remove(self.cards))
end
return Deck(new)
local deck = Deck(new)
deck.face = self.face
return deck
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
--[[
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
--on top of deck
function Deck:placeCardsOn(cards)
if type(cards) == "table" then
for _, card in ipairs(cards) do
insert(self.cards, card)
--if type(cards) == "table" then
-- for _, card in ipairs(cards) do
-- insert(self.cards, card)
-- end
if cards:isInstanceOf(Deck) then
for i=1,#cards.cards do
insert(self.cards, cards.cards[i])
end
else
insert(self.cards, cards)
@@ -94,13 +146,17 @@ end
--on bottom of deck
function Deck:placeCardsUnder(cards)
if type(cards) == "table" then
for _, card in ipairs(cards) do
insert(self.cards, card, 1)
if cards:isInstanceOf(Deck) then
for i=1,#cards.cards do
insert(self.cards, 1, cards.cards[i])
end
else
insert(self.cards, cards, 1)
insert(self.cards, 1, cards)
end
end
function Deck:getCards()
return self.cards
end
return Deck

View File

@@ -1,3 +1,9 @@
function love.conf(t)
t.identity = "52cards"
t.console = true
t.window.title = "52 Cards"
t.window.width = 960
t.window.height = 540
t.window.resizeable = true
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 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 cards = {}
@@ -28,12 +42,15 @@ local function makeDeck(jokers)
end
function love.load()
insert(items, makeDeck(true))
insert(items, makeDeck(false))
items[1]:shuffleCards()
items[1]:moveTo(lg.getWidth()/2, lg.getHeight()/2)
items[2] = Card("", "Joker")
items[2]:moveTo(100, 100)
items[2]:moveTo(80, 100)
items[2]:flip()
items[3] = Card("", "Joker")
items[3]:moveTo(85, 105)
items[3]:flip()
end
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.
if not holding then
--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
local hovering = false
@@ -99,7 +116,7 @@ function love.draw()
else
if hovering == "Card" then
--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
--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)
@@ -109,27 +126,105 @@ function love.draw()
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
function love.mousepressed(x, y, button)
--[[ ORIGINAL TEXT, NOT ACCURATE
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 button == LEFT_MOUSE then
if not holding then
for i=#items,1,-1 do
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
end
end
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)
insert(items, holding)
holding = false
@@ -139,6 +234,7 @@ function love.mousepressed(x, y, button)
for i=#items,1,-1 do
if isOnItem(x, y, items[i]) then
item = i
break
end
end
@@ -149,48 +245,23 @@ function love.mousepressed(x, y, button)
elseif items[item]:isInstanceOf(Card) then
local card = table.remove(items, item)
local deck = Deck({card, holding})
insert(items, deck)
holding = false
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.face = card.face
holding = deck
--deck over deck
"Scroll up to add this deck on top, scroll down to add this deck on bottom."
--deck over nothing
"Scroll to shuffle the deck."
]]
--deck:moveTo(card:getPosition())
--print(inspect(deck)) --NOTE DBEUG
--insert(items, 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
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()
break
end
end
elseif holding:isInstanceOf(Card) then
--TODO easy
elseif holding:isInstanceOf(Deck) then
--TODO maybe harder
end
wheelUP(x, y)
elseif button == "wd" then
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
--TODO easy
elseif holding:isInstanceOf(Deck) then
--TODO maybe harder
end
elseif button == "r" then
wheelDOWN(x, y)
elseif button == RIGHT_MOUSE then
if holding then
holding:flip()
else
@@ -202,12 +273,29 @@ function love.mousepressed(x, y, button)
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
function love.keypressed(key)
if key == "escape" then
love.event.quit()
end
if key == "m" then
insert(items, makeDeck(false))
end
if key == "j" then
insert(items, Card("", "Joker"))
insert(items, Card("", "Joker"))
end
end
-- ♣ ♦ ♥ ♠ A 2 3 4 5 6 7 8 9 10 J Q K Joker