MtnMCG

slot machine

Sep 3rd, 2024 (edited)
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.71 KB | None | 0 0
  1. -- Slot Machine Program
  2.  
  3. local modem = peripheral.find("modem")
  4. if not modem then error("No modem found. Please attach a wireless modem.") end
  5.  
  6. local speaker = peripheral.find("speaker")
  7. if not speaker then error("No speaker found. Please attach a speaker.") end
  8.  
  9. modem.open(1) -- Use channel 1 for communication with the server
  10.  
  11. -- Simple encryption and decryption functions
  12. local function encrypt(text)
  13. local result = ""
  14. for i = 1, #text do
  15. result = result .. string.char((string.byte(text, i) + 5) % 256)
  16. end
  17. return result
  18. end
  19.  
  20. local function decrypt(text)
  21. local result = ""
  22. for i = 1, #text do
  23. result = result .. string.char((string.byte(text, i) - 5) % 256)
  24. end
  25. return result
  26. end
  27.  
  28. -- Function to send requests to the server
  29. local function sendRequest(request)
  30. modem.transmit(1, 1, request)
  31. local timer = os.startTimer(5)
  32. while true do
  33. local event, param1, _, _, message = os.pullEvent()
  34. if event == "modem_message" and type(message) == "table" then
  35. return message
  36. elseif event == "timer" and param1 == timer then
  37. return nil
  38. end
  39. end
  40. end
  41.  
  42. -- Function to save admin credentials
  43. local function saveAdminCredentials(id, password)
  44. local file = fs.open(".admin_cred", "w")
  45. file.write(encrypt(id .. ":" .. password))
  46. file.close()
  47. end
  48.  
  49. -- Function to load admin credentials
  50. local function loadAdminCredentials()
  51. if fs.exists(".admin_cred") then
  52. local file = fs.open(".admin_cred", "r")
  53. local content = decrypt(file.readAll())
  54. file.close()
  55. local id, password = content:match("(.+):(.+)")
  56. return id, password
  57. end
  58. return nil, nil
  59. end
  60.  
  61. -- Admin login on boot
  62. local function adminLogin()
  63. term.clear()
  64. term.setCursorPos(1,1)
  65. print("Admin Setup")
  66. write("Enter admin ID: ")
  67. local adminId = read()
  68. write("Enter admin password: ")
  69. local adminPassword = read("*")
  70.  
  71. local response = sendRequest({type = "login", studentId = adminId, password = adminPassword})
  72. if response and response.success then
  73. saveAdminCredentials(adminId, adminPassword)
  74. print("Admin credentials saved successfully.")
  75. sleep(2)
  76. return adminId, adminPassword
  77. else
  78. print("Admin login failed. Please restart the program and try again.")
  79. sleep(2)
  80. error("Admin login failed")
  81. end
  82. end
  83.  
  84. -- Load or set up admin credentials
  85. local adminId, adminPassword = loadAdminCredentials()
  86. if not adminId or not adminPassword then
  87. adminId, adminPassword = adminLogin()
  88. end
  89.  
  90. local function login()
  91. term.clear()
  92. term.setCursorPos(1,1)
  93. print("Slot Machine Login")
  94. write("Enter student ID: ")
  95. local studentId = read()
  96. write("Enter password: ")
  97. local password = read("*")
  98.  
  99. local response = sendRequest({type = "login", studentId = studentId, password = password})
  100. if response and response.success then
  101. return studentId, password
  102. else
  103. print("Login failed. Please try again.")
  104. sleep(2)
  105. return nil, nil
  106. end
  107. end
  108.  
  109. local function getBalance(studentId, password)
  110. local response = sendRequest({type = "get_balance", studentId = studentId, password = password})
  111. if response and response.type == "balance_response" then
  112. return tonumber(response.balance)
  113. else
  114. return nil
  115. end
  116. end
  117.  
  118. local function updateBalance(studentId, password, action, amount)
  119. local response = sendRequest({type = "update_balance", studentId = studentId, password = password, action = action, amount = amount})
  120. if response and response.type == "balance_update_response" and response.success then
  121. return tonumber(response.result)
  122. else
  123. return nil
  124. end
  125. end
  126.  
  127. local SPIN_COST = 3
  128. local machineProfit = 0
  129. local playerLosses = {}
  130. local LOSS_THRESHOLD = 10
  131. local HIGH_WIN_MULTIPLIER = 2.5
  132.  
  133. local colorMeanings = {
  134. [colors.red] = 1,
  135. [colors.green] = 2,
  136. [colors.blue] = 3,
  137. [colors.yellow] = 4,
  138. [colors.magenta] = 5
  139. }
  140.  
  141. local outcomes = {
  142. {name = "SUPER JACKPOT", win = 20, chance = 0.5},
  143. {name = "JACKPOT", win = 10, chance = 1},
  144. {name = "SUPER WIN", win = 6, chance = 3},
  145. {name = "BIG WIN", win = 5, chance = 5},
  146. {name = "SMALL WIN", win = 4, chance = 10},
  147. {name = "COMEBACK", win = 3, chance = 20},
  148. {name = "SMALL LOSS", win = 2, chance = 25},
  149. {name = "UNLUCKY", win = 1, chance = 20},
  150. {name = "VERY UNLUCKY", win = 0, chance = 15.5}
  151. }
  152.  
  153. local function getAdjustedOutcomes(studentId)
  154. local playerLoss = playerLosses[studentId] or 0
  155. if playerLoss >= LOSS_THRESHOLD then
  156. local adjustedOutcomes = {}
  157. local adjustmentFactor = math.min(playerLoss / LOSS_THRESHOLD, HIGH_WIN_MULTIPLIER)
  158. for _, outcome in ipairs(outcomes) do
  159. local adjustedChance = outcome.chance * (outcome.win > SPIN_COST and adjustmentFactor or (1 / adjustmentFactor))
  160. table.insert(adjustedOutcomes, {name = outcome.name, win = outcome.win, chance = adjustedChance})
  161. end
  162. return adjustedOutcomes
  163. end
  164. return outcomes
  165. end
  166.  
  167. local function getOutcome(studentId)
  168. local adjustedOutcomes = getAdjustedOutcomes(studentId)
  169. local rand = math.random() * 100
  170. local cumulativeChance = 0
  171. for _, outcome in ipairs(adjustedOutcomes) do
  172. cumulativeChance = cumulativeChance + outcome.chance
  173. if rand <= cumulativeChance then
  174. return outcome
  175. end
  176. end
  177. return adjustedOutcomes[#adjustedOutcomes] -- Fallback to last outcome
  178. end
  179.  
  180. local function spinWheel()
  181. local colors = {colors.red, colors.green, colors.blue, colors.yellow, colors.magenta}
  182. local wheel = {}
  183. local primaryColor = colors[math.random(1, #colors)]
  184. for i = 1, 3 do
  185. if math.random() < 0.4 then -- 40% chance of matching the primary color
  186. wheel[i] = primaryColor
  187. else
  188. wheel[i] = colors[math.random(1, #colors)]
  189. end
  190. end
  191. return wheel
  192. end
  193.  
  194. local function checkWin(wheels)
  195. local middleRow = {wheels[1][2], wheels[2][2], wheels[3][2]}
  196. local uniqueColors = {}
  197. local totalValue = 0
  198.  
  199. for _, color in ipairs(middleRow) do
  200. uniqueColors[color] = true
  201. totalValue = totalValue + colorMeanings[color]
  202. end
  203.  
  204. local uniqueCount = 0
  205. for _ in pairs(uniqueColors) do uniqueCount = uniqueCount + 1 end
  206.  
  207. if uniqueCount == 1 then
  208. return 8 -- Three of a kind
  209. elseif uniqueCount == 2 then
  210. return 5 -- Two of a kind
  211. else
  212. return math.min(math.max(totalValue - 5, 0), 4) -- Based on total value
  213. end
  214. end
  215.  
  216. local function drawSlotMachine(wheels, balance, result)
  217. local w, h = term.getSize()
  218. term.clear()
  219. term.setCursorPos(1,1)
  220. print("Slot Machine")
  221. print("Balance: " .. balance .. " diamonds")
  222.  
  223. -- Draw the slot machine frame
  224. local frameWidth = 21
  225. local frameHeight = 9
  226. local startX = math.floor((w - frameWidth) / 2)
  227. local startY = math.floor((h - frameHeight) / 2) - 2
  228.  
  229. for y = startY, startY + frameHeight - 1 do
  230. term.setCursorPos(startX, y)
  231. if y == startY or y == startY + frameHeight - 1 then
  232. term.write(string.rep("-", frameWidth))
  233. else
  234. term.write("|" .. string.rep(" ", frameWidth - 2) .. "|")
  235. end
  236. end
  237.  
  238. -- Draw the wheels
  239. for i = 1, 3 do
  240. for j = 1, 3 do
  241. term.setCursorPos(startX + 1 + (i - 1) * 7, startY + 2 + j)
  242. term.setBackgroundColor(wheels[i][j])
  243. term.write(" ")
  244. term.setBackgroundColor(colors.black)
  245. end
  246. end
  247.  
  248. -- Draw result
  249. if result then
  250. term.setCursorPos(math.floor(w/2 - #result/2), startY + frameHeight + 1)
  251. term.write(result)
  252. end
  253.  
  254. -- Draw color meanings
  255. term.setCursorPos(1, h-8)
  256. print("Color meanings:")
  257. for color, value in pairs(colorMeanings) do
  258. term.setBackgroundColor(color)
  259. term.write(" ")
  260. term.setBackgroundColor(colors.black)
  261. term.write(" - " .. value)
  262. print()
  263. end
  264. term.setBackgroundColor(colors.black)
  265.  
  266. term.setCursorPos(1, h-1)
  267. print("ENTER: spin (" .. SPIN_COST .. " diamonds)")
  268. print("Q: quit")
  269. end
  270.  
  271. local function animateSpin(wheels, balance)
  272. local spinDuration = 5 -- Spin for 5 seconds
  273. local startTime = os.clock()
  274. local framerate = 30
  275.  
  276. while os.clock() - startTime < spinDuration do
  277. local t = (os.clock() - startTime) / spinDuration
  278. local speed = 1 - t -- Start fast, end slow
  279.  
  280. for i = 1, 3 do
  281. if math.random() < speed then
  282. wheels[i] = spinWheel()
  283. end
  284. end
  285.  
  286. drawSlotMachine(wheels, balance)
  287. speaker.playSound("minecraft:block.note_block.hat", 1, 1 + speed)
  288. sleep(0.05 + (t * 0.3)) -- Gradually increase sleep time for slowdown effect
  289. end
  290. end
  291.  
  292. local function playSound(winAmount)
  293. if winAmount <= 2 then
  294. speaker.playSound("minecraft:entity.villager.no")
  295. elseif winAmount == 3 then
  296. speaker.playSound("minecraft:block.note_block.harp")
  297. elseif winAmount >= 4 and winAmount <= 6 then
  298. speaker.playSound("minecraft:entity.player.levelup")
  299. elseif winAmount == 10 then
  300. speaker.playSound("minecraft:ui.toast.challenge_complete")
  301. elseif winAmount == 20 then
  302. speaker.playSound("minecraft:entity.ender_dragon.death")
  303. end
  304. end
  305.  
  306. local function playSlotMachine(studentId, password)
  307. local wheels = {{colors.red, colors.green, colors.blue}, {colors.red, colors.green, colors.blue}, {colors.red, colors.green, colors.blue}}
  308.  
  309. while true do
  310. local balance = getBalance(studentId, password)
  311. drawSlotMachine(wheels, balance)
  312. local event, key = os.pullEvent("key")
  313. if key == keys.enter then
  314. if not balance or balance < SPIN_COST then
  315. print("Insufficient balance. Please add more diamonds.")
  316. sleep(2)
  317. else
  318. local newPlayerBalance = updateBalance(studentId, password, "withdraw", SPIN_COST)
  319. if newPlayerBalance then
  320. local newAdminBalance = updateBalance(adminId, adminPassword, "deposit", SPIN_COST)
  321. if newAdminBalance then
  322. machineProfit = machineProfit + SPIN_COST
  323. playerLosses[studentId] = (playerLosses[studentId] or 0) + SPIN_COST
  324.  
  325. animateSpin(wheels, newPlayerBalance)
  326.  
  327. local outcome = getOutcome(studentId)
  328. local winAmount = outcome.win
  329.  
  330. local adminBalance = getBalance(adminId, adminPassword)
  331. if winAmount > 0 and adminBalance >= winAmount then
  332. newPlayerBalance = updateBalance(studentId, password, "deposit", winAmount)
  333. if newPlayerBalance then
  334. newAdminBalance = updateBalance(adminId, adminPassword, "withdraw", winAmount)
  335. if newAdminBalance then
  336. machineProfit = machineProfit - winAmount
  337. playerLosses[studentId] = math.max(0, playerLosses[studentId] - winAmount)
  338. playSound(winAmount)
  339. print(outcome.name .. "! You won " .. winAmount .. " diamonds!")
  340. else
  341. print("Error updating admin balance. Please contact support.")
  342. end
  343. else
  344. print("Error updating player balance. Please contact support.")
  345. end
  346. elseif winAmount > 0 then
  347. print("Admin has insufficient funds for payout. Please contact support.")
  348. else
  349. playSound(winAmount)
  350. print(outcome.name .. "! You won " .. winAmount .. " diamonds.")
  351. end
  352.  
  353. drawSlotMachine(wheels, newPlayerBalance, outcome.name .. " - " .. winAmount .. " diamonds")
  354. sleep(2)
  355. else
  356. print("Error updating admin balance. Please contact support.")
  357. updateBalance(studentId, password, "deposit", SPIN_COST) -- Refund the player
  358. end
  359. else
  360. print("Error updating player balance. Please try again.")
  361. end
  362. end
  363. elseif key == keys.q then
  364. break
  365. end
  366. end
  367. end
  368.  
  369. local function showAdminStats()
  370. term.clear()
  371. term.setCursorPos(1,1)
  372. print("Admin Statistics")
  373. print("Overall Profit: " .. machineProfit .. " diamonds")
  374. print("Press any key to return")
  375. os.pullEvent("key")
  376. end
  377.  
  378. -- Main program
  379. while true do
  380. term.clear()
  381. term.setCursorPos(1,1)
  382. print("Welcome to the Slot Machine")
  383. print("1. Login")
  384. print("2. Exit")
  385. local choice = read()
  386. if choice == "1" then
  387. local studentId, password = login()
  388. if studentId then
  389. if studentId == adminId then
  390. showAdminStats()
  391. else
  392. playSlotMachine(studentId, password)
  393. end
  394. end
  395. elseif choice == "2" then
  396. break
  397. end
  398. end
Advertisement
Add Comment
Please, Sign In to add comment