first commit

This commit is contained in:
2025-01-12 13:19:14 -05:00
commit 6fa67ece7d
2 changed files with 244 additions and 0 deletions

238
blackjack/blackjack.py Normal file
View File

@@ -0,0 +1,238 @@
import random
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
from maubot import Plugin, MessageEvent
from maubot.handlers import command
class BlackjackBot(Plugin):
values = ['2','3','4','5','6','7','8','9','10','Jack','Queen','King','Ace']
suites = ['Hearts', 'Clubs', 'Diamonds', 'Spades']
deck = []
players = []
game_pending = False
game_started = False
awaiting_commands = False
player_cards = {}
player_score = {}
dealer_cards = []
dealer_score = 0
player_status = {}
def init_game(self):
self.deck = [(card, category) for category in self.suites for card in self.values]
def end_game(self):
self.players = []
self.game_pending = False
self.game_started = False
self.awaiting_commands = False
self.player_cards = {}
self.player_score = {}
self.dealer_cards = []
self.dealer_score = 0
self.player_status = {}
def card_value(self, card):
if card[0] in ['Jack', 'Queen', 'King']:
return 10
elif card[0] == 'Ace':
return 11
else:
return int(card[0])
def get_score(self, cards):
score = 0
aces = 0
for card in cards:
score += self.card_value(card)
if (card[0] == 'Ace'):
aces += 1
while (score > 21 and aces > 0):
aces -= 1
score -= 10
return score
def cards_named(self, cards):
named_list = []
for card in cards:
named_list.append(card[0] + " of " + card[1])
return named_list
def shuffle_deck(self) -> None:
random.shuffle(self.deck)
def add_player(self, player) -> None:
self.players.append(player)
async def dealers_turn(self, evt: MessageEvent) -> None:
players_bust = 0
for player in self.players:
if (self.player_status[player] == -1):
players_bust += 1
if (players_bust == len(self.players)):
for player in self.players:
await evt.respond("Player " + player + " loses")
self.end_game()
return
await evt.respond("Cards of Dealer: " + ', '.join(self.cards_named(self.dealer_cards)))
await evt.respond("Score of Dealer: " + str(self.dealer_score))
while (self.dealer_score < 17):
await evt.respond("Dealer draws")
self.dealer_cards.append(self.deck.pop())
self.dealer_score = self.get_score(self.dealer_cards)
await evt.respond("Cards of Dealer: " + ', '.join(self.cards_named(self.dealer_cards)))
await evt.respond("Score of Dealer: " + str(self.dealer_score))
if (self.dealer_score > 21):
await evt.respond("Dealer busts!")
for player in self.players:
if (self.player_status[player] != -1):
await evt.respond("Player " + player + " wins!")
elif (self.player_status[player] == -1):
await evt.respond("Player " + player + " loses")
else:
for player in self.players:
if (self.player_status[player] != -1):
if (self.player_score[player] > self.dealer_score):
await evt.respond("Player " + player + " wins!")
elif (self.player_score[player] == self.dealer_score):
await evt.respond("Player " + player + " pushes")
elif (self.player_score[player] < self.dealer_score):
await evt.respond("Player " + player + " loses")
elif (self.player_status[player] == -1):
await evt.respond("Player " + player + " loses")
self.end_game()
def bj_match(self, command: str) -> bool:
return command in ["blackjack", "bj"]
@command.new(aliases=bj_match)
async def blackjack(self, evt: MessageEvent) -> None:
if ( not self.game_pending and not self.game_started ):
self.game_pending = True;
await evt.respond("Starting a game of Blackjack, type !join to play")
def join_match(self, command: str) -> bool:
return command in ["join", "j"]
@command.new(aliases=join_match)
async def join(self, evt: MessageEvent) -> None:
if (self.game_pending):
if (evt.sender in self.players):
return
self.add_player(evt.sender)
await evt.respond("Player " + evt.sender + " has joined the game!")
await evt.respond("When all players have joined, type !begin to start the game")
def begin_match(self, command: str) -> bool:
return command in ["begin", "b"]
@command.new(aliases=begin_match)
async def begin(self, evt: MessageEvent) -> None:
if (self.game_pending):
self.game_pending = False
self.game_started = True
self.init_game()
self.shuffle_deck()
for player in self.players:
self.player_cards[player] = [self.deck.pop(), self.deck.pop()]
self.player_status[player] = 0
self.player_score[player] = self.get_score(self.player_cards[player])
self.dealer_cards = [self.deck.pop(), self.deck.pop()]
self.dealer_score = self.get_score(self.dealer_cards)
for player in self.players:
await evt.respond("Cards " + player + " has: " + ', '.join(self.cards_named(self.player_cards[player])))
await evt.respond("Score of " + player + ": "+ str(self.player_score[player]))
if (self.player_score[player] == 21):
await evt.respond("Player " + player + " has blackjack!")
self.player_status[player] = 2
if (self.dealer_score == 21):
await evt.respond("Cards of Dealer: " + ' '.join(self.cards_named(self.dealer_cards)))
await evt.respond("Dealer has blackjack!")
for player in self.players:
if (self.player_score[player] == 21):
await evt.respond("Player " + player + " pushes")
elif (self.player_score[player] < 21):
await evt.respond("Player " + player + " loses")
self.end_game()
return
else:
await evt.respond("Cards of Dealer: " + ' '.join(self.cards_named(self.dealer_cards[1:])))
self.awaiting_commands = True
# edge case handling when all players get blackjack
waiting_for_players = 0
for player in self.players:
if (self.player_status[player] == 0):
waiting_for_players += 1
if (waiting_for_players == 0):
self.end_game()
def hit_match(self, command: str) -> bool:
return command in ["hit", "h"]
@command.new(aliases=hit_match)
async def hit(self, evt: MessageEvent) -> None:
player = evt.sender
if (self.awaiting_commands and player in self.players):
if (self.player_status[player] != 0):
return
self.player_cards[player].append(self.deck.pop())
self.player_score[player] = self.get_score(self.player_cards[player])
await evt.respond("Cards " + player + " has: " + ', '.join(self.cards_named(self.player_cards[player])))
await evt.respond("Score of " + player + ": "+ str(self.player_score[player]))
if (self.player_score[player] > 21 ):
self.player_status[player] = -1
await evt.respond("Player " + player + " busts!")
waiting_for_players = 0
for player in self.players:
if (self.player_status[player] == 0):
waiting_for_players += 1
if (waiting_for_players == 0):
await self.dealers_turn(evt)
def stand_match(self, command: str) -> bool:
return command in ["stand", "stay", "s"]
@command.new(aliases=stand_match)
async def stand(self, evt: MessageEvent) -> None:
player = evt.sender
if (self.awaiting_commands and player in self.players):
if (self.player_status[player] != 0):
return
self.player_status[player] = 1
waiting_for_players = 0
for player in self.players:
if (self.player_status[player] == 0):
waiting_for_players += 1
if (waiting_for_players == 0):
await self.dealers_turn(evt)
@command.new("end")
async def end(self, evt: MessageEvent) -> None:
if (self.game_pending or self.game_started):
self.end_game()
await evt.respond("Blackjack has ended")
@command.new("help")
async def help(self, evt: MessageEvent) -> None:
await evt.respond("!blackjack to initiate a new game players can join")
await evt.respond("!join to join a pending game")
await evt.respond("!begin to start once everyone is on")
await evt.respond("!hit to draw a new card")
await evt.respond("!stand to stop drawing")
await evt.respond("!end to stop a currently running game")