Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- https://pastebin.com/HRsfzDv1
- -- pastebin get HRsfzDv1 startup
- -- autoloader config
- -- pastebin get XcX1FQmw startup
- -- {pastebin='HRsfzDv1 ', program='display'}
- pcall(require, 'computercraft')
- function readConfig()
- if not fs.exists('displayConfig') then
- print('no display config')
- return {}
- end
- local file = fs.open('displayConfig', 'r')--.fakeResult(fileHandle)
- local data = file.readAll()
- file.close()
- return textutils.unserialize(data)
- end
- function connectRednet()
- for k,v in pairs(redstone.getSides()) do
- if peripheral.getType(v) == 'modem' then
- rednet.open(v)
- return
- end
- end
- print('modem not found')
- return false
- end
- function connectMonitor()
- for k,v in pairs(redstone.getSides()) do
- if peripheral.getType(v) == 'monitor' then
- return peripheral.wrap(v)
- end
- end
- print('monitor not found')
- return false
- end
- function delay(seconds)
- -- safe version of 'sleep' - will requeue dropped events
- local timer = os.startTimer(seconds)
- local q = {}
- while true do
- local data = {os.pullEvent()}
- if data[1] == "timer" and data[2] == timer then
- break
- else
- table.insert(q, data)
- end
- end
- for i,v in ipairs(q) do
- os.queueEvent(unpack(v))
- end
- end
- function drawGreen(display, configs)
- display.setBackgroundColor(colors.green)
- display.setTextColor(colors.white)
- display.setTextScale(.5)
- display.clear()
- -- 5x7
- display.setCursorPos(1,1)
- for i=1,10 do
- writeln(display, string.rep(" ",14*configs.size))
- end
- end
- function playerClick(x)
- -- 1-18, 19-40, 41-63, 64-85
- if x <= 18 then
- return 1
- elseif x <= 40 then
- return 2
- elseif x <= 62 then
- return 3
- end
- return 4
- end
- -- returns isBust, isAnyCountEQ21, isBlackjack, value
- function check21OrBust(hand)
- local counts = {0}
- for i=1, table.getn(hand) do
- local handValue = hand[i]%13
- for j=1, table.getn(counts) do
- if handValue < 10 and handValue > 1 then
- counts[j] = counts[j] + handValue
- end
- if handValue >= 10 or handValue == 0 then
- counts[j] = counts[j] + 10
- end
- if handValue == 1 then
- counts[j] = counts[j] + 1
- table.insert(counts, counts[j] + 10) -- this is +11. +10 ontop of +1
- end
- end
- end
- print(textutils.serialize(counts))
- local isAnyCountLTE21 = false
- local isAnyCountEQ21 = false
- local isCardCount2 = table.getn(hand) == 2
- local value = counts[1]
- for k=1, table.getn(counts) do
- if counts[k] <= 21 then isAnyCountLTE21 = true end
- if counts[k] == 21 then isAnyCountEQ21 = true end
- if counts[k] > value and counts[k] <= 21 then
- value = counts[k]
- end
- end
- return not isAnyCountLTE21, isAnyCountEQ21, isAnyCountEQ21 and isCardCount2, value
- end
- function drawJoins(display, players, configs)
- local startPos = {-1,19,41,64}
- drawGreen(display, configs)
- for i=1, configs.size do
- if players[i]==nil then
- display.setBackgroundColor(colors.blue)
- drawBtn(display, 6+startPos[i], 4, 'join')
- elseif players[i].errors then
- display.setBackgroundColor(colors.blue)
- drawBtn(display, 2+startPos[i], 4, players[i].errors[1])
- drawBtn(display, 2+startPos[i], 5, players[i].errors[2])
- elseif players[i].player then
- display.setBackgroundColor(colors.green)
- display.setCursorPos(6+startPos[i],4)
- display.write(players[i].player)
- display.setCursorPos(6+startPos[i],5)
- display.write('joined')
- end
- end
- end
- function writeln(display, text)
- local x,y = display.getCursorPos()
- display.write(text)
- display.setCursorPos(x, y+1)
- end
- function drawBtn(display, x, y, text)
- display.setCursorPos(x,y)
- display.write(string.rep(" ",string.len(text)+2))
- display.setCursorPos(x+1,y)
- display.write(text)
- end
- function drawBet(display, players, currentIndex)
- local startPos = {1,19,41,64}
- for i=1, currentIndex-1 do
- if players[i]~=nil then
- display.setCursorPos(startPos[i],10)
- display.setTextColor(colors.white)
- display.setBackgroundColor(colors.green)
- display.write('bet: $'..players[i].bet)
- end
- end
- end
- function drawBettingScreen(display, player, configs)
- drawGreen(display, configs)
- local startPos = {1,19,41,64}
- display.setCursorPos(startPos[player.order], 2)
- writeln(display, player.player)
- writeln(display, 'balance: $'..player.balance)
- writeln(display, 'bet: $'..player.bet)
- display.setBackgroundColor(colors.blue)
- if configs.min_bet ~= player.bet then
- drawBtn(display, startPos[player.order], 7, '-10')
- end
- if player.balance-(player.bet+10) >= 0 then
- drawBtn(display, startPos[player.order]+11, 7, '+10')
- end
- if player.balance - player.bet >= 0 then
- drawBtn(display, startPos[player.order]+7, 9, 'done')
- end
- drawBtn(display, startPos[player.order]+6, 10, 'cancel')
- end
- function drawCard(display, pos, value, offset)
- display.setBackgroundColor(colors.white)
- display.setTextColor(colors.black)
- if value > 26 then
- display.setTextColor(colors.red)
- end
- value = math.floor(value % 13)
- if value == 11 then value = 'J' end
- if value == 12 then value = 'Q' end
- if value == 13 or value == 0 then value = 'K' end
- if value == 1 then value = 'A' end
- local cardPositions = {{0,2},{3,2},{6,2},{9,2},{0,5}}
- display.setCursorPos(offset + cardPositions[pos][1],cardPositions[pos][2])
- if value == 10 then
- display.write(tostring(value))
- else
- display.write(tostring(value)..' ')
- end
- display.setCursorPos(offset + cardPositions[pos][1],cardPositions[pos][2]+1)
- display.write(' ')
- end
- function drawHands(display, players, configs)
- local startPos = {1,19,41,64}
- for i=1, configs.size do
- if players[i]~=nil then
- for j=1, #players[i].hand do
- drawCard(display, j, players[i].hand[j], startPos[i])
- end
- display.setCursorPos(startPos[i],10)
- display.setTextColor(colors.white)
- display.setBackgroundColor(colors.green)
- display.write('bet: $'..players[i].bet)
- if players[i].specialHand == 'blackjack' then
- display.setBackgroundColor(colors.red)
- drawBtn(display, startPos[i]+8, 9, 'black')
- drawBtn(display, startPos[i]+8, 10, 'jack!')
- display.setBackgroundColor(colors.green)
- end
- if players[i].specialHand == 'bust' then
- display.setBackgroundColor(colors.red)
- drawBtn(display, startPos[i]+9, 10, 'bust')
- display.setBackgroundColor(colors.green)
- end
- end
- end
- end
- function drawActionButtons(display, i, isFirstTurn )
- local startPos = {1,19,41,64, 82}
- display.setBackgroundColor(colors.blue)
- drawBtn(display, startPos[i]+10, 6, 'hit')
- if isFirstTurn then
- drawBtn(display, startPos[i]+7, 8, 'double')
- end
- drawBtn(display, startPos[i]+8, 10, 'stand')
- end
- -- returns isNotDone, isHit
- function checkAction(x, y, player, configs)
- local startPos = {1,19,41,64, 82}
- print('action')
- if x >= startPos[player.order] and x < startPos[player.order+1] then
- if y == 6 and x > startPos[player.order] + 10 then
- print('hit')
- -- if hit, request card
- return true, true
- elseif y==8 and x > startPos[player.order] + 7 and #player.hand == 2 then
- print('double')
- -- if doubledown, betx2 and request card
- rednet.broadcast(textutils.serialize({
- action='bet',
- player=player.player,
- bet=player.bet,
- order=player.order,
- }), configs.protocol)
- player.bet = player.bet*2
- return false, true
- elseif y==10 and x > startPos[player.order] + 8 then
- print('stand')
- -- if stand, is done
- return false, false
- end
- end
- return true, false
- end
- function drawGameScreen(display, players, configs)
- drawGreen(display, configs)
- drawHands(display, players, configs)
- end
- function drawScreen(display, x0, x1)
- display.setCursorPos(x0,1)
- for i=1,10 do
- writeln(display, string.rep(" ",x1-x0))
- end
- end
- function drawEndScreen(display, player, dealerValue)
- local startPos = {1,19,41,64, 82}
- local isBust, is21, isBlackjack, value = check21OrBust(player.hand)
- local screenColor = colors.green
- local message = ''
- --is lost
- if isBust or (dealerValue <=21 and dealerValue > value) then
- screenColor = colors.red
- player.bet = 0
- message = 'Lost!'
- display.setTextColor(colors.black)
- elseif (dealerValue == 0 and isBlackjack) or (dealerValue == value) then
- --push
- screenColor = colors.yellow
- message = 'Push!'
- display.setTextColor(colors.black)
- elseif dealerValue == 0 then
- screenColor = colors.red
- player.bet = 0
- message = 'Lost!'
- display.setTextColor(colors.black)
- elseif dealerValue>21 or dealerValue < value then
- --is won
- display.setTextColor(colors.white)
- if isBlackjack then
- message = 'BLACKJACK!'
- player.bet = player.bet*2.5
- else
- message = 'Won!'
- player.bet = player.bet*2
- end
- end
- display.setBackgroundColor(screenColor)
- drawScreen(display, startPos[player.order], startPos[player.order+1])
- drawBtn(display,startPos[player.order], 2, message)
- drawBtn(display,startPos[player.order], 3, 'won: $'..player.bet)
- display.setBackgroundColor(colors.green)
- end
- -- returns isDone, isCancelled
- function checkBettingAction(x, y, player, configs)
- local startPos = {1,19,41,64, 82}
- if x >= startPos[player.order] and x < startPos[player.order+1] then
- if y == 7 then
- print('betting')
- if x >= startPos[player.order] and x <= startPos[player.order]+5 then
- if player.bet-10 >= configs.min_bet then
- player.bet = player.bet-10
- end
- elseif x >= startPos[player.order]+11 and x <= startPos[player.order]+16 then
- if player.bet+10 <= player.balance then
- player.bet = player.bet+10
- end
- end
- elseif y== 9 then
- print('done')
- return false, false
- elseif y==10 then
- print('cancelled')
- return false, true
- end
- end
- return true, false
- end
- function main()
- connectRednet()
- local display = connectMonitor()
- local configs = readConfig()
- local state = 0
- local dealerId = 0
- local players = {}
- while true do
- parallel.waitForAny(
- function()
- local sender, message, protocol = rednet.receive('ok', 60)
- if protocol == 'ok' then
- rednet.send(sender, configs.protocol..'-display'..configs.order, 'ok')
- end
- end,
- function()
- -- wait for joins
- if state == 0 then
- players = {}
- print('init')
- state = 0.1
- end
- -- wait for joins
- if state == 0.1 then
- parallel.waitForAny(
- -- start action
- function()
- dealerId, message = rednet.receive(configs.protocol..'dealer', 60)
- print('got dealer start')
- if message == 'starting' then
- state = 1
- end
- end,
- -- join action
- function()
- drawJoins(display, players, configs)
- joinEvent, joinButton, joinX, joinY = os.pullEvent("monitor_touch")
- rednet.broadcast(textutils.serialize({
- action='getBalance',
- order=playerClick(joinX),
- }), configs.protocol)
- local joinId, joinMessage = rednet.receive(configs.protocol, 60)
- if joinMessage~=nil then
- local joinRequest = textutils.unserialize(joinMessage)
- if joinRequest.success then
- players[playerClick(joinX)]={
- id=joinId,
- balance=joinRequest.balance,
- order=playerClick(joinX),
- player=joinRequest.player,
- hand={},
- bet=configs.min_bet}
- print(joinRequest.player..' joined')
- else
- players[playerClick(joinX)]={errors={'stand closer', 'and click again'}}
- end
- end
- end)
- end
- -- bet action
- if state == 1 then
- local betActionState = 1
- -- for each player on this monitor
- for betActionState=1, configs.size do
- -- skip no player joined
- if players[betActionState]~= nil then
- print(players[betActionState].player..' betting')
- local isBetting = true
- -- loop while they +/- bet
- while isBetting do
- drawBettingScreen(display, players[betActionState], configs)
- drawBet(display, players, betActionState)
- local bettingEvent, bettingButton, bettingX, bettingY = os.pullEvent("monitor_touch")
- isBetting, isCancelled = checkBettingAction(bettingX, bettingY, players[betActionState], configs)
- if isCancelled then
- players[betActionState] = nil
- end
- end
- rednet.broadcast(textutils.serialize({
- action='bet',
- player=players[betActionState].player,
- bet=players[betActionState].bet,
- order=betActionState,
- }), configs.protocol)
- end
- end
- state = 2
- end
- -- deal 1 card action
- if state == 2 then
- print('done betting')
- local playerSize = 0
- for i=1,configs.size do
- if players[i] ~=nil then playerSize = playerSize + 1 end
- end
- drawGameScreen(display, players, configs)
- print('waiting for cards')
- rednet.send(dealerId, textutils.serialize({
- action='done-betting',
- order=configs.order,
- hands=playerSize,
- }), configs.protocol..'dealer')
- local waitingForDealt = true
- local dealt = {}
- while waitingForDealt do
- local deal1Id, deal1Message = rednet.receive(configs.protocol..'dealer', 60)
- print(deal1Message)
- if deal1Message ~=nil then
- dealt = textutils.unserialize(deal1Message)
- waitingForDealt = false
- end
- end
- -- draw cards
- local isDrawingCards = true
- for i=1,configs.size do
- if players[i] ~=nil then
- table.insert(players[i].hand, table.remove(dealt))
- drawGameScreen(display, players, configs)
- delay(.3)
- end
- end
- rednet.send(dealerId, textutils.serialize({
- action='done-dealing',
- order=configs.order,
- }), configs.protocol..'dealer')
- state = 4
- end
- -- deal 2nd card action
- if state == 4 then
- local waitingForDealt = true
- local dealt = {}
- while waitingForDealt do
- local deal1Id, deal1Message = rednet.receive(configs.protocol..'dealer', 60)
- print(deal1Message)
- if deal1Message ~=nil then
- dealt = textutils.unserialize(deal1Message)
- waitingForDealt = false
- end
- end
- -- draw cards
- local isDrawingCards = true
- for i=1,configs.size do
- if players[i] ~=nil then
- table.insert(players[i].hand, table.remove(dealt))
- drawGameScreen(display, players, configs)
- delay(1)
- end
- end
- print('sent done dealing')
- rednet.send(dealerId, textutils.serialize({
- action='done-dealing',
- order=configs.order,
- }), configs.protocol..'dealer')
- state = 5
- end
- -- resolve each players actions
- if state==5 then
- local waitingForAction = true
- local dealt = {}
- -- wait for dealer to start actions
- while waitingForAction do
- local _, actionMessage= rednet.receive(configs.protocol..'dealer', 60)
- print(actionMessage)
- if actionMessage == 'start-action' then
- waitingForAction = false
- end
- end
- -- do each players actions
- for i=1,configs.size do
- if players[i] ~=nil then
- local notResolved = true
- while notResolved do
- drawGameScreen(display, players, configs)
- local isBust, is21, isBlackjack = check21OrBust(players[i].hand)
- if not isBust and not is21 and not isBlackjack then
- drawActionButtons(display, i, #players[i].hand == 2)
- local actionEvent, actionButton, actionX, actionY = os.pullEvent("monitor_touch")
- notResolved, isHit = checkAction(actionX, actionY, players[i], configs)
- if isHit then
- print('requesting card')
- rednet.send(dealerId, textutils.serialize({action='deal'}), configs.protocol..'dealer')
- local waitingForCard = true
- while waitingForCard do
- local _, card = rednet.receive(configs.protocol..'dealer', 30)
- if card ~=nil then
- print('got card')
- waitingForCard = false
- table.insert(players[i].hand, card)
- end
- end
- end
- else
- -- is 21 OR busted
- notResolved = false
- if isBust then
- players[i].specialHand = 'bust'
- elseif isBlackjack then
- players[i].specialHand = 'blackjack'
- end
- end
- end
- drawGameScreen(display, players, configs)
- end
- end
- -- send action is done message
- print('done action')
- rednet.send(dealerId, textutils.serialize({action='done-action'}), configs.protocol..'dealer')
- state=6
- end
- -- resolve win/loss
- if state==6 then
- local _, dealerValue = rednet.receive(configs.protocol..'dealer', 30)
- if dealerValue then
- print('dealer got:', dealerValue)
- drawGreen(display, configs)
- for i=1,configs.size do
- if players[i] ~=nil then
- drawEndScreen(display, players[i], dealerValue)
- end
- end
- state = 7
- end
- end
- -- wait for reset or reset on timeout
- if state==7 then
- local _, resetValue = rednet.receive(configs.protocol..'dealer', 30)
- state = 0
- end
- end)
- end
- end
- main()
Add Comment
Please, Sign In to add comment