Drum_Stick

slot_machine

Nov 10th, 2025
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.91 KB | Gaming | 0 0
  1. sleep(2)
  2.  
  3. -- Peripheral Setup / Make sure to adjust your peripheral names
  4. local monitor = peripheral.wrap("monitor_29") -- Main game monitor
  5. local actionMonitor = peripheral.wrap("monitor_27") -- Play/Exit monitor
  6. local bidMonitor = peripheral.wrap("monitor_28") -- Higher/Lower monitor
  7. local playerDetector = peripheral.find("playerDetector") -- Player Detector
  8. local speaker = peripheral.wrap("left") -- Speaker for sounds
  9.  
  10. -- API URL
  11. local API_URL = "http://<API_IP>:3000/balance/"
  12.  
  13. -- Constants
  14. local spinDelays = {1, 1.5, 2} -- Sequential spin delays
  15. local WIN_DELAY = 2
  16. local BET_INCREMENT = 20
  17. local MAX_BET = 400
  18. local MIN_BET = 20
  19.  
  20. -- Mob Faces
  21. local mobFaces = {
  22.     Pig = {
  23.         {colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink},
  24.         {colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink},
  25.         {colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink},
  26.         {colors.black, colors.white, colors.pink, colors.pink, colors.pink, colors.pink, colors.white, colors.black},
  27.         {colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink},
  28.         {colors.pink, colors.pink, colors.magenta, colors.pink, colors.pink, colors.magenta, colors.pink, colors.pink},
  29.         {colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink},
  30.         {colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink, colors.pink}
  31.     },
  32.     Creeper = {
  33.         {colors.green, colors.green, colors.green, colors.green, colors.green, colors.green, colors.green, colors.green},
  34.         {colors.green, colors.green, colors.green, colors.green, colors.green, colors.green, colors.green, colors.green},
  35.         {colors.green, colors.black, colors.black, colors.green, colors.green, colors.black, colors.black, colors.green},
  36.         {colors.green, colors.black, colors.black, colors.green, colors.green, colors.black, colors.black, colors.green},
  37.         {colors.green, colors.green, colors.green, colors.black, colors.black, colors.green, colors.green, colors.green},
  38.         {colors.green, colors.green, colors.black, colors.black, colors.black, colors.black, colors.green, colors.green},
  39.         {colors.green, colors.green, colors.black, colors.black, colors.black, colors.black, colors.green, colors.green},
  40.         {colors.green, colors.green, colors.black, colors.black, colors.black, colors.black, colors.green, colors.green}
  41.     },
  42.     Steve = {
  43.         {colors.brown, colors.brown, colors.brown, colors.brown, colors.brown, colors.brown, colors.brown, colors.brown},
  44.         {colors.brown, colors.brown, colors.brown, colors.brown, colors.brown, colors.brown, colors.brown, colors.brown},
  45.         {colors.brown, colors.orange, colors.orange, colors.orange, colors.orange, colors.orange, colors.orange, colors.brown},
  46.         {colors.orange, colors.orange, colors.orange, colors.orange, colors.orange, colors.orange, colors.orange, colors.orange},
  47.         {colors.orange, colors.white, colors.blue, colors.orange, colors.orange, colors.blue, colors.white, colors.orange},
  48.         {colors.orange, colors.orange, colors.orange, colors.brown, colors.brown, colors.orange, colors.orange, colors.orange},
  49.         {colors.orange, colors.orange, colors.brown, colors.pink, colors.pink, colors.brown, colors.orange, colors.orange},
  50.         {colors.orange, colors.orange, colors.brown, colors.brown, colors.brown, colors.brown, colors.orange, colors.orange}
  51.     },
  52.     Skeleton = {
  53.         {colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white},
  54.         {colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white},
  55.         {colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white},
  56.         {colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white},
  57.         {colors.white, colors.gray, colors.gray, colors.white, colors.white, colors.gray, colors.gray, colors.white},
  58.         {colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white},
  59.         {colors.white, colors.gray, colors.gray, colors.gray, colors.gray, colors.gray, colors.gray, colors.white},
  60.         {colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white, colors.white}
  61.     },
  62.     Zombie = {
  63.         {colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime},
  64.         {colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime},
  65.         {colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime},
  66.         {colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime},
  67.         {colors.lime, colors.black, colors.black, colors.lime, colors.lime, colors.black, colors.black, colors.lime},
  68.         {colors.lime, colors.lime, colors.lime, colors.green, colors.green, colors.lime, colors.lime, colors.lime},
  69.         {colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime},
  70.         {colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime, colors.lime}
  71.     },
  72.     Enderman = {
  73.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black},
  74.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black},
  75.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black},
  76.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black},
  77.         {colors.magenta, colors.purple, colors.magenta, colors.black, colors.black, colors.magenta, colors.purple, colors.magenta},
  78.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black},
  79.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black},
  80.         {colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black, colors.black}
  81.     }
  82. }
  83.  
  84. -- Split Monitor Rendering
  85. local function splitMonitor(monitor, leftText, rightText)
  86.     local width, height = monitor.getSize()
  87.     local midX = math.floor(width / 2)
  88.  
  89.     monitor.clear()
  90.  
  91.     for y = 1, height do
  92.         monitor.setCursorPos(midX, y)
  93.         monitor.write("|")
  94.     end
  95.  
  96.     monitor.setCursorPos(2, math.floor(height / 2)) -- Left side
  97.     monitor.write(leftText)
  98.     monitor.setCursorPos(midX + 2, math.floor(height / 2)) -- Right side
  99.     monitor.write(rightText)
  100. end
  101.  
  102. local function waitForMonitorClick(gameStarted)
  103.     while true do
  104.         local event, side, x, y = os.pullEvent("monitor_touch")
  105.  
  106.         if side == peripheral.getName(actionMonitor) then
  107.             local width, height = actionMonitor.getSize()
  108.             local midX = math.floor(width / 2)
  109.             if x <= midX then
  110.                 return gameStarted and "quit" or "exit"
  111.             else
  112.                 return gameStarted and "spin" or "play"
  113.             end
  114.  
  115.         elseif side == peripheral.getName(bidMonitor) then
  116.             local width, height = bidMonitor.getSize()
  117.             local midX = math.floor(width / 2)
  118.             if x <= midX then
  119.                 return "higherBid"
  120.             else
  121.                 return "lowerBid"
  122.             end
  123.         end
  124.     end
  125. end
  126.  
  127. local function renderMonitors(state)
  128.     monitor.clear()
  129.     if state == "welcome" then
  130.         splitMonitor(actionMonitor, "Exit", "Play")
  131.         bidMonitor.clear()
  132.     elseif state == "betting" then
  133.         splitMonitor(actionMonitor, "Exit", "Play")
  134.         splitMonitor(bidMonitor, "Higher", "Lower")
  135.     elseif state == "game" then
  136.         splitMonitor(actionMonitor, "Quit", "Spin")
  137.         splitMonitor(bidMonitor, "Higher", "Lower")
  138.     end
  139. end
  140.  
  141. -- Game state
  142. local currentPlayer = nil
  143. local currentBet = MIN_BET
  144.  
  145. -- Helper Functions
  146. local function getPlayerBalance(playerName)
  147.     local response = http.get(API_URL .. playerName)
  148.     if response then
  149.         local data = response.readAll()
  150.         response.close()
  151.         local result = textutils.unserializeJSON(data)
  152.         return result and result.coins or 0
  153.     end
  154.     return 0
  155. end
  156.  
  157. local function updatePlayerBalance(playerName, newBalance)
  158.     local body = textutils.serializeJSON({ coins = newBalance })
  159.     http.post(API_URL .. playerName, body, { ["Content-Type"] = "application/json" })
  160. end
  161.  
  162. local function weightedRandom()
  163.     local weights = {
  164.         -- YOU CAN CHANGE THE WEIGHTING OF EACH FACE HERE
  165.         {"Pig", 40}, {"Creeper", 25}, {"Skeleton", 15},
  166.         {"Zombie", 15}, {"Enderman", 5}, {"Steve", 30}
  167.     }
  168.     local total = 0
  169.     for _, w in pairs(weights) do total = total + w[2] end
  170.     local roll = math.random(total)
  171.     for _, face in pairs(weights) do
  172.         roll = roll - face[2]
  173.         if roll <= 0 then  
  174.             return face[1]
  175.         end
  176.     end
  177.     return nil
  178. end
  179.  
  180. local function drawFace(x, y, face)
  181.     local pixels = mobFaces[face]
  182.     if not pixels then
  183.         print("ERROR: Invalid face '" .. tostring(face) .. "'.")
  184.         return
  185.     end
  186.  
  187.     term.redirect(monitor)
  188.     for row = 1, #pixels do
  189.         for col = 1, #pixels[row] do
  190.             local color = pixels[row][col] or colors.black
  191.             monitor.setBackgroundColor(color)
  192.             monitor.setCursorPos(x + col - 1, y + row - 1)
  193.             write(" ")
  194.         end
  195.     end
  196.     monitor.setBackgroundColor(colors.black)
  197. end
  198.  
  199.  
  200. local function spinReels()
  201.     local reels = {"", "", ""} -- Initialize reels
  202.     local monitorWidth, monitorHeight = monitor.getSize()
  203.     local centerY = math.floor((monitorHeight - 8) / 2)
  204.     local reelXOffsets = {10, 22, 34}  
  205.  
  206.     term.redirect(monitor)
  207.  
  208.     for i = 1, 3 do
  209.         local startTime = os.clock()
  210.         while os.clock() - startTime < spinDelays[i] do
  211.             reels[i] = weightedRandom()
  212.             monitor.clear()
  213.  
  214.             -- Draw the current state of the reels
  215.             for j = 1, i do
  216.                 drawFace(reelXOffsets[j], centerY, reels[j])
  217.             end
  218.  
  219.             -- Display spinning feedback
  220.             monitor.setCursorPos(1, monitorHeight - 1)
  221.             monitor.clearLine()
  222.  
  223.             -- Play spinning sound
  224.             speaker.playSound("minecraft:block.note_block.hat")
  225.             sleep(0.1) -- Smooth animation
  226.         end
  227.  
  228.         speaker.playSound("minecraft:block.note_block.bass")
  229.         sleep(1)
  230.     end
  231.  
  232.     return reels
  233. end
  234.  
  235. -- YOU CAN CHANGE THE WINNINGS HERE
  236. local faceMultipliers = {
  237.     Pig = 1.5,      
  238.     Steve = 2.5,    
  239.     Zombie = 3,  
  240.     Skeleton = 3.5,
  241.     Creeper = 5,  
  242.     Enderman = 10
  243. }
  244.  
  245. local function calculateWinnings(reels)
  246.     local counts = {}
  247.     for _, face in ipairs(reels) do
  248.         counts[face] = (counts[face] or 0) + 1
  249.     end
  250.  
  251.     for face, count in pairs(counts) do
  252.         local multiplier = faceMultipliers[face] or 1
  253.         if count == 3 then
  254.             return currentBet * 1.5 * multiplier, face .. " Jackpot!"
  255.         end
  256.         if count == 2 then
  257.             return currentBet * 0.5 * multiplier, face .. " Pair!"
  258.         end
  259.     end
  260.  
  261.     return 0, "No win. Try again!"
  262. end
  263.  
  264. local function displayCenteredMenuText(lines)
  265.     local width, height = monitor.getSize()
  266.     local centerX = math.floor(width / 2)
  267.     local centerY = math.floor(height / 2)
  268.  
  269.     monitor.setBackgroundColor(colors.black)
  270.     monitor.clear()
  271.     monitor.setTextColor(colors.white)
  272.  
  273.     for i, line in ipairs(lines) do
  274.         monitor.setCursorPos(centerX - math.floor(string.len(line) / 2), centerY - #lines / 2 + i - 1)
  275.         monitor.write(line)
  276.     end
  277. end
  278.  
  279. local function renderMonitors(state)
  280.     if state == "welcome" then
  281.         actionMonitor.clear()
  282.         bidMonitor.clear()
  283.     elseif state == "betting" then
  284.         splitMonitor(actionMonitor, "Exit", "Play")
  285.         splitMonitor(bidMonitor, "Higher", "Lower")
  286.     elseif state == "game" then
  287.         splitMonitor(actionMonitor, "Exit", "Spin")
  288.         splitMonitor(bidMonitor, "Higher", "Lower")
  289.     end
  290. end
  291.  
  292. local function displayResults(reels, message, winnings)
  293.     local monitorWidth, monitorHeight = monitor.getSize()
  294.     local centerY = math.floor((monitorHeight - 8) / 2)
  295.     local reelXOffsets = {10, 22, 34}
  296.  
  297.     term.redirect(monitor)
  298.  
  299.     for i = 1, 3 do
  300.         drawFace(reelXOffsets[i], centerY, reels[i])
  301.     end
  302.  
  303.     local resultY = centerY + 10
  304.     local centerX = math.floor((monitorWidth - #message) / 2)
  305.  
  306.     monitor.setCursorPos(centerX, resultY)
  307.     monitor.setTextColor(colors.orange)
  308.     monitor.write(message)
  309.  
  310.     local winningsY = resultY + 2
  311.     monitor.setCursorPos(centerX, winningsY)
  312.     monitor.write("Winnings: " .. winnings .. " coins")
  313.  
  314.     monitor.setTextColor(colors.white)
  315. end
  316.  
  317. local function canPlayerPlay(playerName, betAmount)
  318.     local balance = getPlayerBalance(playerName)
  319.     if balance < betAmount then
  320.         return false, "Insufficient balance! You need at least " .. betAmount .. " coins to play."
  321.     end
  322.     return true
  323. end
  324.  
  325. -- Main Game Loop
  326. while true do
  327.     renderMonitors("welcome")
  328.     monitor.clear()
  329.     monitor.setCursorPos(1, 1)
  330.     monitor.clear()
  331.     displayCenteredMenuText({
  332.         "Welcome to the Slot Machine!",
  333.         "Right-click the Green Block to login."
  334.     })
  335.  
  336.     local _, username = os.pullEvent("playerClick")
  337.     currentPlayer = username
  338.     local playerBalance = getPlayerBalance(username)
  339.  
  340.     renderMonitors("betting")
  341.     speaker.playSound("minecraft:block.note_block.bell")
  342.  
  343.     while true do
  344.         monitor.clear()
  345.         monitor.setCursorPos(1, 1)
  346.  
  347.         monitor.clear()
  348.         displayCenteredMenuText({
  349.             "Player: " .. currentPlayer,
  350.             "Balance: " .. playerBalance .. " coins",
  351.             "Bet: " .. currentBet .. " coins",
  352.             "Adjust bet with Higher/Lower.",
  353.             "",
  354.             "Press Play to spin or Exit to quit."
  355.         })
  356.  
  357.         local action = waitForMonitorClick(false)
  358.         if action == "higherBid" then
  359.             currentBet = math.min(currentBet + BET_INCREMENT, MAX_BET)
  360.             speaker.playSound("minecraft:block.note_block.snare")
  361.         elseif action == "lowerBid" then
  362.             currentBet = math.max(currentBet - BET_INCREMENT, MIN_BET)
  363.             speaker.playSound("minecraft:block.note_block.snare")
  364.         elseif action == "play" then
  365.  
  366.             local canPlay, errorMessage = canPlayerPlay(currentPlayer, currentBet)
  367.             if not canPlay then
  368.  
  369.                 displayCenteredMenuText({
  370.                     errorMessage,
  371.                     "",
  372.                     "Adjust your bet or exit to the main menu."
  373.                 })
  374.                 speaker.playSound("minecraft:block.note_block.bass")
  375.                 sleep(2)
  376.             else
  377.  
  378.                 renderMonitors("game")
  379.                 updatePlayerBalance(currentPlayer, getPlayerBalance(currentPlayer) - currentBet)
  380.                 local reels = spinReels()
  381.                 local winnings, message = calculateWinnings(reels)
  382.                 displayResults(reels, message, winnings)
  383.                 playerBalance = getPlayerBalance(currentPlayer) + winnings
  384.                 updatePlayerBalance(currentPlayer, playerBalance)
  385.                 sleep(WIN_DELAY)
  386.                 renderMonitors("betting")
  387.             end
  388.        
  389.         elseif action == "exit" then
  390.             speaker.playSound("minecraft:block.note_block.bass")
  391.             break
  392.         end
  393.     end
  394. end
Advertisement
Add Comment
Please, Sign In to add comment