Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Casino Slots Game
- -- Integrates with player card system
- -- Initialize peripherals
- local monitor = peripheral.find("monitor")
- local oldTerm = term.current()
- if monitor then
- monitor.setTextScale(0.5)
- monitor.clear()
- end
- -- Find disk drive
- local function findDiskDrive()
- local sides = {"top", "bottom", "left", "right", "front", "back"}
- for _, side in ipairs(sides) do
- if peripheral.getType(side) == "drive" then
- return side
- end
- end
- return nil
- end
- local diskDrive = findDiskDrive()
- -- Colors
- local COLORS = {
- background = colors.black,
- header = colors.blue,
- headerText = colors.white,
- primary = colors.white,
- highlight = colors.yellow,
- success = colors.lime,
- error = colors.orange, -- Changed from red to orange for better visibility
- balance = colors.lime,
- balanceNegative = colors.orange, -- Changed from red to orange
- button = colors.lightGray,
- buttonText = colors.black,
- buttonHighlight = colors.yellow,
- slotBorder = colors.gray,
- slotBackground = colors.black,
- cherry = colors.pink, -- Changed from red to pink
- lemon = colors.yellow,
- orange = colors.orange,
- plum = colors.purple,
- seven = colors.lightBlue,
- bar = colors.white,
- exitButton = colors.gray,
- exitText = colors.white
- }
- -- Slot symbols
- local SYMBOLS = {
- {name = "Cherry", color = COLORS.cherry, char = "O", value = 2},
- {name = "Lemon", color = COLORS.lemon, char = "O", value = 3},
- {name = "Orange", color = COLORS.orange, char = "O", value = 4},
- {name = "Plum", color = COLORS.plum, char = "O", value = 5},
- {name = "Seven", color = COLORS.seven, char = "7", value = 7},
- {name = "BAR", color = COLORS.bar, char = "=", value = 10}
- }
- -- Helper functions
- local function centerText(text, y, color, targetTerm)
- targetTerm = targetTerm or term.current()
- local w, h = targetTerm.getSize()
- local x = math.floor((w - #text) / 2) + 1
- if y then
- targetTerm.setCursorPos(x, y)
- if color then
- targetTerm.setTextColor(color)
- end
- targetTerm.write(text)
- end
- return x
- end
- local function drawBox(x, y, width, height, bgColor, fgColor, targetTerm)
- targetTerm = targetTerm or term.current()
- targetTerm.setBackgroundColor(bgColor or COLORS.button)
- targetTerm.setTextColor(fgColor or COLORS.buttonText)
- for i = 1, height do
- targetTerm.setCursorPos(x, y + i - 1)
- targetTerm.write(string.rep(" ", width))
- end
- end
- local function drawButton(x, y, text, bgColor, fgColor, targetTerm)
- targetTerm = targetTerm or term.current()
- local padding = 2
- local width = #text + (padding * 2)
- drawBox(x, y, width, 3, bgColor, fgColor, targetTerm)
- targetTerm.setCursorPos(x + padding, y + 1)
- targetTerm.write(text)
- return {
- x1 = x,
- y1 = y,
- x2 = x + width,
- y2 = y + 2,
- text = text
- }
- end
- local function isInside(x, y, button)
- return x >= button.x1 and x <= button.x2 and
- y >= button.y1 and y <= button.y2
- end
- local function drawHeader(targetTerm)
- targetTerm = targetTerm or term.current()
- local w, h = targetTerm.getSize()
- -- Header background
- targetTerm.setBackgroundColor(COLORS.header)
- targetTerm.setTextColor(COLORS.headerText)
- for i = 1, 3 do
- targetTerm.setCursorPos(1, i)
- targetTerm.write(string.rep(" ", w))
- end
- -- Game title
- local title = "LUCKY SLOTS"
- centerText(title, 2, COLORS.headerText, targetTerm)
- -- Reset for main content
- targetTerm.setBackgroundColor(COLORS.background)
- end
- local function formatCredits(amount)
- local formatted = tostring(amount)
- local pos = #formatted - 3
- while pos > 0 do
- formatted = formatted:sub(1, pos) .. "," .. formatted:sub(pos + 1)
- pos = pos - 3
- end
- return formatted
- end
- -- Show intro screen
- local function showIntroScreen()
- if monitor then term.redirect(monitor) end
- local w, h = term.getSize()
- term.clear()
- drawHeader()
- term.setTextColor(COLORS.highlight)
- centerText("WELCOME TO", 5)
- centerText("LUCKY SLOTS", 6)
- term.setTextColor(COLORS.primary)
- centerText("Insert your player card", 9)
- centerText("to begin playing!", 10)
- -- Draw slot machine graphic
- local slotWidth = 26
- local slotX = math.floor((w - slotWidth) / 2)
- local slotY = 12
- -- Machine body
- drawBox(slotX, slotY, slotWidth, 8, COLORS.slotBorder)
- drawBox(slotX + 2, slotY + 1, slotWidth - 4, 3, COLORS.slotBackground)
- -- Reels
- local reelWidth = 5
- local reelPadding = 2
- local reelX = slotX + 3
- for i = 1, 3 do
- drawBox(reelX, slotY + 1, reelWidth, 3, COLORS.slotBackground)
- -- Draw random symbol
- local symbol = SYMBOLS[math.random(1, #SYMBOLS)]
- term.setTextColor(symbol.color)
- term.setCursorPos(reelX + 2, slotY + 2)
- term.write(symbol.char)
- reelX = reelX + reelWidth + reelPadding
- end
- -- Lever
- term.setBackgroundColor(COLORS.background)
- term.setTextColor(COLORS.slotBorder)
- term.setCursorPos(slotX + slotWidth + 1, slotY + 1)
- term.write("|")
- term.setCursorPos(slotX + slotWidth + 1, slotY + 2)
- term.write("O")
- term.setCursorPos(slotX + slotWidth + 1, slotY + 3)
- term.write("|")
- -- Payout info
- term.setTextColor(COLORS.highlight)
- centerText("PAYOUTS:", slotY + 10)
- term.setTextColor(COLORS.primary)
- local payoutY = slotY + 11
- for i, symbol in ipairs(SYMBOLS) do
- term.setTextColor(symbol.color)
- term.setCursorPos(slotX + 2, payoutY + i - 1)
- term.write(symbol.char .. " " .. symbol.name)
- term.setTextColor(COLORS.primary)
- term.setCursorPos(slotX + 15, payoutY + i - 1)
- term.write("x" .. symbol.value)
- end
- -- Wait for disk to be inserted
- while not disk.isPresent(diskDrive) do
- sleep(0.5)
- -- Check if disk drive is still connected
- if not peripheral.isPresent(diskDrive) then
- diskDrive = findDiskDrive()
- if not diskDrive then
- term.setTextColor(COLORS.error)
- centerText("Disk drive disconnected!", h - 2)
- sleep(1)
- return showIntroScreen() -- Restart the process
- end
- end
- end
- term.setTextColor(COLORS.success)
- centerText("Card detected!", h - 2)
- sleep(1)
- return diskDrive
- end
- -- Load player data from card
- local function loadPlayerData(drive)
- local path = disk.getMountPath(drive) .. "/player.dat"
- if not fs.exists(path) then
- if monitor then term.redirect(monitor) end
- local w, h = term.getSize()
- term.clear()
- drawHeader()
- term.setTextColor(COLORS.error)
- centerText("Invalid player card!", 8)
- centerText("Please visit the Casino PC", 10)
- centerText("to create a new account", 11)
- -- Wait for disk to be removed
- while disk.isPresent(drive) do
- sleep(0.5)
- end
- return nil
- end
- local file = fs.open(path, "r")
- local data = textutils.unserialize(file.readAll())
- file.close()
- return data
- end
- -- Save player data to card
- local function savePlayerData(drive, playerData)
- local path = disk.getMountPath(drive) .. "/player.dat"
- -- Update last played
- playerData.lastPlayed = os.day()
- -- Save updated data
- local file = fs.open(path, "w")
- file.write(textutils.serialize(playerData))
- file.close()
- end
- -- Get bet amount from player
- local function getBetAmount(playerData)
- if monitor then term.redirect(monitor) end
- local w, h = term.getSize()
- term.clear()
- drawHeader()
- term.setTextColor(COLORS.primary)
- centerText("Welcome, " .. playerData.name, 5)
- term.setTextColor(COLORS.balance)
- centerText("Balance: " .. formatCredits(playerData.credits), 7)
- term.setTextColor(COLORS.highlight)
- centerText("Select your bet amount:", 10)
- -- Draw bet buttons in a more organized grid
- local betButtons = {}
- local betAmounts = {100, 500, 1000, 5000, 10000}
- -- Calculate button positions for a centered grid
- local buttonWidth = 10
- local buttonSpacing = 3
- local totalWidth = (buttonWidth * 3) + (buttonSpacing * 2)
- local startX = math.floor((w - totalWidth) / 2)
- -- First row (3 buttons)
- for i = 1, 3 do
- local buttonX = startX + (i-1) * (buttonWidth + buttonSpacing)
- local button = drawButton(buttonX, 12, tostring(betAmounts[i]), COLORS.button, COLORS.buttonText)
- button.amount = betAmounts[i]
- table.insert(betButtons, button)
- end
- -- Second row (2 buttons)
- startX = math.floor((w - ((buttonWidth * 2) + buttonSpacing)) / 2)
- for i = 4, 5 do
- local buttonX = startX + (i-4) * (buttonWidth + buttonSpacing)
- local button = drawButton(buttonX, 16, tostring(betAmounts[i]), COLORS.button, COLORS.buttonText)
- button.amount = betAmounts[i]
- table.insert(betButtons, button)
- end
- -- Custom bet button (centered)
- local customButton = drawButton(math.floor(w/2) - 8, 20, "Custom Bet", COLORS.button, COLORS.buttonText)
- -- Back button (bottom left)
- local backButton = drawButton(5, h - 4, "Back", COLORS.exitButton, COLORS.exitText)
- while true do
- local event, button, x, y = os.pullEvent("monitor_touch")
- -- Check if card is still present
- if not disk.isPresent(diskDrive) then
- return nil
- end
- -- Check bet buttons
- for _, btn in ipairs(betButtons) do
- if isInside(x, y, btn) then
- if btn.amount <= playerData.credits then
- return btn.amount
- else
- -- Show insufficient funds message
- term.setTextColor(COLORS.error)
- centerText("Insufficient funds!", h - 8)
- sleep(1.5)
- -- Clear error message
- term.setBackgroundColor(COLORS.background)
- term.setCursorPos(1, h - 8)
- term.write(string.rep(" ", w))
- end
- end
- end
- -- Check custom bet button
- if isInside(x, y, customButton) then
- -- Switch to computer terminal for input
- term.redirect(oldTerm)
- term.clear()
- term.setCursorPos(1, 1)
- term.setTextColor(colors.yellow)
- print("LUCKY SLOTS - CUSTOM BET")
- print("-----------------------")
- print("")
- term.setTextColor(colors.white)
- print("Player: " .. playerData.name)
- print("Balance: " .. formatCredits(playerData.credits))
- print("")
- print("Enter your bet amount:")
- local input = read()
- local betAmount = tonumber(input)
- -- Switch back to monitor
- if monitor then term.redirect(monitor) end
- if betAmount and betAmount > 0 and betAmount <= playerData.credits then
- return betAmount
- else
- -- Show invalid bet message
- term.setTextColor(COLORS.error)
- centerText("Invalid bet amount!", h - 8)
- sleep(1.5)
- -- Clear error message
- term.setBackgroundColor(COLORS.background)
- term.setCursorPos(1, h - 8)
- term.write(string.rep(" ", w))
- end
- end
- -- Check back button
- if isInside(x, y, backButton) then
- return 0 -- Signal to go back
- end
- end
- end
- -- Draw slot machine
- local function drawSlotMachine(reels)
- if monitor then term.redirect(monitor) end
- local w, h = term.getSize()
- -- Draw slot machine graphic
- local slotWidth = 26
- local slotX = math.floor((w - slotWidth) / 2)
- local slotY = 8
- -- Machine body
- drawBox(slotX, slotY, slotWidth, 8, COLORS.slotBorder)
- drawBox(slotX + 2, slotY + 1, slotWidth - 4, 3, COLORS.slotBackground)
- -- Reels
- local reelWidth = 5
- local reelPadding = 2
- local reelX = slotX + 3
- for i = 1, 3 do
- drawBox(reelX, slotY + 1, reelWidth, 3, COLORS.slotBackground)
- -- Draw symbol if provided
- if reels and reels[i] then
- local symbol = reels[i]
- term.setTextColor(symbol.color)
- term.setCursorPos(reelX + 2, slotY + 2)
- term.write(symbol.char)
- end
- reelX = reelX + reelWidth + reelPadding
- end
- -- Lever
- term.setBackgroundColor(COLORS.background)
- term.setTextColor(COLORS.slotBorder)
- term.setCursorPos(slotX + slotWidth + 1, slotY + 1)
- term.write("|")
- term.setCursorPos(slotX + slotWidth + 1, slotY + 2)
- term.write("O")
- term.setCursorPos(slotX + slotWidth + 1, slotY + 3)
- term.write("|")
- return {
- x = slotX,
- y = slotY,
- width = slotWidth,
- height = 8,
- reelX = slotX + 3,
- reelY = slotY + 2,
- reelWidth = reelWidth,
- reelPadding = reelPadding
- }
- end
- -- Spin the reels animation
- local function spinReels(slotMachine, spinTime)
- local spinStartTime = os.clock()
- local spinEndTime = spinStartTime + spinTime
- -- Spin animation
- while os.clock() < spinEndTime do
- -- Generate random symbols for each reel
- local currentReels = {}
- for i = 1, 3 do
- currentReels[i] = SYMBOLS[math.random(1, #SYMBOLS)]
- end
- -- Draw the current symbols
- local reelX = slotMachine.reelX
- for i = 1, 3 do
- local symbol = currentReels[i]
- term.setTextColor(symbol.color)
- term.setCursorPos(reelX + 2, slotMachine.reelY)
- term.write(symbol.char)
- reelX = reelX + slotMachine.reelWidth + slotMachine.reelPadding
- end
- -- Slow down the animation as it approaches the end
- local timeLeft = spinEndTime - os.clock()
- local delay = math.min(0.3, 0.05 + (0.3 * (1 - timeLeft / spinTime)))
- sleep(delay)
- end
- -- Generate final results
- local finalReels = {}
- for i = 1, 3 do
- finalReels[i] = SYMBOLS[math.random(1, #SYMBOLS)]
- end
- -- Draw the final symbols
- local reelX = slotMachine.reelX
- for i = 1, 3 do
- local symbol = finalReels[i]
- term.setTextColor(symbol.color)
- term.setCursorPos(reelX + 2, slotMachine.reelY)
- term.write(symbol.char)
- reelX = reelX + slotMachine.reelWidth + slotMachine.reelPadding
- end
- return finalReels
- end
- -- Calculate winnings based on the final reels
- local function calculateWinnings(reels, betAmount)
- -- Check if all symbols are the same
- local allSame = true
- local firstSymbol = reels[1]
- for i = 2, 3 do
- if reels[i].name ~= firstSymbol.name then
- allSame = false
- break
- end
- end
- if allSame then
- -- Jackpot! All three symbols match
- return betAmount * firstSymbol.value
- end
- -- Check for pairs
- for i = 1, 2 do
- for j = i + 1, 3 do
- if reels[i].name == reels[j].name then
- -- Pair found
- return math.floor(betAmount * (reels[i].value / 2))
- end
- end
- end
- -- No matches
- return 0
- end
- -- Play one round of slots
- local function playSlots(playerData, betAmount)
- if monitor then term.redirect(monitor) end
- local w, h = term.getSize()
- term.clear()
- drawHeader()
- -- Show player info in a nice box at the top
- local infoBoxY = 5
- local infoBoxHeight = 3
- -- Draw info box
- drawBox(5, infoBoxY, w - 10, infoBoxHeight, COLORS.header, COLORS.primary)
- -- Player name
- term.setTextColor(COLORS.primary)
- term.setCursorPos(8, infoBoxY + 1)
- term.write("Player: " .. playerData.name)
- -- Balance
- term.setTextColor(COLORS.balance)
- term.setCursorPos(w - 25, infoBoxY + 1)
- term.write("Balance: " .. formatCredits(playerData.credits))
- -- Draw bet amount in a highlighted box
- local betBoxWidth = 20
- local betBoxX = math.floor((w - betBoxWidth) / 2)
- drawBox(betBoxX, infoBoxY + infoBoxHeight + 2, betBoxWidth, 3, COLORS.background, COLORS.highlight)
- term.setTextColor(COLORS.highlight)
- centerText("Bet: " .. formatCredits(betAmount), infoBoxY + infoBoxHeight + 3)
- -- Draw the slot machine
- local slotMachine = drawSlotMachine()
- -- Draw spin button with a more attractive style
- local spinButtonWidth = 12
- local spinButtonX = math.floor((w - spinButtonWidth) / 2)
- local spinButtonY = slotMachine.y + slotMachine.height + 2
- drawBox(spinButtonX, spinButtonY, spinButtonWidth, 3, COLORS.highlight, COLORS.buttonText)
- term.setTextColor(COLORS.buttonText)
- term.setCursorPos(spinButtonX + 4, spinButtonY + 1)
- term.write("SPIN")
- local spinButton = {
- x1 = spinButtonX,
- y1 = spinButtonY,
- x2 = spinButtonX + spinButtonWidth,
- y2 = spinButtonY + 2
- }
- -- Wait for player to press spin
- while true do
- local event, button, x, y = os.pullEvent("monitor_touch")
- -- Check if card is still present
- if not disk.isPresent(diskDrive) then
- return nil
- end
- if isInside(x, y, spinButton) then
- break
- end
- end
- -- Deduct bet amount
- playerData.credits = playerData.credits - betAmount
- -- Animate lever pull
- term.setTextColor(COLORS.slotBorder)
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 1)
- term.write(" ")
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 2)
- term.write("|")
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 3)
- term.write("O")
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 4)
- term.write("|")
- sleep(0.3)
- -- Spin the reels
- local finalReels = spinReels(slotMachine, 3.0)
- -- Reset lever
- term.setTextColor(COLORS.slotBorder)
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 1)
- term.write("|")
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 2)
- term.write("O")
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 3)
- term.write("|")
- term.setCursorPos(slotMachine.x + slotMachine.width + 1, slotMachine.y + 4)
- term.write(" ")
- -- Calculate winnings
- local winnings = calculateWinnings(finalReels, betAmount)
- -- Update player credits
- playerData.credits = playerData.credits + winnings
- -- Record game in player history
- if not playerData.games then
- playerData.games = {}
- end
- table.insert(playerData.games, {
- game = "slots",
- bet = betAmount,
- winnings = winnings,
- time = os.day()
- })
- -- Display results in a nice box
- local resultBoxY = slotMachine.y + slotMachine.height + 6
- local resultBoxHeight = 4
- local resultBoxWidth = 20
- local resultBoxX = math.floor((w - resultBoxWidth) / 2)
- if winnings > 0 then
- -- Win message with fancy box
- drawBox(resultBoxX, resultBoxY, resultBoxWidth, resultBoxHeight, COLORS.success, COLORS.primary)
- term.setTextColor(COLORS.primary)
- centerText("YOU WIN!", resultBoxY + 1)
- centerText(formatCredits(winnings), resultBoxY + 2)
- else
- -- Lose message
- drawBox(resultBoxX, resultBoxY, resultBoxWidth, resultBoxHeight, COLORS.error, COLORS.primary)
- term.setTextColor(COLORS.primary)
- centerText("NO MATCH", resultBoxY + 1)
- centerText("Try Again!", resultBoxY + 2)
- end
- -- Update balance display
- term.setTextColor(COLORS.balance)
- term.setCursorPos(w - 25, infoBoxY + 1)
- term.write("Balance: " .. formatCredits(playerData.credits) .. " ")
- -- Draw buttons in a more organized way
- local buttonY = h - 5
- local playAgainButton = drawButton(10, buttonY, "Play Again", COLORS.button, COLORS.buttonText)
- local cashOutButton = drawButton(w - 20, buttonY, "Cash Out", COLORS.button, COLORS.buttonText)
- -- Wait for player decision
- while true do
- local event, button, x, y = os.pullEvent("monitor_touch")
- -- Check if card is still present
- if not disk.isPresent(diskDrive) then
- return nil
- end
- if isInside(x, y, playAgainButton) then
- return true -- Play again
- elseif isInside(x, y, cashOutButton) then
- return false -- Cash out
- end
- end
- end
- -- Main game loop
- while true do
- -- Show intro screen and wait for card
- local drive = showIntroScreen()
- -- Load player data
- local playerData = loadPlayerData(drive)
- -- If valid player data was loaded
- if playerData then
- local playing = true
- while playing and disk.isPresent(drive) do
- -- Get bet amount
- local betAmount = getBetAmount(playerData)
- -- Check if player wants to exit or card was removed
- if not betAmount then
- break
- elseif betAmount == 0 then
- -- Player pressed back, show intro screen
- break
- end
- -- Play a round of slots
- local playAgain = playSlots(playerData, betAmount)
- -- Save player data after each round
- savePlayerData(drive, playerData)
- -- Check if player wants to play again
- if not playAgain then
- playing = false
- end
- -- Check if player is out of credits
- if playerData.credits <= 0 then
- if monitor then term.redirect(monitor) end
- term.clear()
- drawHeader()
- -- Draw a nicer "out of credits" message
- local messageBoxY = 10
- local messageBoxHeight = 5
- local messageBoxWidth = 30
- local messageBoxX = math.floor((w - messageBoxWidth) / 2)
- drawBox(messageBoxX, messageBoxY, messageBoxWidth, messageBoxHeight, COLORS.error, COLORS.primary)
- term.setTextColor(COLORS.primary)
- centerText("OUT OF CREDITS!", messageBoxY + 1)
- centerText("Please visit the Casino PC", messageBoxY + 3)
- centerText("to add more credits", messageBoxY + 4)
- -- Draw exit button
- local exitButton = drawButton(math.floor(w/2) - 4, h - 5, "Exit", COLORS.exitButton, COLORS.exitText)
- -- Wait for exit button or card removal
- while disk.isPresent(drive) do
- local event, button, x, y = os.pullEvent()
- if event == "monitor_touch" and isInside(x, y, exitButton) then
- break
- end
- end
- playing = false
- end
- end
- end
- -- Wait for card to be removed before showing intro again
- while disk.isPresent(drive) do
- sleep(0.5)
- end
- end
Add Comment
Please, Sign In to add comment