Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Blackjack Turtle Casino
- -- Centered-card UI with left info panel
- -- ComputerCraft / CC:Tweaked style program
- -- Designed for Advanced Monitor wall, 3 tall x 7 wide
- -- Uses a turtle as the diamond bank/payout machine
- -- Uses speaker if available
- --------------------------------------------------
- -- CONFIG
- --------------------------------------------------
- local DIAMOND_ID = "minecraft:diamond"
- local TEXT_SCALE = 0.5
- local MIN_BET = 1
- local MAX_BET = 999
- local MAX_BET_AMOUNT = 999
- local DEALER_HITS_SOFT_17 = true
- local BLACKJACK_PAYS_NUMERATOR = 3
- local BLACKJACK_PAYS_DENOMINATOR = 2
- -- Blackjack profit is 3:2.
- -- Total payout = bet + floor(bet * 3 / 2).
- -- Example:
- -- 2 diamond bet blackjack pays 5 total.
- -- 1 diamond bet blackjack pays 2 total because diamonds cannot split.
- local SHOE_DECKS = 6
- local SHUFFLE_AT_CARDS_LEFT = 30
- local CASINO_MENU_PROGRAM = "casino"
- local CASINO_BANK_FILE = "casino_bank_base.txt"
- --------------------------------------------------
- -- PERIPHERALS
- --------------------------------------------------
- local mon = peripheral.find("monitor")
- if not mon then
- error("No monitor found. Attach/wrap an advanced monitor wall.")
- end
- local speaker = nil
- for _, name in ipairs(peripheral.getNames()) do
- local p = peripheral.wrap(name)
- if p then
- if type(p.playNote) == "function" or type(p.playSound) == "function" then
- speaker = p
- break
- end
- end
- end
- mon.setTextScale(TEXT_SCALE)
- mon.setBackgroundColor(colors.green)
- mon.setTextColor(colors.white)
- mon.clear()
- local W, H = mon.getSize()
- --------------------------------------------------
- -- UTILS
- --------------------------------------------------
- local function clamp(v, a, b)
- if v < a then return a end
- if v > b then return b end
- return v
- end
- local function writeAt(x, y, text, fg, bg)
- if bg then mon.setBackgroundColor(bg) end
- if fg then mon.setTextColor(fg) end
- mon.setCursorPos(x, y)
- mon.write(text)
- end
- local function fillBox(x, y, w, h, bg)
- if w <= 0 or h <= 0 then return end
- mon.setBackgroundColor(bg)
- for yy = y, y + h - 1 do
- if yy >= 1 and yy <= H then
- mon.setCursorPos(x, yy)
- mon.write(string.rep(" ", math.max(0, math.min(w, W - x + 1))))
- end
- end
- end
- local function centerText(x, y, w, text, fg, bg)
- text = tostring(text)
- if #text > w then
- text = string.sub(text, 1, w)
- end
- local pad = math.floor((w - #text) / 2)
- writeAt(x + pad, y, text, fg, bg)
- end
- local function drawButton(x, y, w, h, label, bg, fg)
- fillBox(x, y, w, h, bg)
- local cy = y + math.floor(h / 2)
- centerText(x, cy, w, label, fg or colors.white, bg)
- end
- local function inBox(px, py, box)
- return px >= box.x and px < box.x + box.w and py >= box.y and py < box.y + box.h
- end
- local function money(n)
- return tostring(math.floor(n or 0))
- end
- --------------------------------------------------
- -- DIAMOND BANKING
- --------------------------------------------------
- local function countDiamonds()
- local total = 0
- for slot = 1, 16 do
- local d = turtle.getItemDetail(slot)
- if d and d.name == DIAMOND_ID then
- total = total + d.count
- end
- end
- return total
- end
- local function selectDiamondSlot()
- for slot = 1, 16 do
- local d = turtle.getItemDetail(slot)
- if d and d.name == DIAMOND_ID and d.count > 0 then
- turtle.select(slot)
- return true
- end
- end
- return false
- end
- local function pullDiamondsFromAboveUntil(amountNeeded)
- local tries = 0
- while countDiamonds() < amountNeeded and tries < 64 do
- tries = tries + 1
- local pulled = turtle.suckUp(64)
- if not pulled then
- break
- end
- sleep(0.05)
- end
- return countDiamonds() >= amountNeeded
- end
- local function dropDiamondsDown(amount)
- local remaining = amount
- while remaining > 0 do
- if not selectDiamondSlot() then
- return false, amount - remaining
- end
- local d = turtle.getItemDetail()
- if not d or d.name ~= DIAMOND_ID then
- return false, amount - remaining
- end
- local toDrop = math.min(remaining, d.count)
- local ok = turtle.dropDown(toDrop)
- if not ok then
- return false, amount - remaining
- end
- remaining = remaining - toDrop
- sleep(0.03)
- end
- return true, amount
- end
- local function loadBankBase()
- if fs.exists(CASINO_BANK_FILE) then
- local f = fs.open(CASINO_BANK_FILE, "r")
- if f then
- local raw = f.readAll()
- f.close()
- local n = tonumber(raw)
- if n and n >= 0 then
- return n
- end
- end
- end
- return countDiamonds()
- end
- local bankBase = loadBankBase()
- local function saveBankBase()
- local f = fs.open(CASINO_BANK_FILE, "w")
- if f then
- f.write(tostring(math.floor(bankBase)))
- f.close()
- end
- end
- saveBankBase()
- --------------------------------------------------
- -- SOUND
- --------------------------------------------------
- local function playNoteSafe(instrument, volume, pitch)
- if not speaker then return end
- instrument = instrument or "harp"
- volume = volume or 1
- pitch = pitch or 12
- if type(speaker.playNote) == "function" then
- local ok = pcall(function()
- speaker.playNote(instrument, volume, pitch)
- end)
- if ok then
- return
- end
- end
- if type(speaker.playSound) == "function" then
- pcall(function()
- speaker.playSound("note.harp", volume, 1)
- end)
- end
- end
- local function soundClick()
- playNoteSafe("hat", 0.8, 12)
- end
- local function soundDeal()
- playNoteSafe("hat", 0.7, 14)
- sleep(0.04)
- end
- local function soundWin()
- playNoteSafe("bell", 1, 16)
- sleep(0.08)
- playNoteSafe("bell", 1, 20)
- sleep(0.08)
- playNoteSafe("bell", 1, 24)
- end
- local function soundBlackjack()
- playNoteSafe("bell", 1, 16)
- sleep(0.06)
- playNoteSafe("bell", 1, 20)
- sleep(0.06)
- playNoteSafe("bell", 1, 24)
- sleep(0.06)
- playNoteSafe("bell", 1, 28)
- end
- local function soundLoss()
- playNoteSafe("bass", 1, 6)
- sleep(0.12)
- playNoteSafe("bass", 1, 4)
- end
- local function soundPush()
- playNoteSafe("harp", 1, 12)
- sleep(0.08)
- playNoteSafe("harp", 1, 12)
- end
- --------------------------------------------------
- -- CARD / SHOE LOGIC
- --------------------------------------------------
- math.randomseed(os.epoch and os.epoch("utc") or os.clock() * 100000)
- local suits = {
- {name = "S", color = colors.black},
- {name = "H", color = colors.red},
- {name = "D", color = colors.red},
- {name = "C", color = colors.black}
- }
- local ranks = {
- {name = "A", value = 11},
- {name = "2", value = 2},
- {name = "3", value = 3},
- {name = "4", value = 4},
- {name = "5", value = 5},
- {name = "6", value = 6},
- {name = "7", value = 7},
- {name = "8", value = 8},
- {name = "9", value = 9},
- {name = "10", value = 10},
- {name = "J", value = 10},
- {name = "Q", value = 10},
- {name = "K", value = 10}
- }
- local shoe = {}
- local function shuffleShoe()
- shoe = {}
- for deck = 1, SHOE_DECKS do
- for _, suit in ipairs(suits) do
- for _, rank in ipairs(ranks) do
- table.insert(shoe, {
- rank = rank.name,
- value = rank.value,
- suit = suit.name,
- color = suit.color
- })
- end
- end
- end
- for i = #shoe, 2, -1 do
- local j = math.random(1, i)
- shoe[i], shoe[j] = shoe[j], shoe[i]
- end
- end
- local function drawCardFromShoe()
- if #shoe <= SHUFFLE_AT_CARDS_LEFT then
- shuffleShoe()
- end
- local card = table.remove(shoe)
- soundDeal()
- return card
- end
- local function handValue(hand)
- local total = 0
- local aces = 0
- for _, card in ipairs(hand) do
- total = total + card.value
- if card.rank == "A" then
- aces = aces + 1
- end
- end
- while total > 21 and aces > 0 do
- total = total - 10
- aces = aces - 1
- end
- local soft = aces > 0
- return total, soft
- end
- local function isBlackjack(hand)
- if #hand ~= 2 then
- return false
- end
- local value = handValue(hand)
- return value == 21
- end
- --------------------------------------------------
- -- GAME STATE
- --------------------------------------------------
- local STATE_BETTING = "betting"
- local STATE_PLAYER = "player"
- local STATE_DEALER = "dealer"
- local STATE_ROUND_OVER = "round_over"
- local state = STATE_BETTING
- local playerHand = {}
- local dealerHand = {}
- local currentBet = 0
- local originalBet = 0
- local betAmount = 1
- local message = "Set bet amount, then press DEAL."
- local revealDealer = false
- local lastOutcome = nil
- local hitBoxes = {}
- local confirmMode = nil
- local drawAll
- local function availableCredits()
- local current = countDiamonds()
- local credits = current - bankBase - currentBet
- if credits < 0 then
- credits = 0
- end
- return credits
- end
- local function roundIsActive()
- return state == STATE_PLAYER or state == STATE_DEALER
- end
- --------------------------------------------------
- -- BET AMOUNT CONTROLS
- --------------------------------------------------
- local function changeBetAmount(delta)
- if roundIsActive() or confirmMode then
- message = "Cannot change bet amount during a hand."
- soundLoss()
- return
- end
- betAmount = betAmount + delta
- betAmount = clamp(betAmount, MIN_BET, MAX_BET_AMOUNT)
- message = "Bet amount set to " .. betAmount .. " diamond(s). Press DEAL to start."
- soundClick()
- end
- local function resetBetAmount()
- if roundIsActive() or confirmMode then
- message = "Cannot reset bet amount during a hand."
- soundLoss()
- return
- end
- betAmount = 1
- message = "Bet amount reset to 1 diamond."
- soundClick()
- end
- local function clearBet()
- if roundIsActive() then
- message = "Cannot clear bet during an active hand."
- soundLoss()
- return
- end
- currentBet = 0
- originalBet = 0
- if state == STATE_ROUND_OVER then
- playerHand = {}
- dealerHand = {}
- revealDealer = false
- lastOutcome = nil
- state = STATE_BETTING
- end
- message = "Bet cleared. Press DEAL to use current bet amount."
- soundClick()
- end
- --------------------------------------------------
- -- CASH OUT / MENU LOGIC
- --------------------------------------------------
- local function resetRoundForExitOrCashout()
- currentBet = 0
- originalBet = 0
- playerHand = {}
- dealerHand = {}
- revealDealer = false
- lastOutcome = nil
- state = STATE_BETTING
- end
- local function cashOutCredits()
- if roundIsActive() then
- message = "Cannot cash out directly during a hand."
- soundLoss()
- return
- end
- local amount = availableCredits()
- if amount <= 0 then
- message = "No unbet credits to cash out."
- soundLoss()
- return
- end
- local ok, dropped = dropDiamondsDown(amount)
- if ok then
- message = "Cashed out " .. dropped .. " diamond(s) below."
- soundWin()
- else
- message = "Cash out blocked! Dropped " .. dropped .. "/" .. amount .. "."
- soundLoss()
- end
- saveBankBase()
- end
- local function requestCashOut()
- if currentBet > 0 or roundIsActive() then
- confirmMode = "cashout"
- message = "Confirm cash out. Active bet/hand will be cleared first."
- soundLoss()
- return
- end
- cashOutCredits()
- end
- local function exitToMenuNow()
- resetRoundForExitOrCashout()
- confirmMode = nil
- saveBankBase()
- mon.setBackgroundColor(colors.black)
- mon.setTextColor(colors.white)
- mon.clear()
- if shell then
- if fs.exists(CASINO_MENU_PROGRAM) then
- shell.run(CASINO_MENU_PROGRAM)
- elseif fs.exists(CASINO_MENU_PROGRAM .. ".lua") then
- shell.run(CASINO_MENU_PROGRAM .. ".lua")
- else
- print("Casino menu not found.")
- print("Expected: " .. CASINO_MENU_PROGRAM)
- end
- end
- error("Exited to casino menu", 0)
- end
- local function requestExit()
- if currentBet > 0 or roundIsActive() then
- confirmMode = "exit"
- message = "Confirm menu. Active bet/hand will be cleared."
- soundLoss()
- return
- end
- exitToMenuNow()
- end
- --------------------------------------------------
- -- PAYOUT HANDLING
- --------------------------------------------------
- local function payPlayer(amount, outcomeMessage, soundFunc)
- local unbetCredits = availableCredits()
- if amount <= 0 then
- message = outcomeMessage or "No payout."
- if soundFunc then soundFunc() end
- return
- end
- message = outcomeMessage .. " Paying " .. amount .. " diamonds."
- if soundFunc then soundFunc() end
- local enough = pullDiamondsFromAboveUntil(amount)
- if enough then
- local ok, dropped = dropDiamondsDown(amount)
- if ok then
- message = outcomeMessage .. " Paid " .. dropped .. " diamonds below."
- else
- message = "Payout blocked! Dropped " .. dropped .. "/" .. amount
- end
- else
- local available = countDiamonds()
- local _, dropped = dropDiamondsDown(available)
- message = "HOUSE EMPTY! Paid only " .. dropped .. "/" .. amount .. "."
- end
- local after = countDiamonds()
- bankBase = after - unbetCredits
- if bankBase < 0 then
- bankBase = 0
- end
- saveBankBase()
- end
- local function houseKeepsBet()
- bankBase = bankBase + currentBet
- saveBankBase()
- end
- local function finishRound(outcome, payoutAmount, msg, soundFunc)
- lastOutcome = outcome
- revealDealer = true
- if payoutAmount and payoutAmount > 0 then
- payPlayer(payoutAmount, msg, soundFunc)
- else
- if outcome == "loss" then
- houseKeepsBet()
- end
- message = msg
- if soundFunc then soundFunc() end
- end
- currentBet = 0
- originalBet = 0
- state = STATE_ROUND_OVER
- end
- --------------------------------------------------
- -- ROUND LOGIC
- --------------------------------------------------
- local function dealCardTo(hand)
- table.insert(hand, drawCardFromShoe())
- drawAll()
- sleep(0.10)
- end
- local function startDeal()
- if state == STATE_PLAYER or state == STATE_DEALER then
- return
- end
- if state == STATE_ROUND_OVER then
- playerHand = {}
- dealerHand = {}
- revealDealer = false
- lastOutcome = nil
- state = STATE_BETTING
- end
- if currentBet < MIN_BET then
- if betAmount < MIN_BET then
- message = "Bet amount must be at least " .. MIN_BET .. "."
- soundLoss()
- return
- end
- if availableCredits() < betAmount then
- message = "Not enough credits. Need " .. betAmount .. " diamond(s)."
- soundLoss()
- return
- end
- currentBet = betAmount
- originalBet = currentBet
- else
- originalBet = currentBet
- end
- playerHand = {}
- dealerHand = {}
- revealDealer = false
- lastOutcome = nil
- message = "Dealing..."
- drawAll()
- dealCardTo(playerHand)
- dealCardTo(dealerHand)
- dealCardTo(playerHand)
- dealCardTo(dealerHand)
- local playerBJ = isBlackjack(playerHand)
- local dealerBJ = isBlackjack(dealerHand)
- if playerBJ or dealerBJ then
- revealDealer = true
- drawAll()
- if playerBJ and dealerBJ then
- finishRound(
- "push",
- currentBet,
- "Both have blackjack. Push.",
- soundPush
- )
- elseif playerBJ then
- local profit = math.floor(currentBet * BLACKJACK_PAYS_NUMERATOR / BLACKJACK_PAYS_DENOMINATOR)
- local payout = currentBet + profit
- finishRound(
- "blackjack",
- payout,
- "BLACKJACK!",
- soundBlackjack
- )
- else
- finishRound(
- "loss",
- 0,
- "Dealer has blackjack. You lose.",
- soundLoss
- )
- end
- return
- end
- state = STATE_PLAYER
- message = "Your turn. Hit, Stand, or Double."
- end
- local function playerHit()
- if state ~= STATE_PLAYER then
- return
- end
- dealCardTo(playerHand)
- local value = handValue(playerHand)
- if value > 21 then
- revealDealer = true
- finishRound(
- "loss",
- 0,
- "Bust! You lose.",
- soundLoss
- )
- else
- message = "You drew a card. Hand value: " .. value
- end
- end
- local function dealerShouldHit()
- local value, soft = handValue(dealerHand)
- if value < 17 then
- return true
- end
- if value == 17 and soft and DEALER_HITS_SOFT_17 then
- return true
- end
- return false
- end
- local function resolveDealer()
- state = STATE_DEALER
- revealDealer = true
- message = "Dealer's turn."
- drawAll()
- sleep(0.25)
- while dealerShouldHit() do
- dealCardTo(dealerHand)
- sleep(0.20)
- end
- local playerValue = handValue(playerHand)
- local dealerValue = handValue(dealerHand)
- if dealerValue > 21 then
- finishRound(
- "win",
- currentBet * 2,
- "Dealer busts. You win!",
- soundWin
- )
- elseif playerValue > dealerValue then
- finishRound(
- "win",
- currentBet * 2,
- "You win!",
- soundWin
- )
- elseif playerValue < dealerValue then
- finishRound(
- "loss",
- 0,
- "Dealer wins.",
- soundLoss
- )
- else
- finishRound(
- "push",
- currentBet,
- "Push. Bet returned.",
- soundPush
- )
- end
- end
- local function playerStand()
- if state ~= STATE_PLAYER then
- return
- end
- resolveDealer()
- end
- local function playerDouble()
- if state ~= STATE_PLAYER then
- return
- end
- if #playerHand ~= 2 then
- message = "Double only allowed on your first 2 cards."
- soundLoss()
- return
- end
- if availableCredits() < originalBet then
- message = "Need " .. originalBet .. " more diamonds to double."
- soundLoss()
- return
- end
- currentBet = currentBet + originalBet
- message = "Double down! Bet is now " .. currentBet .. "."
- soundClick()
- drawAll()
- sleep(0.12)
- dealCardTo(playerHand)
- local value = handValue(playerHand)
- if value > 21 then
- revealDealer = true
- finishRound(
- "loss",
- 0,
- "Double bust! You lose.",
- soundLoss
- )
- else
- resolveDealer()
- end
- end
- --------------------------------------------------
- -- DRAWING
- --------------------------------------------------
- local function resetHitBoxes()
- hitBoxes = {}
- end
- local function addHit(id, x, y, w, h)
- table.insert(hitBoxes, {
- id = id,
- x = x,
- y = y,
- w = w,
- h = h
- })
- end
- local function drawFrame()
- fillBox(1, 1, W, H, colors.green)
- fillBox(1, 1, W, 1, colors.black)
- centerText(1, 1, W, "BLACKJACK | DIAMOND CASINO", colors.lime, colors.black)
- end
- local function drawLeftInfoPanel()
- local x = 2
- local y = 3
- local w = 38
- local h = 13
- fillBox(x, y, w, h, colors.black)
- centerText(x, y, w, "GAME INFO", colors.yellow, colors.black)
- writeAt(x + 2, y + 2, "Credits: " .. money(availableCredits()), colors.lime, colors.black)
- writeAt(x + 2, y + 3, "Current Bet: " .. money(currentBet), colors.yellow, colors.black)
- writeAt(x + 2, y + 4, "Bet Amount: " .. money(betAmount), colors.orange, colors.black)
- writeAt(x + 2, y + 5, "Diamonds In Turtle: " .. money(countDiamonds()), colors.white, colors.black)
- writeAt(x + 2, y + 6, "House Bank Base: " .. money(bankBase), colors.lightGray, colors.black)
- writeAt(x + 2, y + 7, "Shoe Left: " .. tostring(#shoe), colors.lightGray, colors.black)
- local soft17Text = "Dealer hits soft 17: "
- if DEALER_HITS_SOFT_17 then
- soft17Text = soft17Text .. "YES"
- else
- soft17Text = soft17Text .. "NO"
- end
- writeAt(x + 2, y + 8, soft17Text, colors.lightGray, colors.black)
- fillBox(x + 1, y + 10, w - 2, 2, colors.gray)
- local msg = message
- if #msg > w - 4 then
- msg = string.sub(msg, 1, w - 4)
- end
- writeAt(x + 2, y + 10, msg, colors.white, colors.gray)
- end
- local function drawCardBox(x, y, card, hidden)
- local w = 8
- local h = 5
- if hidden then
- fillBox(x, y, w, h, colors.blue)
- centerText(x, y + 2, w, "???", colors.white, colors.blue)
- return
- end
- local bg = colors.white
- local fg = card.color
- fillBox(x, y, w, h, bg)
- writeAt(x + 1, y, card.rank, fg, bg)
- centerText(x, y + 2, w, card.suit, fg, bg)
- writeAt(x + w - #card.rank, y + h - 1, card.rank, fg, bg)
- end
- local function drawCardPlaceholder(x, y)
- local w = 8
- local h = 5
- fillBox(x, y, w, h, colors.lightGray)
- centerText(x, y + 2, w, "--", colors.gray, colors.lightGray)
- end
- local function handAreaBounds()
- local leftEdge = 43
- local rightEdge = W - 2
- if leftEdge > rightEdge then
- leftEdge = 2
- rightEdge = W - 2
- end
- return leftEdge, rightEdge, rightEdge - leftEdge + 1
- end
- local function getCenteredHandX(count)
- local cardW = 8
- local gap = 1
- local leftEdge, _, areaW = handAreaBounds()
- local totalW = count * cardW + math.max(0, count - 1) * gap
- if totalW > areaW then
- gap = 0
- totalW = count * cardW + math.max(0, count - 1) * gap
- end
- local startX = leftEdge + math.floor((areaW - totalW) / 2)
- if startX < leftEdge then
- startX = leftEdge
- end
- return startX, cardW, gap
- end
- local function drawCenteredHand(title, hand, labelY, hideDealerSecondCard)
- local valueText
- if hideDealerSecondCard and #hand > 0 then
- local shown = hand[1].value
- if hand[1].rank == "A" then
- shown = 11
- end
- valueText = "Showing: " .. shown
- elseif #hand > 0 then
- local v, soft = handValue(hand)
- valueText = "Value: " .. v
- if soft and v <= 21 then
- valueText = valueText .. " soft"
- end
- else
- valueText = "Value: --"
- end
- local leftEdge, _, areaW = handAreaBounds()
- centerText(leftEdge, labelY, areaW, title .. " " .. valueText, colors.white, colors.green)
- local cardY = labelY + 1
- local count = math.max(2, #hand)
- local startX, cardW, gap = getCenteredHandX(count)
- if #hand == 0 then
- for i = 1, 2 do
- local x = startX + (i - 1) * (cardW + gap)
- drawCardPlaceholder(x, cardY)
- end
- return
- end
- for i, card in ipairs(hand) do
- local x = startX + (i - 1) * (cardW + gap)
- local hidden = false
- if hideDealerSecondCard and i == 2 then
- hidden = true
- end
- drawCardBox(x, cardY, card, hidden)
- end
- end
- local function drawCardArea()
- local bottomControlsY = H - 9
- local actionRowY = H - 13
- local playerLabelY = actionRowY - 8
- local dealerLabelY = playerLabelY - 8
- if dealerLabelY < 6 then
- dealerLabelY = 6
- playerLabelY = dealerLabelY + 8
- end
- drawCenteredHand("DEALER", dealerHand, dealerLabelY, (not revealDealer and #dealerHand > 0))
- drawCenteredHand("PLAYER", playerHand, playerLabelY, false)
- local leftEdge, _, areaW = handAreaBounds()
- if state == STATE_PLAYER then
- centerText(leftEdge, playerLabelY - 2, areaW, "YOUR TURN", colors.yellow, colors.green)
- elseif state == STATE_DEALER then
- centerText(leftEdge, playerLabelY - 2, areaW, "DEALER PLAYING...", colors.yellow, colors.green)
- elseif state == STATE_ROUND_OVER and lastOutcome then
- local outcomeText = "ROUND OVER"
- if lastOutcome == "win" then
- outcomeText = "YOU WIN"
- elseif lastOutcome == "loss" then
- outcomeText = "YOU LOSE"
- elseif lastOutcome == "push" then
- outcomeText = "PUSH"
- elseif lastOutcome == "blackjack" then
- outcomeText = "BLACKJACK!"
- end
- centerText(leftEdge, playerLabelY - 2, areaW, outcomeText, colors.yellow, colors.green)
- end
- end
- local function drawActionRow()
- local y = H - 13
- local h = 3
- local buttons = {}
- if state == STATE_PLAYER then
- buttons = {
- {"HIT", "HIT", colors.lime, colors.black},
- {"STAND", "STAND", colors.yellow, colors.black},
- {"DOUBLE", "DOUBLE", colors.orange, colors.black},
- {"EXIT_MENU", "MENU", colors.gray, colors.white}
- }
- else
- buttons = {
- {"CLEAR_BET", "CLEAR BET", colors.red, colors.white},
- {"DEAL", "DEAL", colors.lime, colors.black},
- {"EXIT_MENU", "MENU", colors.gray, colors.white}
- }
- end
- local gap = 2
- local count = #buttons
- local btnW
- if count == 4 then
- btnW = 18
- else
- btnW = 22
- end
- local totalW = count * btnW + (count - 1) * gap
- local x = math.floor((W - totalW) / 2)
- for i, b in ipairs(buttons) do
- local id, label, bg, fg = b[1], b[2], b[3], b[4]
- local bx = x + (i - 1) * (btnW + gap)
- drawButton(bx, y, btnW, h, label, bg, fg)
- addHit(id, bx, y, btnW, h)
- end
- end
- local function drawBottomBetControls()
- local panelW = math.min(W - 6, 124)
- local x = math.floor((W - panelW) / 2)
- local y = H - 9
- local panelH = 8
- fillBox(x, y, panelW, panelH, colors.black)
- centerText(x, y, panelW, "BET CONTROLS | CURRENT BET AMOUNT: " .. betAmount, colors.yellow, colors.black)
- local gap = 1
- local smallW = math.floor((panelW - 4 - gap * 2) / 3)
- drawButton(x + 1, y + 1, smallW, 2, "+1", colors.lime, colors.black)
- addHit("BETAMT:+1", x + 1, y + 1, smallW, 2)
- drawButton(x + 1 + smallW + gap, y + 1, smallW, 2, "+5", colors.lime, colors.black)
- addHit("BETAMT:+5", x + 1 + smallW + gap, y + 1, smallW, 2)
- drawButton(x + 1 + (smallW + gap) * 2, y + 1, smallW, 2, "+10", colors.lime, colors.black)
- addHit("BETAMT:+10", x + 1 + (smallW + gap) * 2, y + 1, smallW, 2)
- drawButton(x + 1, y + 3, smallW, 2, "-1", colors.orange, colors.black)
- addHit("BETAMT:-1", x + 1, y + 3, smallW, 2)
- drawButton(x + 1 + smallW + gap, y + 3, smallW, 2, "-5", colors.orange, colors.black)
- addHit("BETAMT:-5", x + 1 + smallW + gap, y + 3, smallW, 2)
- drawButton(x + 1 + (smallW + gap) * 2, y + 3, smallW, 2, "-10", colors.orange, colors.black)
- addHit("BETAMT:-10", x + 1 + (smallW + gap) * 2, y + 3, smallW, 2)
- local halfW = math.floor((panelW - 3) / 2)
- drawButton(x + 1, y + 5, halfW, 3, "RESET AMT", colors.gray, colors.white)
- addHit("BETAMT:RESET", x + 1, y + 5, halfW, 3)
- drawButton(x + 2 + halfW, y + 5, halfW, 3, "CASH OUT", colors.yellow, colors.black)
- addHit("ACTION:CASHOUT", x + 2 + halfW, y + 5, halfW, 3)
- end
- local function drawConfirmScreen()
- resetHitBoxes()
- fillBox(1, 1, W, H, colors.black)
- if confirmMode == "exit" then
- centerText(1, 4, W, "CONFIRM RETURN TO GAME MENU", colors.yellow, colors.black)
- if roundIsActive() then
- centerText(1, 7, W, "A hand is currently active.", colors.white, colors.black)
- centerText(1, 9, W, "Leaving now will cancel the hand and clear the bet back to credits.", colors.lightGray, colors.black)
- elseif currentBet > 0 then
- centerText(1, 7, W, "You have a " .. currentBet .. " diamond bet staged.", colors.white, colors.black)
- centerText(1, 9, W, "Leaving will clear that bet back into your credits.", colors.lightGray, colors.black)
- end
- centerText(1, 11, W, "No diamonds will be paid out or removed.", colors.lightGray, colors.black)
- elseif confirmMode == "cashout" then
- centerText(1, 4, W, "CONFIRM CASH OUT", colors.yellow, colors.black)
- if roundIsActive() then
- centerText(1, 7, W, "A hand is currently active.", colors.white, colors.black)
- centerText(1, 9, W, "Cash out will cancel the hand and clear the bet back to credits.", colors.lightGray, colors.black)
- elseif currentBet > 0 then
- centerText(1, 7, W, "You have a " .. currentBet .. " diamond bet staged.", colors.white, colors.black)
- centerText(1, 9, W, "Cash out will clear the bet back into credits first.", colors.lightGray, colors.black)
- end
- centerText(1, 11, W, "Then all player credits will drop below the turtle.", colors.lightGray, colors.black)
- end
- local btnW = 32
- local btnH = 5
- local gap = 6
- local totalW = btnW * 2 + gap
- local startX = math.floor((W - totalW) / 2)
- local y = 16
- drawButton(startX, y, btnW, btnH, "CANCEL", colors.lime, colors.black)
- addHit("CONFIRM_CANCEL", startX, y, btnW, btnH)
- if confirmMode == "exit" then
- drawButton(startX + btnW + gap, y, btnW, btnH, "MENU - CLEAR BET", colors.red, colors.white)
- addHit("CONFIRM_YES", startX + btnW + gap, y, btnW, btnH)
- elseif confirmMode == "cashout" then
- drawButton(startX + btnW + gap, y, btnW, btnH, "CASH OUT ALL", colors.yellow, colors.black)
- addHit("CONFIRM_YES", startX + btnW + gap, y, btnW, btnH)
- end
- end
- drawAll = function()
- if confirmMode then
- drawConfirmScreen()
- return
- end
- resetHitBoxes()
- drawFrame()
- drawLeftInfoPanel()
- drawCardArea()
- drawActionRow()
- drawBottomBetControls()
- end
- --------------------------------------------------
- -- INPUT
- --------------------------------------------------
- local function handleConfirmTouch(x, y)
- for _, box in ipairs(hitBoxes) do
- if inBox(x, y, box) then
- if box.id == "CONFIRM_CANCEL" then
- confirmMode = nil
- message = "Action cancelled."
- soundClick()
- drawAll()
- return true
- elseif box.id == "CONFIRM_YES" then
- if confirmMode == "exit" then
- resetRoundForExitOrCashout()
- confirmMode = nil
- saveBankBase()
- exitToMenuNow()
- return true
- elseif confirmMode == "cashout" then
- resetRoundForExitOrCashout()
- confirmMode = nil
- saveBankBase()
- cashOutCredits()
- drawAll()
- return true
- end
- end
- end
- end
- return false
- end
- local function handleTouch(x, y)
- if confirmMode then
- handleConfirmTouch(x, y)
- return
- end
- for _, box in ipairs(hitBoxes) do
- if inBox(x, y, box) then
- local id = box.id
- if id == "BETAMT:+1" then
- changeBetAmount(1)
- elseif id == "BETAMT:+5" then
- changeBetAmount(5)
- elseif id == "BETAMT:+10" then
- changeBetAmount(10)
- elseif id == "BETAMT:-1" then
- changeBetAmount(-1)
- elseif id == "BETAMT:-5" then
- changeBetAmount(-5)
- elseif id == "BETAMT:-10" then
- changeBetAmount(-10)
- elseif id == "BETAMT:RESET" then
- resetBetAmount()
- elseif id == "CLEAR_BET" then
- clearBet()
- elseif id == "DEAL" then
- startDeal()
- elseif id == "HIT" then
- playerHit()
- elseif id == "STAND" then
- playerStand()
- elseif id == "DOUBLE" then
- playerDouble()
- elseif id == "ACTION:CASHOUT" then
- requestCashOut()
- elseif id == "EXIT_MENU" then
- requestExit()
- end
- drawAll()
- return
- end
- end
- end
- --------------------------------------------------
- -- STARTUP
- --------------------------------------------------
- shuffleShoe()
- drawAll()
- while true do
- local e, side, x, y = os.pullEvent()
- if e == "monitor_touch" then
- handleTouch(x, y)
- elseif e == "peripheral" or e == "peripheral_detach" then
- drawAll()
- end
- end
Add Comment
Please, Sign In to add comment