Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Slot Machine Program
- local modem = peripheral.find("modem")
- if not modem then error("No modem found. Please attach a wireless modem.") end
- local speaker = peripheral.find("speaker")
- if not speaker then error("No speaker found. Please attach a speaker.") end
- modem.open(1) -- Use channel 1 for communication with the server
- -- Simple encryption and decryption functions
- local function encrypt(text)
- local result = ""
- for i = 1, #text do
- result = result .. string.char((string.byte(text, i) + 5) % 256)
- end
- return result
- end
- local function decrypt(text)
- local result = ""
- for i = 1, #text do
- result = result .. string.char((string.byte(text, i) - 5) % 256)
- end
- return result
- end
- -- Function to send requests to the server
- local function sendRequest(request)
- modem.transmit(1, 1, request)
- local timer = os.startTimer(5)
- while true do
- local event, param1, _, _, message = os.pullEvent()
- if event == "modem_message" and type(message) == "table" then
- return message
- elseif event == "timer" and param1 == timer then
- return nil
- end
- end
- end
- -- Function to save admin credentials
- local function saveAdminCredentials(id, password)
- local file = fs.open(".admin_cred", "w")
- file.write(encrypt(id .. ":" .. password))
- file.close()
- end
- -- Function to load admin credentials
- local function loadAdminCredentials()
- if fs.exists(".admin_cred") then
- local file = fs.open(".admin_cred", "r")
- local content = decrypt(file.readAll())
- file.close()
- local id, password = content:match("(.+):(.+)")
- return id, password
- end
- return nil, nil
- end
- -- Admin login on boot
- local function adminLogin()
- term.clear()
- term.setCursorPos(1,1)
- print("Admin Setup")
- write("Enter admin ID: ")
- local adminId = read()
- write("Enter admin password: ")
- local adminPassword = read("*")
- local response = sendRequest({type = "login", studentId = adminId, password = adminPassword})
- if response and response.success then
- saveAdminCredentials(adminId, adminPassword)
- print("Admin credentials saved successfully.")
- sleep(2)
- return adminId, adminPassword
- else
- print("Admin login failed. Please restart the program and try again.")
- sleep(2)
- error("Admin login failed")
- end
- end
- -- Load or set up admin credentials
- local adminId, adminPassword = loadAdminCredentials()
- if not adminId or not adminPassword then
- adminId, adminPassword = adminLogin()
- end
- local function login()
- term.clear()
- term.setCursorPos(1,1)
- print("Slot Machine Login")
- write("Enter student ID: ")
- local studentId = read()
- write("Enter password: ")
- local password = read("*")
- local response = sendRequest({type = "login", studentId = studentId, password = password})
- if response and response.success then
- return studentId, password
- else
- print("Login failed. Please try again.")
- sleep(2)
- return nil, nil
- end
- end
- local function getBalance(studentId, password)
- local response = sendRequest({type = "get_balance", studentId = studentId, password = password})
- if response and response.type == "balance_response" then
- return tonumber(response.balance)
- else
- return nil
- end
- end
- local function updateBalance(studentId, password, action, amount)
- local response = sendRequest({type = "update_balance", studentId = studentId, password = password, action = action, amount = amount})
- if response and response.type == "balance_update_response" and response.success then
- return tonumber(response.result)
- else
- return nil
- end
- end
- local SPIN_COST = 3
- local machineProfit = 0
- local playerLosses = {}
- local LOSS_THRESHOLD = 10
- local HIGH_WIN_MULTIPLIER = 2.5
- local colorMeanings = {
- [colors.red] = 1,
- [colors.green] = 2,
- [colors.blue] = 3,
- [colors.yellow] = 4,
- [colors.magenta] = 5
- }
- local outcomes = {
- {name = "SUPER JACKPOT", win = 20, chance = 0.5},
- {name = "JACKPOT", win = 10, chance = 1},
- {name = "SUPER WIN", win = 6, chance = 3},
- {name = "BIG WIN", win = 5, chance = 5},
- {name = "SMALL WIN", win = 4, chance = 10},
- {name = "COMEBACK", win = 3, chance = 20},
- {name = "SMALL LOSS", win = 2, chance = 25},
- {name = "UNLUCKY", win = 1, chance = 20},
- {name = "VERY UNLUCKY", win = 0, chance = 15.5}
- }
- local function getAdjustedOutcomes(studentId)
- local playerLoss = playerLosses[studentId] or 0
- if playerLoss >= LOSS_THRESHOLD then
- local adjustedOutcomes = {}
- local adjustmentFactor = math.min(playerLoss / LOSS_THRESHOLD, HIGH_WIN_MULTIPLIER)
- for _, outcome in ipairs(outcomes) do
- local adjustedChance = outcome.chance * (outcome.win > SPIN_COST and adjustmentFactor or (1 / adjustmentFactor))
- table.insert(adjustedOutcomes, {name = outcome.name, win = outcome.win, chance = adjustedChance})
- end
- return adjustedOutcomes
- end
- return outcomes
- end
- local function getOutcome(studentId)
- local adjustedOutcomes = getAdjustedOutcomes(studentId)
- local rand = math.random() * 100
- local cumulativeChance = 0
- for _, outcome in ipairs(adjustedOutcomes) do
- cumulativeChance = cumulativeChance + outcome.chance
- if rand <= cumulativeChance then
- return outcome
- end
- end
- return adjustedOutcomes[#adjustedOutcomes] -- Fallback to last outcome
- end
- local function spinWheel()
- local colors = {colors.red, colors.green, colors.blue, colors.yellow, colors.magenta}
- local wheel = {}
- local primaryColor = colors[math.random(1, #colors)]
- for i = 1, 3 do
- if math.random() < 0.4 then -- 40% chance of matching the primary color
- wheel[i] = primaryColor
- else
- wheel[i] = colors[math.random(1, #colors)]
- end
- end
- return wheel
- end
- local function checkWin(wheels)
- local middleRow = {wheels[1][2], wheels[2][2], wheels[3][2]}
- local uniqueColors = {}
- local totalValue = 0
- for _, color in ipairs(middleRow) do
- uniqueColors[color] = true
- totalValue = totalValue + colorMeanings[color]
- end
- local uniqueCount = 0
- for _ in pairs(uniqueColors) do uniqueCount = uniqueCount + 1 end
- if uniqueCount == 1 then
- return 8 -- Three of a kind
- elseif uniqueCount == 2 then
- return 5 -- Two of a kind
- else
- return math.min(math.max(totalValue - 5, 0), 4) -- Based on total value
- end
- end
- local function drawSlotMachine(wheels, balance, result)
- local w, h = term.getSize()
- term.clear()
- term.setCursorPos(1,1)
- print("Slot Machine")
- print("Balance: " .. balance .. " diamonds")
- -- Draw the slot machine frame
- local frameWidth = 21
- local frameHeight = 9
- local startX = math.floor((w - frameWidth) / 2)
- local startY = math.floor((h - frameHeight) / 2) - 2
- for y = startY, startY + frameHeight - 1 do
- term.setCursorPos(startX, y)
- if y == startY or y == startY + frameHeight - 1 then
- term.write(string.rep("-", frameWidth))
- else
- term.write("|" .. string.rep(" ", frameWidth - 2) .. "|")
- end
- end
- -- Draw the wheels
- for i = 1, 3 do
- for j = 1, 3 do
- term.setCursorPos(startX + 1 + (i - 1) * 7, startY + 2 + j)
- term.setBackgroundColor(wheels[i][j])
- term.write(" ")
- term.setBackgroundColor(colors.black)
- end
- end
- -- Draw result
- if result then
- term.setCursorPos(math.floor(w/2 - #result/2), startY + frameHeight + 1)
- term.write(result)
- end
- -- Draw color meanings
- term.setCursorPos(1, h-8)
- print("Color meanings:")
- for color, value in pairs(colorMeanings) do
- term.setBackgroundColor(color)
- term.write(" ")
- term.setBackgroundColor(colors.black)
- term.write(" - " .. value)
- print()
- end
- term.setBackgroundColor(colors.black)
- term.setCursorPos(1, h-1)
- print("ENTER: spin (" .. SPIN_COST .. " diamonds)")
- print("Q: quit")
- end
- local function animateSpin(wheels, balance)
- local spinDuration = 5 -- Spin for 5 seconds
- local startTime = os.clock()
- local framerate = 30
- while os.clock() - startTime < spinDuration do
- local t = (os.clock() - startTime) / spinDuration
- local speed = 1 - t -- Start fast, end slow
- for i = 1, 3 do
- if math.random() < speed then
- wheels[i] = spinWheel()
- end
- end
- drawSlotMachine(wheels, balance)
- speaker.playSound("minecraft:block.note_block.hat", 1, 1 + speed)
- sleep(0.05 + (t * 0.3)) -- Gradually increase sleep time for slowdown effect
- end
- end
- local function playSound(winAmount)
- if winAmount <= 2 then
- speaker.playSound("minecraft:entity.villager.no")
- elseif winAmount == 3 then
- speaker.playSound("minecraft:block.note_block.harp")
- elseif winAmount >= 4 and winAmount <= 6 then
- speaker.playSound("minecraft:entity.player.levelup")
- elseif winAmount == 10 then
- speaker.playSound("minecraft:ui.toast.challenge_complete")
- elseif winAmount == 20 then
- speaker.playSound("minecraft:entity.ender_dragon.death")
- end
- end
- local function playSlotMachine(studentId, password)
- local wheels = {{colors.red, colors.green, colors.blue}, {colors.red, colors.green, colors.blue}, {colors.red, colors.green, colors.blue}}
- while true do
- local balance = getBalance(studentId, password)
- drawSlotMachine(wheels, balance)
- local event, key = os.pullEvent("key")
- if key == keys.enter then
- if not balance or balance < SPIN_COST then
- print("Insufficient balance. Please add more diamonds.")
- sleep(2)
- else
- local newPlayerBalance = updateBalance(studentId, password, "withdraw", SPIN_COST)
- if newPlayerBalance then
- local newAdminBalance = updateBalance(adminId, adminPassword, "deposit", SPIN_COST)
- if newAdminBalance then
- machineProfit = machineProfit + SPIN_COST
- playerLosses[studentId] = (playerLosses[studentId] or 0) + SPIN_COST
- animateSpin(wheels, newPlayerBalance)
- local outcome = getOutcome(studentId)
- local winAmount = outcome.win
- local adminBalance = getBalance(adminId, adminPassword)
- if winAmount > 0 and adminBalance >= winAmount then
- newPlayerBalance = updateBalance(studentId, password, "deposit", winAmount)
- if newPlayerBalance then
- newAdminBalance = updateBalance(adminId, adminPassword, "withdraw", winAmount)
- if newAdminBalance then
- machineProfit = machineProfit - winAmount
- playerLosses[studentId] = math.max(0, playerLosses[studentId] - winAmount)
- playSound(winAmount)
- print(outcome.name .. "! You won " .. winAmount .. " diamonds!")
- else
- print("Error updating admin balance. Please contact support.")
- end
- else
- print("Error updating player balance. Please contact support.")
- end
- elseif winAmount > 0 then
- print("Admin has insufficient funds for payout. Please contact support.")
- else
- playSound(winAmount)
- print(outcome.name .. "! You won " .. winAmount .. " diamonds.")
- end
- drawSlotMachine(wheels, newPlayerBalance, outcome.name .. " - " .. winAmount .. " diamonds")
- sleep(2)
- else
- print("Error updating admin balance. Please contact support.")
- updateBalance(studentId, password, "deposit", SPIN_COST) -- Refund the player
- end
- else
- print("Error updating player balance. Please try again.")
- end
- end
- elseif key == keys.q then
- break
- end
- end
- end
- local function showAdminStats()
- term.clear()
- term.setCursorPos(1,1)
- print("Admin Statistics")
- print("Overall Profit: " .. machineProfit .. " diamonds")
- print("Press any key to return")
- os.pullEvent("key")
- end
- -- Main program
- while true do
- term.clear()
- term.setCursorPos(1,1)
- print("Welcome to the Slot Machine")
- print("1. Login")
- print("2. Exit")
- local choice = read()
- if choice == "1" then
- local studentId, password = login()
- if studentId then
- if studentId == adminId then
- showAdminStats()
- else
- playSlotMachine(studentId, password)
- end
- end
- elseif choice == "2" then
- break
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment