Larvix

blackjack.lua

Feb 27th, 2026 (edited)
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.71 KB | None | 0 0
  1. -- INITIALISATION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. local paintutils = require("//pup")
  3.  
  4. -- Locate and wrap monitor
  5. mon = peripheral.find("monitor")
  6. -- Change the colour green to a deep green
  7. mon.setPaletteColor(colors.green,0,176,0)
  8. -- Change the colour lime to a slightly lighter deep green
  9. mon.setPaletteColor(colors.lime,0,174,0)
  10. -- Minimise text scale
  11. mon.setTextScale(0.5)
  12. -- Get the size of the monitor
  13. maxX,maxY = mon.getSize()
  14. -- Reset the monitor
  15. mon.clear()
  16.  
  17. -- Create a window for the background
  18. local background = window.create(mon, 1, 1, maxX, maxY, true)
  19. term.redirect(background)
  20. -- Draw the background as # in every pixel
  21. -- fg/bg are the replaced shades of lime/green
  22. for y = 1,maxY do
  23.     term.setCursorPos(1,y)
  24.     term.blit(string.rep("#",maxX),string.rep("5",maxX),string.rep("d",maxX))
  25. end
  26. term.redirect(term.native())
  27.  
  28. -- Initialise each suit icon in a table
  29. suits = {"h","d","s","c"}
  30. -- Initialise each card value in a table
  31. values = {"a","2","3","4","5","6","7","8","9","j","q","k"}
  32. -- Create empty table for storing a deck of cards
  33. -- Each pack has a card for every suit/value combo
  34. -- Add set number of packs together to make a deck
  35. function shuffleDeck(packsUsed)
  36.     deck = {}
  37.     if not packsUsed then packsUsed = 1 end
  38.     for decks = 1,packsUsed do
  39.         for suit = 1,#suits do
  40.             for value = 1,#values do
  41.                 table.insert(deck,tostring(values[value]..suits[suit]))
  42.             end
  43.         end
  44.     end
  45. end
  46.  
  47. -- Create empty tables for storing player and dealer hands
  48. hand = {
  49.     ["d"] = {},
  50.     ["p"] = {}
  51. }
  52.  
  53. -- Set a score the dealer will stop drawing at
  54. dealerLimit = 17
  55.  
  56. -- FUNCTIONS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  57.  
  58. -- Clear the monitor by redrawing the 'table'
  59. function clearTable()
  60.     background.setVisible(true)
  61.     background.redraw()
  62.     background.setVisible(false)
  63. end
  64.  
  65. -- Draw a card object at a given location on the monitor (point is top left of card)
  66. -- Take given suit and value to write on card
  67. function drawCard(target,value,suit)
  68.     local clr = nil
  69.     if suit == "h" or suit == "d" then
  70.         clr = "red"
  71.     else
  72.         clr = "black"
  73.     end
  74.     term.redirect(target)
  75.     if suit == "?" then
  76.         paintutils.loadImage("cards/back.nfp"):upscale():drawImage(1,1)
  77.     else
  78.         paintutils.loadImage("cards/blank.nfp"):upscale():drawImage(1,1)
  79.         paintutils.loadImage("cards/values/"..value..".nfp"):upscale(clr):drawImage(3,2)
  80.         paintutils.loadImage("cards/values/"..value..".nfp"):mirror("x","y"):upscale(clr):drawImage(7,8)
  81.     end
  82.     if value == "q" then
  83.         paintutils.loadImage("cards/faces/q.nfp"):upscale(clr):drawImage(5,2)
  84.         paintutils.loadImage("cards/faces/q.nfp"):mirror("x","y"):upscale(clr):drawImage(2,7)
  85.         paintutils.loadImage("cards/suits/s"..suit..".nfp"):upscale(1):drawImage(3,4)
  86.         paintutils.loadImage("cards/suits/s"..suit..".nfp"):mirror("x","y"):upscale(1):drawImage(7,6)
  87.     elseif value == "k" or value == "j" then
  88.         paintutils.loadImage("cards/faces/"..value..".nfp"):upscale(clr):drawImage(5,2)
  89.         paintutils.loadImage("cards/faces/"..value..".nfp"):mirror("x","y"):upscale(clr):drawImage(3,7)
  90.         paintutils.loadImage("cards/suits/s"..suit..".nfp"):upscale(1):drawImage(3,4)
  91.         paintutils.loadImage("cards/suits/s"..suit..".nfp"):mirror("x","y"):upscale(1):drawImage(7,6)
  92.     elseif value ~= "?" then
  93.         paintutils.loadImage("cards/suits/"..suit..".nfp"):upscale(1):drawImage(3,4)
  94.     end
  95.     term.redirect(term.native())
  96. end
  97.  
  98. -- Add one card to given hand table, remove card from deck and return new table
  99. function dealCard(target)
  100.     drawnCard = math.random(1,#deck)
  101.     table.insert(target, {["v"] = deck[drawnCard], ["i"] = window.create(mon,1,1,10,10,false)})
  102.     table.remove(deck, drawnCard)
  103.     drawCard(target[#target].i,target[#target].v:sub(1,1),target[#target].v:sub(2,2))
  104.     return target
  105. end
  106.  
  107. -- Calculate the total value of a hand and return the score
  108. function getScore(target)
  109.     score = 0
  110.     aceCount = 0
  111.     for c = 1,#target do
  112.         v = target[c].v:sub(1,1)
  113.         if tonumber(v) then
  114.             score = score + v
  115.         elseif v ~= "a" then
  116.             score = score + 10
  117.         else
  118.             aceCount = aceCount + 1
  119.         end
  120.     end
  121.     if aceCount > 0 then
  122.         for i = 1,aceCount do
  123.             if score + 11 > 21 then
  124.                 score = score + 1
  125.             else
  126.                 score = score + 11
  127.             end
  128.         end
  129.     end
  130.     return score
  131. end
  132.  
  133.  
  134. -- Display the player hand and score
  135. function showHandP()
  136.     for c = 1,#hand.p do
  137.         hand.p[c].i.reposition((math.floor((maxX - ((#hand.p * 11) - 1)) / 2) + 1) + ((c - 1) * 11),(maxY/2)+6)
  138.         hand.p[c].i.setVisible(true)
  139.         hand.p[c].i.redraw()
  140.         hand.p[c].i.setVisible(false)
  141.     end
  142.  mon.setBackgroundColour(colors.green)
  143.  mon.setTextColour(colors.black)
  144.     mon.setCursorPos((maxX-10)/2,(maxY/2)+4)
  145.  if getScore(hand.p) > 9 then
  146.     mon.write("Player: "..getScore(hand.p))
  147.  else
  148.  mon.write("Player: 0"..getScore(hand.p))
  149.  end
  150. end
  151.  
  152. -- Display the dealer hand and score
  153. function showHandD()
  154.  for c = 1,#hand.d do
  155.         hand.d[c].i.reposition((math.floor((maxX - ((#hand.d * 11) - 1)) / 2) + 1) + ((c - 1) * 11),(maxY/2)-13)
  156.         hand.d[c].i.setVisible(true)
  157.         hand.d[c].i.redraw()
  158.         hand.d[c].i.setVisible(false)
  159.     end
  160.  mon.setBackgroundColour(colors.green)
  161.  mon.setTextColour(colors.black)
  162.     mon.setCursorPos((maxX-10)/2,(maxY/2)-2)
  163.  if getScore(hand.d) > 9 then
  164.     mon.write("Dealer: "..getScore(hand.d))
  165.  else
  166.  mon.write("Dealer: 0"..getScore(hand.d))
  167.  end
  168. end
  169.  
  170. function hideDealer()
  171.     term.redirect(mon)
  172.     paintutils.loadImage("cards/back.nfp"):upscale():drawImage(((maxX-20)/2)+1,(maxY/2)-13)
  173.     term.redirect(term.native())
  174.     mon.setCursorPos((maxX-10)/2,(maxY/2)-2)
  175.     mon.write("Dealer: ??")
  176. end
  177.  
  178.  
  179. -- RUNTIME~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  180. while true do
  181. clearTable()
  182. shuffleDeck(2)
  183. hand.p = {}
  184. hand.d = {}
  185. -- Deal 2 cards to player and dealer respectively
  186. for i = 1,2 do
  187.     hand.p = dealCard(hand.p)
  188.     hand.d = dealCard(hand.d)
  189. end
  190.  
  191. -- Show 1 card from dealer hand, leave other hidden
  192. --[[
  193. mon.setCursorPos(4,13)
  194. mon.write("Dealer: ??")
  195. mon.setCursorPos(4,maxY-12)
  196. mon.write("Player: ??")
  197. sleep(0.3)
  198. drawCard(4,maxY-10,hand.p[1]:sub(1,1),hand.p[1]:sub(2,2))
  199. sleep(0.3)
  200. drawCard(maxX-11,4,"?","?")
  201. sleep(0.3)
  202. drawCard(15,maxY-10,hand.p[2]:sub(1,1),hand.p[2]:sub(2,2))
  203. sleep(0.3)
  204. drawCard(maxX-22,4,hand.d[2]:sub(1,1),hand.d[2]:sub(2,2))
  205. ]]--
  206.  
  207.  
  208. showHandP()
  209. showHandD()
  210. hideDealer()
  211. if getScore(hand.p) ~= 21 then
  212. -- Loop gameplay until player is bust or decides to stand
  213. -- Show new hand after each card drawn
  214. playing = true
  215. while playing do
  216.     if getScore(hand.p) > 21 or #hand.p == 5 then
  217.         playing = false
  218.     else
  219.         choice = {os.pullEvent("monitor_touch")}
  220.         if choice[3] > maxX/2 then
  221.             playing = false
  222.             print("Player Stands!")
  223.         else
  224.             print("Player Hit!")
  225.             hand.p = dealCard(hand.p)
  226.             clearTable()
  227.             showHandP()
  228.             showHandD()
  229.             hideDealer()
  230.             sleep(0.5)
  231.         end
  232.     end
  233. end
  234. end
  235.  
  236. -- If player is not bust, dealer draws cards
  237. -- Until dealer reaches their set limit, goes bust, or has higher score than player
  238. -- Only happens if player doesn't have BJ
  239. showHandD()
  240. if not (getScore(hand.p) == 21 and #hand.p == 2) then
  241.     if getScore(hand.p) < 22 and #hand.p < 5 then
  242.         while (getScore(hand.d) < dealerLimit) do
  243.             print("Dealer Hit!")
  244.             hand.d = dealCard(hand.d)
  245.             sleep(0.5)
  246.             clearTable()
  247.             showHandD()
  248.             showHandP()
  249.         end
  250.         if getScore(hand.d) < 22 then
  251.             print("Dealer Stands!")
  252.         end
  253.     end
  254. end  
  255.  
  256. -- Determine winner based on hand scores
  257. outcome = ""
  258. if getScore(hand.p) > 21 then
  259.     outcome = "House Win - Player Bust!"
  260. elseif #hand.p == 5 then
  261.     outcome = "Player Win - 5 Card Charlie!"
  262. elseif getScore(hand.d) > 21 then
  263.     outcome = "Player Win - Dealer Bust!"
  264. elseif getScore(hand.p) < 21 and getScore(hand.p) == getScore(hand.d) then
  265.     outcome = "Push - Scores Tied!"
  266. elseif getScore(hand.p) == 21 and getScore(hand.d) == 21 then
  267.     if #hand.p == 2 then
  268.         if #hand.d ~= #hand.p then
  269.             outcome = "Player Win - Natural Blackjack!"
  270.         else
  271.             outcome = "Push - Double Blackjack!"
  272.         end
  273.     elseif #hand.d == 2 then
  274.         outcome = "House Win - Natural Blackjack!"
  275.     end
  276. elseif getScore(hand.p) > getScore(hand.d) then
  277.     outcome = "Player Win - High Hand!"
  278. else
  279.     outcome = "House Win - High Hand!"
  280. end
  281. mon.setCursorPos((maxX-#outcome)/2,(maxY-1)/2+2)
  282. mon.write(outcome)
  283.  
  284. -- Wait for key press to end game
  285. os.pullEvent("monitor_touch")
  286. end
Add Comment
Please, Sign In to add comment