-- BlackJackCC by jimisdam local function interactWithCard(userUUID, mode, money) if mode == "updateBalance" then rednet.broadcast({ uuid = userUUID, amount = money, type = "set" }, "machineBalanceModifier") end if mode == "getBalance" then local _, _, cardUUID = os.pullEvent("nfc_data") rednet.broadcast({ card = cardUUID }, "getAccountData") while true do local id, message = rednet.receive("server_response", 10) if not id then print("the server is down") print("please ping @minecartchris") sleep(30) return 'error' --shell.run("reboot") end if not message then print("WTF!? I got a rednet message with no data!?") print("Rebooting...") sleep(5) return 'error' end if message.type == "account_data" and message.cardId == cardUUID then return { balance = message.balance, uuid = message.uuid, username = message.username, } end end end end -- local SUITS = { 'spades', 'hearts', 'clubs', 'diamonds' } local SUITMOJIS = { utf8.char(6), -- '♠', -- '♠️', utf8.char(3), -- '♥', -- '♥️', utf8.char(5), -- '♣', -- '♣️', utf8.char(4), -- '♦', -- '♦️', } local FACES = { 'ace', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'jack', 'queen', 'king' } local DEFAULT_DECK = {} for si = 1, #SUITMOJIS do for fi = 1, #FACES do local card = { si, fi } table.insert(DEFAULT_DECK, card) end end local function list_concat(list1, list2) local new_list = {} table.move(list1, 1, #list1, 1, new_list) table.move(list2, 1, #list2, #list1 + 1, new_list) return new_list end local function deck_populate(deck, times) times = times or 1 if times > 0 then deck = list_concat(deck, deck) return deck_populate(deck, times - 1) end return deck end local function list_shuffle(list, times) times = times or 1 if times > 0 then for i = 1, #list do local j = math.random(#list) list[i], list[j] = list[j], list[i] end return list_shuffle(list, times - 1) end end local deck_shuffle = list_shuffle local function hand_serve(deck, times, hand) times = times or 1 hand = hand or {} if times > 0 then local card = table.remove(deck, 1) table.insert(hand, card) return hand_serve(deck, times - 1, hand) end return hand end local function card_count(card) local f = card[2] if f > 10 then return 10 else return f end end local function hand_count(hand) local score = 0 local had_ace = false for _ci, card in ipairs(hand) do score = score + card_count(card) had_ace = had_ace or (card[2] == 1) end if (score <= 11) and had_ace then score = score + 10 end return score end local function card_pretty(card, is_hidden) is_hidden = is_hidden or false if is_hidden then return '??' end local s = SUITMOJIS[card[1]] local f = FACES[card[2]] if type(f) == 'number' then f = tostring(f) elseif type(f) == 'string' then f = f:sub(1, 1):upper() end return s .. f end local function card_print(card, is_hidden) is_hidden = is_hidden or false local suit_fg_colour = colors.toBlit(colors.red) if card[1] % 2 > 0 then suit_fg_colour = colors.toBlit(colors.black) end local card_str = card_pretty(card, is_hidden) local face_fg_colour = colors.toBlit(colors.black):rep(#card_str - 1) term.blit(card_str, suit_fg_colour .. face_fg_colour, ('0'):rep(#card_str)) end local function hand_print(hand, is_dealer) is_dealer = is_dealer or false for ci, card in ipairs(hand) do local separator = ', ' if ci == #hand then separator = '' end card_print(card, is_dealer and ci == 1 and #hand == 2) io.write(separator) end end local function term_reset() term.clear() term.setCursorPos(1, 1) end local function credits_print(who) print('[BlackJack by ' .. who .. ']\n') end local function game_print(dealer_hand, player_hand, is_first_round) is_first_round = is_first_round or false local dealer_count_str = ': ' .. hand_count(dealer_hand) if is_first_round then dealer_count_str = '' end print('[Dealer' .. dealer_count_str .. ']') hand_print(dealer_hand, is_first_round) print('\n') print('[Player: ' .. hand_count(player_hand) .. ']') hand_print(player_hand) print('\n') end local function game_winner(dealer_hand, player_hand) local dealer_count = hand_count(dealer_hand) local player_count = hand_count(player_hand) local has_dealer_blackjack = dealer_count == 21 and #dealer_hand == 2 local has_player_blackjack = player_count == 21 and #player_hand == 2 if has_dealer_blackjack and not has_player_blackjack then return 'dealer' elseif has_player_blackjack and not has_dealer_blackjack then return 'player' end local is_dealer_greater = dealer_count > player_count local is_player_greater = player_count > dealer_count local has_dealer_busted = dealer_count > 21 local has_player_busted = player_count > 21 local dealer_wins = has_player_busted or (not has_dealer_busted and is_dealer_greater) local player_wins = not has_player_busted and (has_dealer_busted or is_player_greater) if dealer_wins then return 'dealer' elseif player_wins then return 'player' end return 'tie' end -- Game Script rednet.open('back') os.pullEvent = function(...) while true do local t = table.pack(os.pullEventRaw(...)) if t[1] ~= 'terminate' then return table.unpack(t, 1, t.n) end end end ::post_init:: term_reset() credits_print('jimisdam') print('Please swipe your card to begin') local player_data = interactWithCard(nil, "getBalance", nil) if player_data == 'error' then goto post_init end local player_bet = nil while true do term_reset() credits_print('jimisdam') print('Balance: ' .. player_data.balance) io.write('Bet: ') player_bet = tonumber(read()) if not player_bet then print('\nNot a number') goto continue elseif player_data.balance < player_bet then print('\nInsufficient amount') goto continue end break ::continue:: sleep(3) end local deck = deck_populate(DEFAULT_DECK) deck_shuffle(deck, 1000) local dealer_hand = hand_serve(deck, 2) local player_hand = hand_serve(deck) repeat hand_serve(deck, 1, player_hand) term_reset() credits_print('jimisdam') game_print(dealer_hand, player_hand, #dealer_hand == 2) io.write("Want to Hit (y/n): ") until read() ~= 'y' while hand_count(dealer_hand) < 17 do hand_serve(deck, 1, dealer_hand) term_reset() credits_print('jimisdam') game_print(dealer_hand, player_hand) end local winner = game_winner(dealer_hand, player_hand) if winner == 'dealer' then print('You Busted!') player_data.balance = player_data.balance - player_bet elseif winner == 'player' then print('You Win!') player_data.balance = player_data.balance + player_bet elseif winner == 'tie' then print("Tie!") else print('WTF CASE!') end term_reset() credits_print('jimisdam') game_print(dealer_hand, player_hand) print('\nBalance: ' .. player_data.balance) interactWithCard(player_data.uuid, 'updateBalance', player_data.balance) sleep(5) goto post_init