314 lines
7.9 KiB
Lua
314 lines
7.9 KiB
Lua
local lgsc = love.graphics.setColor
|
|
local lgsbgc = love.graphics.setBackgroundColor
|
|
|
|
local Deck, Card = dofile("deck52.lua")
|
|
|
|
local marginX = 20
|
|
local marginY = 20
|
|
local padding = 10
|
|
|
|
local mx, my = 0, 0
|
|
local mb = false
|
|
local cardOffX, cardOffY = 0, 0
|
|
|
|
local slotX = function(v) return (v * CARDW) + ((v + 1) * padding) + marginX end
|
|
local slotY = function(v) return (v * CARDH) + ((v + 1) * padding) + marginY end
|
|
|
|
love.window.setMode(slotX(9), slotY(5))
|
|
|
|
--*************************************************************************************************
|
|
|
|
local stock = Deck:new(slotX(0), slotY(0), false)
|
|
local waste = Deck:new(slotX(1), slotY(0), false)
|
|
|
|
local foundation1 = Deck:new(slotX(3), slotY(0), false)
|
|
local foundation2 = Deck:new(slotX(4), slotY(0), false)
|
|
local foundation3 = Deck:new(slotX(5), slotY(0), false)
|
|
local foundation4 = Deck:new(slotX(6), slotY(0), false)
|
|
|
|
local tableau1 = Deck:new(slotX(0), slotY(1), true)
|
|
local tableau2 = Deck:new(slotX(1), slotY(1), true)
|
|
local tableau3 = Deck:new(slotX(2), slotY(1), true)
|
|
local tableau4 = Deck:new(slotX(3), slotY(1), true)
|
|
local tableau5 = Deck:new(slotX(4), slotY(1), true)
|
|
local tableau6 = Deck:new(slotX(5), slotY(1), true)
|
|
local tableau7 = Deck:new(slotX(6), slotY(1), true)
|
|
|
|
local handDeck = nil
|
|
local undoDeck = nil
|
|
|
|
local decks = {
|
|
stock, waste,
|
|
foundation1, foundation2, foundation3, foundation4,
|
|
tableau1, tableau2, tableau3, tableau4, tableau5, tableau6, tableau7,
|
|
}
|
|
|
|
local tableaus = { tableau1, tableau2, tableau3, tableau4, tableau5, tableau6, tableau7 }
|
|
local foundations = { foundation1, foundation2, foundation3, foundation4 }
|
|
|
|
--*************************************************************************************************
|
|
|
|
local findDeckUnderMouse = function(x, y)
|
|
for _, deck in ipairs(decks) do
|
|
if (#deck > 0) then
|
|
local card = deck:findCardUnderMouse(x, y)
|
|
if (card) then
|
|
return deck, card
|
|
end
|
|
elseif (deck:hitTest(x, y)) then
|
|
return deck
|
|
end
|
|
end
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
local undo = function()
|
|
if (not handDeck or not undoDeck) then return end
|
|
|
|
local count = #handDeck
|
|
for _, card in ipairs(handDeck) do
|
|
undoDeck:push(card)
|
|
end
|
|
|
|
undoDeck:layout()
|
|
|
|
handDeck = nil
|
|
undoDeck = nil
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
local isOddCard = function(card1, card2)
|
|
local suit1 = card1.suit
|
|
local suit2 = card2.suit
|
|
|
|
return (
|
|
(((suit1 == Spade) or (suit1 == Club)) and ((suit2 == Heart) or (suit2 == Diamond)))
|
|
or (((suit1 == Heart) or (suit1 == Diamond)) and ((suit2 == Spade) or (suit2 == Club)))
|
|
)
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
local isAnyOf = function(t, o)
|
|
for _, v in ipairs(t) do
|
|
if (v == o) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
local newGame = function()
|
|
for _, deck in ipairs(decks) do
|
|
deck:empty()
|
|
end
|
|
|
|
for i = 1, 52 do
|
|
stock:push(Card:new(i, 0, 0, FaceDown))
|
|
end
|
|
|
|
stock:shuffle()
|
|
|
|
for i = 1, 7 do
|
|
for j = 1, i do
|
|
local card = stock:pop()
|
|
card.showing = (i == j)
|
|
decks[6 + i]:push(card)
|
|
end
|
|
end
|
|
|
|
for _, deck in ipairs(decks) do
|
|
deck:layout()
|
|
end
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.load = function()
|
|
math.randomseed(os.time())
|
|
|
|
love.graphics.setLineStyle("rough")
|
|
love.graphics.setLineWidth(1)
|
|
love.graphics.setPointSize(1)
|
|
|
|
newGame()
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.mousemoved = function(x, y)
|
|
mx = x
|
|
my = y
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.mousepressed = function(x, y, b)
|
|
if (b == 1) then
|
|
if (hooverDeck == waste) then
|
|
if (hooverCard) then
|
|
undoDeck = waste
|
|
cardOffX = x - hooverCard.x
|
|
cardOffY = y - hooverCard.y
|
|
handDeck = Deck:new(x - cardOffX, y - cardOffY, true)
|
|
local card = hooverDeck:pop()
|
|
card.showing = FaceUp
|
|
handDeck:push(card)
|
|
handDeck:layout()
|
|
end
|
|
elseif (hooverDeck == stock) then
|
|
if (#stock == 0) then
|
|
--Click on empty stock restores it from waste.
|
|
local card = waste:pop()
|
|
while card do
|
|
card.showing = FaceDown
|
|
stock:push(card)
|
|
card = waste:pop()
|
|
end
|
|
|
|
stock:shuffle()
|
|
stock:layout()
|
|
waste:layout()
|
|
else
|
|
--Click on face down card moves it face-up to waste.
|
|
local card = stock:pop()
|
|
card.showing = FaceUp
|
|
waste:push(card)
|
|
waste:layout()
|
|
stock:layout()
|
|
end
|
|
|
|
-- handDeck = nil
|
|
elseif (hooverCard and (hooverCard == hooverDeck:topCard()) and (hooverCard.showing == FaceDown)) then
|
|
--Click on face down card flips it.
|
|
hooverCard.showing = FaceUp
|
|
hooverDeck:layout()
|
|
elseif (hooverCard and hooverCard.showing == FaceUp) then
|
|
undoDeck = hooverDeck
|
|
cardOffX = x - hooverCard.x
|
|
cardOffY = y - hooverCard.y
|
|
handDeck = Deck:new(x - cardOffX, y - cardOffY, true, hooverDeck:popAt(hooverCard))
|
|
hooverDeck:layout()
|
|
end
|
|
elseif (b == 2) then
|
|
if (hooverCard and (hooverCard == hooverDeck:topCard()) and (hooverCard.showing == FaceUp)) then
|
|
for k, deck in ipairs(foundations) do
|
|
local tc = deck:topCard()
|
|
if ((#deck == 0 and hooverCard.rank == 1) or (tc and hooverCard.rank == tc.rank + 1 and hooverCard.suit == tc.suit)) then
|
|
local card = hooverDeck:pop()
|
|
card.showing = FaceUp
|
|
deck:push(card)
|
|
|
|
return --RETURN
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.mousereleased = function(x, y, b)
|
|
if (b ~= 1) then return end
|
|
|
|
if (handDeck and hooverDeck) then
|
|
if (isAnyOf(tableaus, hooverDeck)) then
|
|
if (#hooverDeck == 0) then
|
|
--Drop on empty tableau, only king allowed.
|
|
if (handDeck[1].rank == 13) then
|
|
local count = #handDeck
|
|
for _, card in ipairs(handDeck) do
|
|
hooverDeck:push(card)
|
|
end
|
|
else
|
|
undo()
|
|
end
|
|
elseif (hooverDeck:topCard() == hooverCard) then
|
|
--Must drop on the top card and only odd-colored down-going cards allowed.
|
|
if (
|
|
isOddCard(hooverDeck[#hooverDeck], handDeck[1])
|
|
and (handDeck[1].rank == hooverCard.rank - 1)
|
|
) then
|
|
for _, card in ipairs(handDeck) do
|
|
hooverDeck:push(card)
|
|
end
|
|
else
|
|
undo()
|
|
end
|
|
else
|
|
undo()
|
|
end
|
|
|
|
hooverDeck:layout()
|
|
elseif (#handDeck == 1 and isAnyOf(foundations, hooverDeck)) then
|
|
--Drop on foundation, only one card at a time. Only up-going same sort allowed.
|
|
if (#hooverDeck == 0) then
|
|
--Drop on empty foundation. Only aces allowed.
|
|
if (handDeck[1].rank == 1) then
|
|
hooverDeck:push(handDeck[1])
|
|
else
|
|
undo()
|
|
end
|
|
elseif (
|
|
hooverDeck[#hooverDeck].rank == handDeck[1].rank - 1
|
|
and hooverDeck[#hooverDeck].suit == handDeck[1].suit
|
|
) then
|
|
hooverDeck:push(handDeck[1])
|
|
else
|
|
undo()
|
|
end
|
|
else
|
|
undo()
|
|
end
|
|
|
|
hooverDeck:layout()
|
|
elseif (handDeck) then
|
|
undo()
|
|
end
|
|
|
|
handDeck = nil
|
|
undoDeck = nil
|
|
hooverDeck = nil
|
|
hooverCard = nil
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.keypressed = function(k)
|
|
if (k == "n") then
|
|
newGame()
|
|
elseif (k == "1") then
|
|
backId = 53
|
|
elseif (k == "2") then
|
|
backId = 54
|
|
end
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.update = function(dt)
|
|
hooverDeck, hooverCard = findDeckUnderMouse(mx, my)
|
|
|
|
if (handDeck) then
|
|
handDeck:move(mx - cardOffX, my - cardOffY)
|
|
end
|
|
end
|
|
|
|
--*************************************************************************************************
|
|
|
|
love.draw = function()
|
|
lgsc(1, 1, 1, 1)
|
|
lgsbgc(0.20, 0.40, 0.20, 1)
|
|
|
|
for _, deck in ipairs(decks) do
|
|
deck:draw()
|
|
end
|
|
|
|
if (handDeck) then
|
|
handDeck:draw()
|
|
end
|
|
end
|
|
|