@slashin8r

Here is my pack class

```
Pack = class()
--[[
Manages one or more packs of cards
Functions:
shuffle - shuffles the pack
nextCard - returns the next card in the pack
--]]
function Pack:init(p)
self.pack=self:shuffle(p)
end
function Pack:shuffle(p)
n=p or 1 --number of packs, defaults to 1
--set up pile with all the packs in order first
local t={}
for i=1,n do
for j=1,52 do
t[#t+1]=j
end
end
--now sort the pile randomly by pulling cards out at random
local pack={} --table to hold shuffled cards
while #t>0 do
local i=math.random(1,#t)
pack[#pack+1]=t[i]
table.remove(t,i)
end
return pack
end
function Pack:nextCard(p)
if #self.pack==0 then return nil end
local value={"A","2","3","4","5","6","7","8","9","10","J","Q","K"}
local suit={"S","H","D","C"}
local c=self.pack[1]
table.remove(self.pack,1)
local v=(c-1)%13+1
local s=(c-v)/13+1
return {value=value[v],suit=suit[s],valueIndex=v,suitIndex=s,cardIndex=c}
end
function Pack:cards()
return #self.pack
end
```

And here is my card class

```
--# Card
Card = class()
--[[this class builds and draws the card images from scratch and provides some utilities
--]]
--class initialises by creating card design
--Parameters:
--height of card in pixels
--the image to be used on the back
--background color on the face of the card
--(optional) background color on the back of the card
-- (optional) color along the border ofthe card
--returns nothing
function Card:init(height,backImg,faceColor,backColor,borderColor)
self.height = height
self.backImg=backImg
self.f=height/200 --scale font size to card size
self.faceColor=faceColor or color(255)
local x=100 --default border color
self.borderColor=borderColor or color(x, x, x, 255)
x=x*1.5 --corners are drawn with circles which appear darker than lines, so lighten colour for them
self.cornerColor=borderColor or color(x,x,x, 150)
self.backColor=backColor or color(240, 239, 237, 255)
self:createCard()
self:createSuits()
self.value={"A","2","3","4","5","6","7","8","9","10","J","Q","K"}
self.suit={"S","H","D","C"}
end
--this and the next function build just the front and back of the card itself
--the main problem is rounded corners
--this is done by drawing circles at the corners and then overlapping rectangles forthe final effect
function Card:createCard()
self.cardFace=self:createOutline(true)
self.cardBack=self:createOutline(false)
end
function Card:createOutline(face)
--use standard 25/35 ratio
self.width=math.floor(self.height*30/45+.5)
local img=image(self.width,self.height)
--create rounded corner on top right
local corner=0,05 --distance from end of card as percent of height
local c=math.floor(corner*self.height+0.5)
setContext(img)
pushStyle()
strokeWidth(1)
stroke(self.cornerColor)
--set background colour
if face then fill(self.faceColor) else fill(self.backColor) end
--draw small circles at corners
ellipse(self.width-c+1,self.height-c+1,c*2)
ellipse(self.width-c+1,c-1,c*2)
ellipse(c-1,self.height-c+1,c*2)
ellipse(c-1,c-1,c*2)
if face then stroke(self.faceColor) else stroke(self.backColor) end
--now rectangles to fill in thre centre of the card
rect(0,c,self.width,self.height-c*2)
rect(c,0,self.width-c*2,self.height)
--now a border round the card
stroke(self.borderColor)
line(0,c,0,self.height-c)
line(c,0,self.width-c,0)
line(self.width,c,self.width,self.height-c)
line(c,self.height,self.width-c,self.height)
--do picture on back
if face~=true then
sprite(self.backImg,img.width/2,img.height/2,img.width*.9)
end
popStyle()
setContext()
return img
end
--the suit images come from emoji
function Card:createSuits()
font("AppleColorEmoji")
self.suits={unicode2UTF8(9824),unicode2UTF8(9829),unicode2UTF8(9830),unicode2UTF8(9827)}
end
--draws a card at x,y with value of card (1-52), face=true if face up, a=angle in degrees (default 0)
function Card:draw(x,y,card,face,a)
pushMatrix()
translate(x+self.width/2,y-self.height/2)
if a==nil then a=0 end
rotate(a)
if face then
if card>0 then self:drawDetails(card) else sprite(self.cardFace,0,0) end
else
sprite(self.cardBack,0,0)
end
popMatrix()
end
--draws the numbers and symbols on the front of the card
--one parameter = card value
function Card:drawDetails(card)
sprite(self.cardFace,0,0)
pushStyle()
font("SourceSansPro-Regular")
fontSize(24*self.f)
--calculate suit and value of card
card=card-1
local v=card%13
local s=(card-v)/13+1
v=v+1
local w=self.cardFace.width
local h=self.cardFace.height
if s==1 or s==4 then fill(0,0, 0, 255) else fill(255,0,0,255) end --fill is red or black
--half the images on a card are upside down
--so we do them in two loops, turning the card upside down between them
--where the card is not exactly symmetrical, eg for odd numbers, we only draw on the first loop
for i=1,2 do
if i==2 then rotate(180) end --turn 180 degrees to do second loop
local u=self.suits[s]
text(self.value[v],-w*.4,h*.4) --text in corner of card
fontSize(16*self.f)
text(u,-w*.4,h*.28) --suit image
fontSize(28*self.f)
local ss=.13*h
--now all the symbols arranged in the middle of the card
if v==1 then
if i==1 then text(u,0,0) end
elseif v==2 then
text(u,0,.3*h)
elseif v==3 then
if i==1 then text(u,0,0) end
text(u,0,.3*h)
elseif v==4 then
text(u,-w*.18,.15*h)
text(u,w*.18,.15*h)
elseif v==5 then
text(u,-w*.18,.3*h)
text(u,w*.18,.3*h)
if i==1 then text(u,0,0) end
elseif v==6 then
text(u,-w*.18,.3*h)
text(u,w*.18,.3*h)
text(u,-w*.18,0)
elseif v==7 then
text(u,-w*.18,.3*h)
text(u,w*.18,.3*h)
text(u,-w*.18,0)
if i==1 then text(u,0,.15*h) end
elseif v==8 then
text(u,-w*.18,.3*h)
text(u,w*.18,.3*h)
text(u,-w*.18,0)
text(u,0,.15*h)
elseif v==9 then
text(u,-w*.18,.3*h)
text(u,w*.18,.3*h)
if i==1 then text(u,0,0) end
text(u,-w*.18,.1*h)
text(u,w*.18,.1*h)
elseif v==10 then
text(u,-w*.18,.3*h)
text(u,w*.18,.3*h)
text(u,-w*.18,.1*h)
text(u,w*.18,.1*h)
text(u,0,.2*h)
else --royalty
pushStyle()
font("AppleColorEmoji")
fill(255)
fontSize(84*self.f)
if i==1 then
if v==11 then text(unicode2UTF8(128113))
elseif v==12 then text(unicode2UTF8(128120))
else text(unicode2UTF8(128116))
end
end
popStyle()
end
end
popStyle()
end
--used by Main and other classes
--given a value 1-52, it returns the value and suit in text and numbers, eg S,J,1,11
function Card:SuitValue(c)
local v=(c-1)%13
local s=(c-1-v)/13+1
v = v + 1
return self.value[v],self.suit[s],v,s
end
function unicode2UTF8(u) --needed for emoji
u = math.max(0, math.floor(u)) -- A positive integer
local UTF8
if u < 0x80 then -- less than 8 bits
UTF8 = string.char(u)
elseif u < 0x800 then -- less than 12 bits
local b2 = u % 0x40 + 0x80
local b1 = math.floor(u/0x40) + 0xC0
UTF8 = string.char(b1, b2)
elseif u < 0x10000 then -- less than 16 bits
local b3 = u % 0x40 + 0x80
local b2 = math.floor(u/0x40) % 0x40 + 0x80
local b1 = math.floor(u/0x1000) + 0xE0
UTF8 = string.char(b1, b2, b3)
elseif u < 0x200000 then -- less than 22 bits
local b4 = u % 0x40 + 0x80
local b3 = math.floor(u/0x40) % 0x40 + 0x80
local b2 = math.floor(u/0x1000) % 0x40 + 0x80
local b1 = math.floor(u/0x40000) + 0xF0
UTF8 = string.char(b1, b2, b3, b4)
elseif u < 0x800000 then -- less than 24 bits
local b5 = u % 0x40 + 0x80
local b4 = math.floor(u/0x40) % 0x40 + 0x80
local b3 = math.floor(u/0x1000) % 0x40 + 0x80
local b2 = math.floor(u/0x40000) % 0x40 + 0x80
local b1 = math.floor(u/0x1000000) + 0xF8
UTF8 = string.char(b1, b2, b3, b4, b5)
else
print("Error: Code point too large for Codea's Lua.")
end
return UTF8
end
```