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