Klondike/deck52.lua
Kari Sigurjonsson 342b040ca4 Bongo
2022-01-19 13:29:02 +00:00

243 lines
4.2 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--*************************************************************************************************
CARDW = 200
CARDH = 300
Heart = 1
Spade = 2
Diamond = 3
Club = 4
FaceUp = true
FaceDown = false
backId = 54
TABLEAU_MARGIN_FACEUP = 80
TABLEAU_MARGIN_FACEDOWN = 10
--*************************************************************************************************
local lgni = love.graphics.newImage
local lgnq = love.graphics.newQuad
local lsgsc = love.graphics.setColor
local lgd = love.graphics.draw
local lgsc = love.graphics.setColor
local lgr = love.graphics.rectangle
--*************************************************************************************************
local cardAtlas = lgni("deck52english.png")
local cardAtlasW = cardAtlas:getWidth()
local cardAtlasH = cardAtlas:getHeight()
local cardQuads = {}
for i = 1, 57 do
cardQuads[i] = lgnq(((i-1) % 13) * CARDW, math.floor((i-1) / 13) * CARDH, CARDW, CARDH, cardAtlasW, cardAtlasH)
end
--*************************************************************************************************
local Card = { id = 1, x = 0, y = 0, w = CARDW, h = CARDH }
function Card:show()
self.showing = FaceUp
end
function Card:move(x, y)
self.x = x
self.y = y
end
function Card:hitTest(x, y)
return not (
(x < self.x) or (x > (self.x + self.w))
or (y < self.y) or (y > (self.y + self.h))
)
end
function Card:draw()
lgsc(1, 1, 1, 1)
if (self.showing == FaceUp) then
lgd(cardAtlas, cardQuads[self.id], self.x, self.y)
else
lgd(cardAtlas, cardQuads[backId], self.x, self.y)
end
lgsc(0.25, 0.25, 0.25, 1)
lgr("line", self.x, self.y, CARDW, CARDH, 4)
end
function Card:new(id, x, y, showing)
local o = {}
for k, v in pairs(self) do
o[k] = v
end
o.id = id
o.rank = math.floor(((id - 1) % 13) + 1);
o.suit = math.floor(((id - 1) / 13) + 1);
o.showing = showing
return o
end
--*************************************************************************************************
local Deck = { x = 0, y = 0 }
function Deck:empty()
local j = #self
for i = 1, j do
self[i] = nil
end
end
function Deck:push(card)
card.owner = self
card.x = self.x
card.y = self.y
self[#self + 1] = card
end
function Deck:layout()
if (self.tableau) then
local yoff = self.y
for _, card in ipairs(self) do
card.x = self.x
card.y = yoff
yoff = yoff + ((card.showing == FaceUp) and TABLEAU_MARGIN_FACEUP or TABLEAU_MARGIN_FACEDOWN)
end
else
for _, card in ipairs(self) do
card.x = self.x
card.y = self.y
end
end
end
--FisherYates shuffle.
function Deck:shuffle()
for i = #self-1, 1, -1 do
j = math.random(0, i)
local tc = self[i+1]
self[i+1] = self[j+1]
self[j+1] = tc
end
end
function Deck:move(x, y)
self.x = x
self.y = y
for _, card in ipairs(self) do
card.x = x
card.y = y
end
self:layout()
end
function Deck:findCardUnderMouse(x, y)
if (#self == 0) then
return
end
for i = #self, 1, -1 do
local card = self[i]
if (card:hitTest(x, y)) then
return card
end
end
end
function Deck:hitTest(x, y)
return not (
(x < self.x) or (x > (self.x + self.w))
or (y < self.y) or (y > (self.y + self.h))
)
end
function Deck:indexOf(card)
if (#self == 0) then
return
end
for i = #self, 1, -1 do
if (card == self[i]) then
return #self - i
end
end
return math.huge
end
function Deck:draw()
if (#self == 0) then
lgsc(1, 1, 0, 1)
lgr("line", self.x, self.y, self.w, self.h, 15)
else
for _, card in ipairs(self) do
card:draw()
end
end
end
function Deck:topCard()
return self[#self]
end
function Deck:pop()
local o = self[#self]
self[#self] = nil
return o
end
function Deck:popAt(atCard)
if (#self == 0) then return end
local deck = Deck:new(mx, my, true);
local count = #self
for i = 1, count do
if (self[i] == atCard) then
for j = i, count do
deck:push(self[j])
self[j] = nil
end
break
end
end
return deck
end
function Deck:new(x, y, tableau, cards)
local o = {}
for k, v in pairs(self) do
o[k] = v
end
o.x = x or 0
o.y = y or 0
o.w = CARDW
o.h = CARDH
o.tableau = tableau
if (cards) then
for _, card in ipairs(cards) do
o:push(card)
end
end
return o
end
--*************************************************************************************************
return Deck, Card