#Module importieren
import arcade
import arcade.gui
import arcade.gui.widgets.buttons
import arcade.gui.widgets.layout
from arcade.gui import UIFlatButton
import random
import time
#Variablen definieren
width = 1200
height = 800
title = "Black Jack Arcade"
button_words = ["Hit", "Stand", "Split", "Double Down"]
border_color = arcade.color.ZINNWALDITE_BROWN
#Karten sprite variablen
# Constants for sizing
CARD_SCALE = 0.1
# Card constants
CARD_VALUES = ["8", "4"]
CARD_SUITS = ["Kreuz", "Herz", "Pik", "Karo"]
#"A", "2", "3", "4", "5", "6", "7",
#, "9", "10", "J", "Q", "K
# Face down image
FACE_DOWN_IMAGE = f"./cards/coverCover.jpg"
CARD_STACK_OFFSET = 50 # karten abstand der hand
#klassen erstellen
class Card(arcade.Sprite):
""" Card sprite """
def __init__(self, suit, value, scale=1):
""" Card constructor """
# Attributes for suit and value
self.suit = suit
self.value = value
# Image to use for the sprite when face up
self.image_file_name = f"./cards/card{self.suit}{self.value}.jpg"
self.is_face_up = False
super().__init__(FACE_DOWN_IMAGE, scale, hit_box_algorithm="None")
def face_down(self):
""" Turn card face-down """
self.texture = arcade.load_texture(FACE_DOWN_IMAGE)
self.is_face_up = False
def face_up(self):
""" Turn card face-up """
self.texture = arcade.load_texture(self.image_file_name)
self.is_face_up = True
def card_value(self):
""" Return the numerical value of the card """
if self.value in ["J", "Q", "K"]:
return 10
elif self.value == "A":
return 11
else:
return int(self.value)
def card_suit(self):
return self.card_suit
def is_face_down(self):
""" Is this card face down? """
return not self.is_face_up #Karten
class game(arcade.Window):
#Fenster öffnen und Spiel initialisieren
def __init__(self):
super().__init__(width, height, title)
arcade.set_background_color(arcade.color.AO)
self.manager = arcade.gui.UIManager()
self.manager.enable()
self.setup()
self.on_draw()
def textures(self):
# create wooden background
wood_background = arcade.load_texture(
"./game_textures/background_wood.jpg")
arcade.draw_lbwh_rectangle_textured(0, 0, 1200, 800, wood_background)
# create green felt texture
playing_field = arcade.load_texture(
"./game_textures/background_felt.jpg")
arcade.draw_lbwh_rectangle_textured(250, 50, 900, 700, playing_field)
arcade.draw_rectangle_outline(700, 400, 900, 700, border_color, 3)
def on_draw(self):
arcade.start_render() #startet das rendering
self.textures() #erstellt die Bereiche mit den Texturen
self.manager.draw() #lädt UI Elemente
#Ränder für Buttons
for i in range(len(button_words)):
arcade.draw_rectangle_outline(125, 680 - (i * 150), 190, 100, border_color, 3)
#Rand für Spielfläche
arcade.draw_rectangle_outline(125, 95, 95, 50, border_color, 3)
# gelbe Fläche für die Karten
arcade.draw_xywh_rectangle_outline(990, 321, 120, 158, color=arcade.color.AMBER, border_width=3)
#Karten rendern
self.card_deck.draw()
self.drawn_cards_player.draw()
self.drawn_cards_dealer.draw()
self.split_deck_left.draw()
self.split_deck_right.draw()
# Rendern beenden
arcade.finish_render()
def create_buttons(self):
# styles
button_style = {
'normal': UIFlatButton.UIStyle(
font_size=30,
font_name=('Kenney Pixel'),
font_color=arcade.color.BLACK,
bg=arcade.color.RED,
border=None,
border_width=0,
),
'hover': UIFlatButton.UIStyle(
font_size=30,
font_name=('Kenney Pixel'),
font_color=arcade.color.BLACK,
bg=arcade.color.REDWOOD,
border=None,
border_width=2,
),
'press': UIFlatButton.UIStyle(
font_size=30,
font_name=('Kenney Pixel'),
font_color=arcade.color.BLACK,
bg=arcade.color.REDWOOD,
border=None,
border_width=2,
)
}
exit_button_style = {
'normal': UIFlatButton.UIStyle(
font_size=20,
font_name=('Kenney Pixel'),
font_color=arcade.color.WHITE,
bg=arcade.color.BLACK,
border=None,
border_width=0,
),
'hover': UIFlatButton.UIStyle(
font_size=20,
font_name=('Kenney Pixel'),
font_color=arcade.color.WHITE,
bg=arcade.color.AUROMETALSAURUS,
border=None,
border_width=2,
),
'press': UIFlatButton.UIStyle(
font_size=20,
font_name=('Kenney Pixel'),
font_color=arcade.color.AUROMETALSAURUS,
bg=arcade.color.AUROMETALSAURUS,
border=None,
border_width=2,
)
}
# Create buttons and associate them with functions
for i, word in enumerate(button_words):
button_function = getattr(self, f"button{i + 1}_click") # Get corresponding function dynamically
buttons = arcade.gui.UIFlatButton(text=word, x=30, y=630 - (i * 150), width=190, height=100,
style=button_style)
buttons.on_click = button_function # Assign the appropriate function
self.manager.add(buttons)
exit_button = arcade.gui.UIFlatButton(text="Exit", x=77.5, y=70, width=95, height=50, style=exit_button_style)
exit_button.on_click = self.on_exit_quit
self.manager.add(exit_button)
#Counter für Spieler und Dealer Werte
def counter(self):
if self.split_deck == False:
#player counter
self.text = str(self.summe)
self.p_counter = arcade.gui.UITextArea(text=self.text, width=450, height=40, font_size=24, font_name="Kenney Future", x=350,
y=100)
self.manager.add(self.p_counter)
#dealer counter
self.dealer_text = str(self.dealer_summe)
self.d_counter = arcade.gui.UITextArea(text=self.dealer_text, width=450, height=40, font_size=24, font_name="Kenney Future", x=350,
y=660)
self.manager.add(self.d_counter)
elif self.split_deck == True:
self.manager.remove(self.p_counter)
self.text = str(self.split_summe_left)
self.p_counter_left = arcade.gui.UITextArea(text=self.text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=350, y=100)
self.manager.add(self.p_counter_left) # Add the updated counter
self.text = str(self.split_summe_right)
self.p_counter_right = arcade.gui.UITextArea(text=self.text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=1050, y=100)
self.manager.add(self.p_counter_right) # Add the updated counter
self.on_draw()
def counter_update(self, typ):
if typ == "p":
if self.split_deck == False:
self.text = str(self.summe)
self.manager.remove(self.p_counter) # Remove the old counter
self.p_counter = arcade.gui.UITextArea(text=self.text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=350, y=100)
self.manager.add(self.p_counter) # Add the updated counter
self.on_draw()
else:
self.text = str(self.split_summe_left)
self.manager.remove(self.p_counter_left) # Remove the old counter
self.p_counter_left = arcade.gui.UITextArea(text=self.text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=350, y=100)
self.manager.add(self.p_counter_left) # Add the updated counter
self.text = str(self.split_summe_right)
self.manager.remove(self.p_counter_right) # Remove the old counter
self.p_counter_right = arcade.gui.UITextArea(text=self.text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=600, y=100)
self.manager.add(self.p_counter_right) # Add the updated counter
self.on_draw()
elif typ == "d":
self.dealer_text = str(self.dealer_summe)
self.manager.remove(self.d_counter) # Remove the old counter
self.d_counter = arcade.gui.UITextArea(text=self.dealer_text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=350, y=660)
self.manager.add(self.d_counter) # Add the updated counter
self.on_draw()
#setzt Spielwerte auf die Ausgangslage zurück
def setup(self):
self.create_buttons()
# definiert drei sprite listen fürs karten deck und die gezogenen karten(spieler/dealer)
self.card_deck = arcade.SpriteList()
#deck erstellen
for card_suit in CARD_SUITS:
for card_value in CARD_VALUES:
card = Card(card_suit, card_value, CARD_SCALE)
self.card_deck.append(card)
card.position = 1050, 400
# Spieler werte, anzahl der karten, wertesumme, zähler
self.drawn_cards_player = arcade.SpriteList()
self.player_value = []
self.summe = 0
self.count = 0
#dealer werte, anzahl der karten, wertesumme, zähler
self.drawn_cards_dealer = arcade.SpriteList()
self.dealer_value = []
self.dealer_count = 0
self.dealer_summe = 0
#Split dinge
self.split_deck = False
self.split_deck_left = arcade.SpriteList()
self.split_deck_right = arcade.SpriteList()
self.split_deck_value_left = []
self.split_deck_value_right = []
self.split_deck_count_left = 0
self.split_deck_count_right = 0
self.split_summe_left = 0
self.split_summe_right = 0
self.counter()
arcade.schedule(self.delayed_start, 1.0)
def delayed_start(self, delta_time):
arcade.unschedule(self.delayed_start)
if self.count == 0:
self.game_start(1)
elif self.dealer_count == 0:
self.game_start(2)
elif self.count == 2:
self.game_start(2)
self.win_condition(1)
elif self.dealer_count == 1:
self.game_start(1)
def game_start(self,typ):
#Karten Spieler
if typ == 1:
#1 Karte Spieler
self.karte_ziehen("player")
self.counter_update("p")
arcade.schedule(self.delayed_start, 1)
#1 Karte Dealer
if typ == 2:
self.karte_ziehen("dealer")
if self.dealer_count < 2:
arcade.schedule(self.delayed_start, 1)
self.counter_update("d")
def karte_ziehen(self, typ):
random_card = random.choice(self.card_deck)
self.card_deck.remove(random_card)
if typ == "player":
if self.split_deck == False:
random_card.face_up()
self.drawn_cards_player.append(random_card)
random_card.position = 680 + (self.count * 21), 180 # Adjust y position
self.player_value.append(random_card.card_value()) # Add card value to player value list
self.summe = sum(self.player_value)
print(f"Spieler Summe:{self.summe}")
self.counter_update("p")
self.count += 1
if self.summe != 21 and self.count != 2:
self.win_condition(1)
elif self.summe == 21 and self.count != 2:
self.win_condition(1)
elif self.split_deck == True:
if self.split_deck_count_left == self.split_deck_count_right :
random_card.face_up()
self.split_deck_left.append(random_card)
random_card.position = 600 + (self.split_deck_count_left * 21), 180 # Adjust y position
self.split_deck_value_left.append(random_card.card_value()) # Add card value to player value list
self.split_summe_left = sum(self.split_deck_value_left)
print(f"Deck links:{self.split_summe_left}")
self.counter_update("p")
self.split_deck_count_left += 1
else:
y = 780
random_card.face_up()
self.split_deck_right.append(random_card)
random_card.position = 780 + (self.split_deck_count_right * 21), 180 # Adjust y position
self.split_deck_value_right.append(random_card.card_value()) # Add card value to player value list
self.split_summe_right = sum(self.split_deck_value_right)
print(f"Deck Rechts:{self.split_summe_right}")
self.counter_update("p")
self.split_deck_count_right += 1
elif typ == "dealer":
self.drawn_cards_dealer.append(random_card)
random_card.position = 680 + (self.dealer_count * 21), 600 # Different y position for dealer
self.dealer_value.append(random_card.card_value()) # Add card value to player value list
self.dealer_summe = sum(self.dealer_value)
print(f"Dealer Summe {self.dealer_summe}")
self.dealer_count += 1
if self.dealer_count == 2:
random_card.face_down()
else: random_card.face_up(), self.counter_update("d")
self.drawn_cards_dealer.draw()
def button1_click(self, button):
self.karte_ziehen("player")
def button2_click(self, button):
self.dealer_continue()
def button3_click(self, button):
if self.count > 2:
self.split_con_text(1)
elif self.split_deck == False and self.drawn_cards_player[0].card_value() == self.drawn_cards_player[1].card_value():
self.split()
elif self.split_deck == True:
self.split()
elif self.split_deck == False and self.drawn_cards_player[0].card_value() != self.drawn_cards_player[1].card_value():
self.split_con_text(2)
def split(self):
if self.split_deck == False:
self.split_deck = True
self.drawn_cards_player[0].center_x = 600
self.drawn_cards_player[1].center_x = 780
self.split_deck_left.append(self.drawn_cards_player[0])
self.split_deck_value_left.append(int(self.summe / 2))
self.split_summe_left = sum(self.split_deck_value_left)
self.split_deck_count_left += 1
self.split_deck_right.append(self.drawn_cards_player[1])
self.split_deck_value_right.append(int(self.summe / 2))
self.split_summe_right = sum(self.split_deck_value_right)
self.split_deck_count_right += 1
for i in range(2):
self.drawn_cards_player.remove(self.drawn_cards_player[0])
self.counter()
self.on_draw()
elif self.split_deck == True:
self.split_con_text(3)
self.counter()
def button4_click(self, button):
# Action for button 2
print("Double Down")
def dealer_continue(self):
self.drawn_cards_dealer[1].face_up() # Reveal the second dealer card
self.counter_update("d")
self.on_draw()
while self.dealer_summe < 17:
if self.dealer_summe > self.summe:
break
else:
time.sleep(1)
self.karte_ziehen("dealer")
self.win_condition(2)
def win_condition(self, typ):
if typ == 1:
# Check for player bust
if self.summe > 21:
self.end_text = "Lose!"
arcade.schedule(self.delayed_end, 0.5)
return
# Check for player blackjack
if self.count == 2 and self.summe == 21:
if self.dealer_count == 2 and self.dealer_summe == 21:
self.end_text = "Push!"
else:
self.end_text = "Black Jack!"
arcade.schedule(self.delayed_end, 0.5)
return
# If player has more than 2 cards and a sum of 21, let dealer continue
if self.count > 2 and self.summe == 21:
self.dealer_continue()
return
elif typ == 2:
# Dealer must stand on 17 or higher
if self.dealer_summe > 21:
self.end_text = "Win!"
elif self.dealer_summe > self.summe:
self.end_text = "Lose!"
elif self.dealer_summe < self.summe:
self.end_text = "Win!"
else:
self.end_text = "Push!"
arcade.schedule(self.delayed_end, 0.5)
return
#beendet das spiel und startet es neu
def delayed_end(self, delta_time):
arcade.unschedule(self.delayed_end)
self.end()
def end(self):
self.counter_update("d")
self.drawn_cards_dealer[1].face_up()
self.restart()
def split_con_text(self, typ):
if typ == 1:
self.cond = arcade.gui.UITextArea(text="Split nur bei zwei Karten möglich!", width=600, height=40,
font_size=15,
font_name="Kenney Future", x=450, y=380)
self.manager.add(self.cond)
self.on_draw()
elif typ == 2:
self.cond = arcade.gui.UITextArea(text="Karten sind nicht gleichwertig!", width=600, height=40, font_size=15,
font_name="Kenney Future", x=450, y=380)
self.manager.add(self.cond)
self.on_draw()
elif typ == 3:
self.cond = arcade.gui.UITextArea(text="Nur ein Split möglich!", width=600, height=40,
font_size=15,
font_name="Kenney Future", x=450, y=380)
self.manager.add(self.cond)
self.on_draw()
arcade.schedule(self.delayed_cond,1)
def double_down_con_text(self):
self.cond = arcade.gui.UITextArea(text="Mindestens eine Karte ziehen!", width=600, height=40, font_size=15,
font_name="Kenney Future", x=425, y=380)
self.manager.add(self.cond)
self.on_draw()
arcade.schedule(self.delayed_cond, 1)
def delayed_cond(self, delta_time):
arcade.unschedule(self.delayed_cond)
self.manager.remove(self.cond)
def restart(self):
print(self.end_text)
self.end_text = arcade.gui.UITextArea(text=self.end_text, width=450, height=40, font_size=24,
font_name="Kenney Future", x=600, y=400)
self.manager.add(self.end_text)
self.on_draw()
time.sleep(1.0)
self.manager.clear()
self.setup()
def on_exit_quit(self, event):
arcade.exit()
def start():
window = game()
arcade.run()
if __name__ == "__main__":
start()
My Problem ist that after hitting Split the cards split and new counters for both piles are created. But when hitting Hit and getting a new card for each pile the sums update but the counter isn’t. it’s working when you don’t hit split for the whole game. I don´t understand the problem because its the same structure as in the other counter update