Mr_Tuti

startup.lua

Jan 28th, 2021 (edited)
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.43 KB | None | 0 0
  1. local surface, monitor, width, height, screen, font, cardBg, cardBack, drive, buttons, deck, bigfont, lastBet, speaker, bouncingCards, logo
  2.  
  3. MAX_BET = 128
  4. MAINFRAME_ID = 5
  5.  
  6. math.round = function(x) return x + 0.5 - (x + 0.5) % 1 end
  7. function shuffle(tbl)
  8.   for i = #tbl, 2, -1 do
  9.     local j = math.random(i)
  10.     tbl[i], tbl[j] = tbl[j], tbl[i]
  11.   end
  12.   return tbl
  13. end
  14.  
  15. function setup()
  16.   surface = dofile("surface")
  17.   monitor = peripheral.wrap("monitor_2")
  18.     drive = peripheral.wrap("bottom")
  19.     rednet.open("right")
  20.     speaker = peripheral.find("speaker")
  21.   monitor.setTextScale(0.5)
  22.   term.redirect(monitor)
  23.   term.setPaletteColor(colors.lightGray, 0xc5c5c5)
  24.   term.setPaletteColor(colors.orange, 0xf15c5c)
  25.   term.setPaletteColor(colors.gray, 0x363636)
  26.   term.setPaletteColor(colors.green, 0x044906)
  27.     width, height = term.getSize()
  28.   screen = surface.create(width, height)
  29.   font = surface.loadFont(surface.load("font"))
  30.   bigfont = surface.loadFont(surface.load("gothic"))
  31.   cardBg = surface.load("card.nfp")
  32.     cardBack = surface.load("cardback.nfp")
  33.     logo = surface.load("logo.nfp")
  34.   buttons = {}
  35.   deck = {}
  36.   local i = 1
  37.   for _,suit in ipairs({"heart", "diamond", "club", "spade"}) do
  38.     for _,num in ipairs({"A", "T", "J", "Q", "K"}) do
  39.       deck[i] = num..suit;
  40.       i = i + 1
  41.     end
  42.     for num = 2, 9, 1 do
  43.       deck[i] = tostring(num)..suit;
  44.       i = i + 1
  45.     end
  46.     end
  47.     shuffle(deck)
  48.     bouncingCards = {}
  49.    
  50.     for i=1,4 do
  51.         bouncingCards[i] = {
  52.             x=-math.floor(math.random() * screen.width * 2),
  53.             mirror=math.random() > 0.5,
  54.             card=deck[i]
  55.         }
  56.     end
  57. end
  58.  
  59. function drawCard(cardID)
  60.     local number = cardID:sub(1, 1)
  61.     if number == "T" then
  62.         number = "10"
  63.     end
  64.     local suit = cardID:sub(2, -1)
  65.     local card = surface.create(12, 15)
  66.   suit = surface.load(suit..".nfp")
  67.   card:drawSurface(cardBg, 0, 0)
  68.   card:drawSurface(suit, 5, 2)
  69.   card:drawText(number, font, 2, 8, colors.black)
  70.   return card
  71. end
  72.  
  73. function run()
  74.   local club = surface.load("club.nfp")
  75.   screen:clear(colors.green)
  76.   --screen:drawSurfaceSmall(club, 0, 0)
  77.   screen:drawSurface(drawCard("K", "spade"), 3, 3)
  78.   screen:drawSurface(drawCard("A", "club"), 16, 3)
  79.   screen:drawSurface(drawCard("1", "heart"), 3, 18)
  80.   screen:drawSurface(drawCard("2", "diamond"), 16, 18)
  81.   --screen:drawString(tostring(width)..", "..tostring(height), font, 2, 2, colors.red)
  82.   screen:output()
  83. end
  84.  
  85. function getButtonSurface(text, bg)
  86.   local textSize = surface.getTextSize(text, font)
  87.   local button = surface.create(textSize + 2, 7)
  88.   button:fillRect(0,0,textSize+2, 7, bg)
  89.   button:drawText(text, font, 1, 1, colors.black)
  90.   return button
  91. end
  92.  
  93. function betSlider(balance, func)
  94.     local value
  95.     if lastBet ~= nil then
  96.         value = math.min(balance, lastBet)
  97.     else
  98.         value = math.min(MAX_BET / 2, math.floor(balance / 2))
  99.     end
  100.     local buttonPressed = false
  101.     local quitPressed = false
  102.   while not buttonPressed and not quitPressed do
  103.         screen:clear(colors.green)
  104.  
  105.     screen:drawText("BALANCE:", font, math.round((screen.width - surface.getTextSize("BALANCE:", font)) / 2), 2, colors.white)
  106.     screen:drawText("$"..tostring(balance), bigfont, math.round((screen.width - surface.getTextSize("$"..tostring(balance), bigfont)) / 2), 8, colors.white)
  107.     local betText = tostring(value)
  108.     local betTextWidth = surface.getTextSize(betText, font)
  109.     -- local betButton = getButtonSurface("BET", colors.lightBlue)
  110.     -- slider:drawSurface(betButton, math.floor(slider.width / 2), 8)
  111.  
  112.     local updateValue = function(amount)
  113.       return function ()
  114.         value = math.floor(value + amount)
  115.         value = math.min(math.min(MAX_BET, balance), math.max(1, value))
  116.       end
  117.         end
  118.         local yOffset = height - 20
  119.     local betButton = button(screen, "BET", colors.lightBlue, screen.width / 2, yOffset + 8, function() buttonPressed = true end, true)
  120.         button(screen, "QUIT", colors.red, 0, screen.height - 7, function() quitPressed = true end)
  121.         button(screen, "-1", colors.red, math.round(screen.width / 2 - betButton.width / 2 - 11), yOffset, updateValue(-1))
  122.     button(screen, "-8", colors.red, math.round(screen.width / 2 - betButton.width / 2 - 22), yOffset, updateValue(-8))
  123.     button(screen, "+1", colors.lime, math.round(screen.width / 2 + betButton.width / 2 + 2), yOffset, updateValue(1))
  124.     button(screen, "+8", colors.lime, math.round(screen.width / 2 + betButton.width / 2 + 12), yOffset, updateValue(8))
  125.     screen:fillRect(math.round((screen.width - betButton.width)/2), yOffset, betButton.width, 7, colors.white)
  126.     screen:drawText(betText, font, math.round((screen.width - betTextWidth) / 2), yOffset + 1, colors.black)
  127.     screen:output()
  128.     waitForButtonPress(0, 0)
  129.     end
  130.     if quitPressed then
  131.         return nil
  132.     end
  133.     lastBet = value
  134.   return value
  135. end
  136.  
  137. function waitForButtonPress(ox, oy)
  138.   local pressed = false
  139.   while not pressed do
  140.         local event, button, px, py = os.pullEvent("monitor_touch")
  141.     px = px - ox
  142.         py = py - oy
  143.     for text,button in pairs(buttons) do
  144.       if px >= button.x and px <= button.x + button.width and py >= button.y and py <= button.y + button.height then
  145.         button.cb()
  146.         buttons = {}
  147.         pressed = true
  148.       end
  149.     end
  150.   end
  151. end
  152.  
  153.  
  154. function button(surface, text, bg, x, y, func, center)
  155.   local button = getButtonSurface(text, bg)
  156.   if center then
  157.     x = math.floor(x - button.width / 2)
  158.   end
  159.   surface:drawSurface(button, x, y)
  160.   buttons[text] = {x=x, y=y, width=button.width, height=button.height, cb=func}
  161.   return button
  162. end
  163.  
  164. function getHandScore(hand)
  165.     local sum = 0
  166.     local aceCount = 0
  167.     for _,card in ipairs(hand) do
  168.         local nStr = card:sub(1, 1)
  169.         local number = tonumber(nStr)
  170.         if number == nil then
  171.             if nStr == "A" then
  172.                 number = 11
  173.                 aceCount = aceCount + 1
  174.             else
  175.                 number = 10
  176.             end
  177.         end
  178.         sum = sum + number
  179.     end
  180.     local soft = aceCount > 0
  181.     while sum > 21 and aceCount > 0 do
  182.         sum = sum - 10
  183.         aceCount = aceCount - 1
  184.     end
  185.     return sum, soft
  186. end
  187.  
  188. function getPlayerBalance(player)
  189.     rednet.send(MAINFRAME_ID, {type="getPlayerBalance", player=player}, "otto")
  190.     local _, data = rednet.receive("otto")
  191.     if not data then
  192.         return nil
  193.     end
  194.     return data.name, data.balance
  195. end
  196.  
  197. function setPlayerBalance(player, balance)
  198.     rednet.send(MAINFRAME_ID, {type="setPlayerBalance", player=player, balance=balance}, "otto")
  199.     rednet.receive("otto")
  200.     local filePath = fs.combine(drive.getMountPath(), "bal")
  201.     file = fs.open(filePath, "w")
  202.     file.write(tostring(balance))
  203.     file.close()
  204.     return
  205. end
  206.  
  207. function sleep()
  208.   os.sleep(0.1)
  209. end
  210.  
  211. function ease(x)
  212.     local n1 = 7.5625
  213.     local d1 = 2.75
  214.  
  215.     if x < 1 / d1 then
  216.         return n1 * x * x
  217.     elseif x < 2 / d1 then
  218.         x = x - 1.5 / d1
  219.         return n1 * x * x + 0.75
  220.     elseif x < 2.5 / d1 then
  221.         x = x - 2.25 / d1
  222.         return n1 * x * x + 0.9375
  223.     else
  224.         x = x - 2.625 / d1
  225.         return n1 * x * x + 0.984375
  226.     end
  227. end
  228.  
  229. -- for i=0,1,0.01 do
  230. --  print(-ease(i) * 79)
  231. --  os.sleep(0.05)
  232. -- end
  233.  
  234.  
  235. local jX, aX = 0,-30
  236. function drawIdleScreen()
  237.   screen:clear(colors.green)
  238.     for i,card in ipairs(bouncingCards) do
  239.         local x = card.x
  240.         if card.mirror then
  241.             x = (screen.width - cardBack.width) - x
  242.         end
  243.  
  244.         screen:drawSurface(drawCard(card.card), x, math.round((ease(card.x / screen.width)) * (screen.height * 0.75) + (screen.height * 0.25)) - cardBack.height)
  245.         bouncingCards[i].x = card.x + 1
  246.         if card.x > width then
  247.             bouncingCards[i].x = -cardBack.width - 5
  248.             card.card = deck[math.floor(math.random() * #deck) + 1]
  249.         end
  250.     end
  251.     screen:drawSurface(logo, 0, 0)
  252.     -- screen:drawText(" BLACK\n   JACK", bigfont, -1, 1, colors.black)
  253.     -- screen:drawText(" BLACK\n   JACK", bigfont, -1, -1, colors.black)
  254.     -- screen:drawText(" BLACK\n   JACK", bigfont, 1, 1, colors.black)
  255.     -- screen:drawText(" BLACK\n   JACK", bigfont, 1, -1, colors.black)
  256.     -- screen:drawText(" BLACK\n   JACK", bigfont, 0, 0, colors.orange)
  257.   screen:output()
  258. end
  259.  
  260. function quit()
  261.   local player = drive.getDiskID()
  262.   local name, balance = getPlayerBalance(player)
  263.   if balance ~= nil then
  264.     drive.setDiskLabel(name.."'s Periodt Card - $"..tostring(balance))
  265.   end
  266.   turtle.suckDown()
  267.   turtle.dropUp()
  268.   redstone.setOutput("top", false)
  269.   os.sleep(0.1)
  270.     redstone.setOutput("top", true)
  271.     os.sleep(0.1)
  272.   redstone.setOutput("top", false)
  273.   os.sleep(0.1)
  274.   redstone.setOutput("top", true)
  275. end
  276.  
  277. function loop()
  278.  
  279.   screen:clear(colors.green)
  280.   local player = drive.getDiskID()
  281.   local _,balance = getPlayerBalance(player)
  282.   if balance == nil then
  283.     quit()
  284.     return
  285.   end
  286.   screen:drawText(tostring(balance), font, 0,0,colors.black)
  287.     local betAmount = betSlider(balance, quit)
  288.     if betAmount == nil or betAmount == 0 then
  289.     quit()
  290.     return
  291.   end
  292.  
  293.     shuffle(deck)
  294.  
  295.     local playerHand = {deck[1], deck[3]}
  296.     local dealerHand = {deck[2], deck[4]}
  297.     local deckIndex = 5
  298.  
  299.     local userAction = ""
  300.     local handScore = getHandScore(playerHand)
  301.     local dealerScore, dealerSoft = getHandScore(dealerHand)
  302.     local winState
  303.     local canDouble = balance >= betAmount * 2
  304.     local hasDoubled = false
  305.  
  306.     local function drawPlayerHand(hand, y, hideCard)
  307.         local cardDeltaX = cardBack.width + 2
  308.         if cardDeltaX * #hand > screen.width then
  309.             cardDeltaX = (screen.width - 7) / #hand
  310.         end
  311.         local cardX = (screen.width - (#hand * cardDeltaX)) / 2
  312.         for i,card in ipairs(hand) do
  313.             local img
  314.             if hideCard and i == 2 then
  315.                 img = cardBack
  316.             else
  317.                 img = drawCard(card)
  318.             end
  319.             screen:drawSurface(img, math.round(cardX), y)
  320.             cardX = cardX + cardDeltaX
  321.         end
  322.     end
  323.    
  324.     local function drawBottomButtons(buttons)
  325.         local totalWidth = 0
  326.         for _, button in ipairs(buttons) do
  327.             button.width = surface.getTextSize(button.text, font) + 4
  328.             totalWidth = totalWidth + button.width
  329.         end
  330.         local leftX = math.round((screen.width - totalWidth) / 2)
  331.         local accWidth = 0
  332.         for _, b in ipairs(buttons) do
  333.             button(screen, b.text, b.color, leftX + accWidth, screen.height - 8, b.func)
  334.             accWidth = accWidth + b.width
  335.         end
  336.     end
  337.  
  338.     local function drawHands(hideDealerCard, showPlayerButtons)
  339.         screen:clear(colors.green)
  340.         drawPlayerHand(dealerHand, 5, hideDealerCard)
  341.         drawPlayerHand(playerHand, screen.height - 10 - cardBack.height)
  342.         if showPlayerButtons then
  343.             local buttons = {}
  344.             if not hasDoubled then
  345.                 buttons[1] = {
  346.                     text="HIT",
  347.                     color=colors.lightBlue,
  348.                     func=function() userAction = "hit" end
  349.                 }
  350.             end
  351.             buttons[#buttons + 1] = {
  352.                 text="STAND",
  353.                 color=colors.lightBlue,
  354.                 func=function() userAction = "stand" end
  355.             }
  356.             if canDouble then
  357.                 buttons[#buttons + 1]={
  358.                     text="x2",
  359.                     color=colors.lightBlue,
  360.                     func=function() userAction = "double" end
  361.                 }
  362.             end
  363.             drawBottomButtons(buttons)
  364.             -- button(screen, "HIT", colors.lightBlue, hitPos, screen.height - 8, function() userAction = "hit" end)
  365.             -- button(screen, "STAND", colors.lightBlue, hitPos + hitWidth + 1, screen.height - 8, function() userAction = "stand" end)
  366.         end
  367.         screen:output()
  368.     end
  369.  
  370.     if handScore == 21 and dealerScore == 21 then
  371.         winState = "push"
  372.     elseif handScore == 21 then
  373.         winState = "blackjack"
  374.     elseif dealerScore == 21 then
  375.         winState = "dealer blackjack"
  376.     end
  377.  
  378.     if winState == nil then
  379.         -- Do player actions
  380.         while userAction ~= "stand" and handScore < 21 do
  381.             drawHands(true, true)
  382.             waitForButtonPress(0, 0)
  383.             if userAction == "hit" or userAction == "double" then
  384.                 if userAction == "double" then
  385.                     hasDoubled = true
  386.                 end
  387.                 canDouble = false
  388.                 playerHand[#playerHand + 1] = deck[deckIndex]
  389.                 deckIndex = deckIndex + 1
  390.                 handScore = getHandScore(playerHand)
  391.             end
  392.         end
  393.  
  394.         drawHands(false, false)
  395.  
  396.         if handScore > 21 then
  397.             winState = "busted"
  398.         else
  399.             while dealerScore < 17 or (dealerScore == 17 and dealerSoft) do
  400.                 os.sleep(1.5)
  401.                 -- do dealer hit
  402.                 dealerHand[#dealerHand + 1] = deck[deckIndex]
  403.                 deckIndex = deckIndex + 1
  404.                 dealerScore, dealerSoft = getHandScore(dealerHand)
  405.  
  406.                 drawHands(false, false)
  407.             end
  408.             if dealerScore > 21 then
  409.                 winState = "you win"
  410.             elseif dealerScore == handScore then
  411.                 winState = "push"
  412.             elseif dealerScore > handScore then
  413.                 winState = "try again"
  414.             else
  415.                 winState = "you win"
  416.             end
  417.         end
  418.     end
  419.  
  420.     local payoutMult
  421.     if winState == "you win" and hasDoubled then
  422.         payoutMult = 2
  423.     elseif winState == "you win" then
  424.         payoutMult = 1
  425.     elseif winState == "push" then
  426.         payoutMult = 0
  427.     elseif winState == "blackjack" then
  428.         payoutMult = 1.5
  429.     elseif hasDoubled then
  430.         payoutMult = -2
  431.     else
  432.         payoutMult = -1
  433.     end
  434.     if payoutMult > 0 then
  435.         speaker.playSound("minecraft:entity.player.levelup")
  436.     elseif payoutMult < 0 then
  437.         speaker.playSound("minecraft:entity.witch.ambient")
  438.     end
  439.     local payout = math.floor(payoutMult * betAmount)
  440.     setPlayerBalance(player, balance + payout)
  441.  
  442.     local playAgain;
  443.     drawHands(false, false)
  444.     drawBottomButtons({
  445.         [1]={
  446.             text="PLAY AGAIN",
  447.             color=colors.lightBlue,
  448.             func=function() playAgain = true end
  449.         },
  450.         [2]={
  451.             text="QUIT",
  452.             color=colors.orange,
  453.             func=function() playAgain = false end
  454.         }
  455.     })
  456.     local winText = string.upper(winState)
  457.     local winTextWidth = surface.getTextSize(winText, font)
  458.     screen:drawText(winText, font, math.round((screen.width - winTextWidth) / 2), math.round(screen.height / 2 - 5), colors.yellow)
  459.     screen:output()
  460.     waitForButtonPress(0, 0)
  461.     if not playAgain then
  462.         quit()
  463.         return
  464.     end
  465. end
  466.  
  467. setup()
  468. while true do
  469.   if not drive.isDiskPresent() then
  470.     drawIdleScreen()
  471.   else
  472.     loop()
  473.   end
  474.   os.sleep(0.05)
  475. end
  476.  
Add Comment
Please, Sign In to add comment