SPANHIS-DECK CARD SIMULATOR

Objective:
Create a Spanish-deck card simulator that builds a full deck with tuples and sets, draws random cards while updating the deck and per-suit counters, performs set operations, supports targeted search, and estimates draw probabilities.

How it works:

  1. Define deck structure: Create immutable tuples for suits (Oros, Copas, Espadas, Bastos) and ranks (As, 2–7, Sota, Caballo, Rey), then build the deck as a set of (valor, palo) tuples to ensure uniqueness.

  2. Track suit counts: Initialize global counters per suit (numero_oros, etc.) to tally the suits of cards drawn across the session.

  3. Draw and remove card: In sacar_carta(baraja), sample one card at random, print it, remove it from the set, update the remaining-card count, and increment the corresponding suit counter.

  4. Interactive draw loop: While there are cards left, repeat draws and prompt the user (si/no) to continue; stop gracefully when the user declines or the deck empties.

  5. Summarize draws: After the loop, print per-suit totals (bastos, copas, espadas, oros) accumulated during the session.

  6. Build suit subsets: From the (possibly reduced) deck, construct suit-specific sets (e.g., cartas_espadas) and demonstrate set algebra (union, intersection, difference, symmetric difference) between suits.

  7. Search utility: Implement buscar_cartas(baraja, valor=None, palo=None) to filter by value, suit, both, or neither, returning a set of matching cards; show examples (all As, all Oros, the Rey de Espadas).

  8. Probability estimator: Implement calcular_probabilidad(...) that, given a value and/or suit, computes the probability relative to the current deck size (after removals) and prints counts and totals before returning the probability.


# El objetivo es crear un programa que simule sacar una carta de la baraja, usando tuplas, diccionarios y conjuntos, además de algunas operaciones con ellos.
# Habrá que: mostrar todas las cartas disponibles, sacar una carta al azar actualizando la baraja y hacer operaciones con conjuntos para comparar diferentes barajas, además de lo que se me ocurra.

import random
# Creo las tuplas pues son inmutables
tupla_palos = ("Oros", "Copas", "Espadas", "Bastos")
tupla_valores = ("As", "2", "3", "4", "5", "6", "7", "Sota", "Caballo", "Rey")

# Aplicamos un contador global de cuantos palos va sacando el programa
numero_oros = 0
numero_copas = 0
numero_espadas = 0
numero_bastos = 0

# Creo un set en el que cada carta es una tupla con 2 valores: el valor y el palo.
baraja = {(valor, palo) for valor in tupla_valores for palo in tupla_palos}
print(f"Total cartas: {len(baraja)}")

# Hagamos operaciones y definamos funciones
def sacar_carta(baraja):
    global numero_oros, numero_copas, numero_espadas, numero_bastos
    # Escoge una carta al azar y desempaqueta
    carta = random.sample(list(baraja), 1)[0]
    print(f"Carta seleccionada: {carta}")

    # Eliminar la carta si está en el conjunto
    if carta in baraja:
        baraja.remove(carta)
        print(f"Carta eliminada: {carta}")
    else:
        print("Error: La carta seleccionada no está en la baraja.")

    print(f"Cartas restantes: {len(baraja)}")
    
    # Contador por palo
    if carta[1] == "Oros":
        numero_oros += 1
    elif carta[1] == "Copas":
        numero_copas += 1
    elif carta[1] == "Espadas":
        numero_espadas += 1
    elif carta[1] == "Bastos":
        numero_bastos += 1
    else:
        print("No es un palo disponible")

# Sacar cartas sucesivas con confirmación del usuario
validar_sacar_carta = True
while len(baraja) > 0 and validar_sacar_carta:
    sacar_carta(baraja)
    while True:
        continuar = input("Seguimos sacando cartas? si/no:").lower()
        if continuar == "si":
            print("Toma otra cartita")
            break
        elif continuar == "no":
            validar_sacar_carta = False 
            break
        else:
            print("Repite por favor")
print(f"Nº bastos: {numero_bastos}, nº copas: {numero_copas}, nº espadas: {numero_espadas}, nº oros: {numero_oros}")

# Creamos variables de todas las cartas de cada tipo de palo
cartas_oros = {carta for carta in baraja if carta[1] == "Oros"}
cartas_espadas = {carta for carta in baraja if carta[1] == "Espadas"}
carta_copas = {carta for carta in baraja if carta[1] == "Copas"}
carta_bastos = {carta for carta in baraja if carta[1] == "Bastos"}

# Operaciones con sets
cartas_oros_espadas = cartas_oros | cartas_espadas
print(f"1.Conjunto oros y espadas: {cartas_oros_espadas}")
interseccion_oros_espadas = cartas_oros & cartas_espadas
print(f"2.Intersección oros y espadas: {interseccion_oros_espadas}")
diferencia_oros_espadas = cartas_oros - cartas_espadas
print(f"3.Diferencia oros y espadas: {diferencia_oros_espadas}")
diferencia_asimetrica_oros_espadas = cartas_oros ^ cartas_espadas
print(f"4.Diferencia asimétrica oros y espadas: {diferencia_asimetrica_oros_espadas}")

# Función para buscar cartas específicas en la baraja
def buscar_cartas(baraja, valor=None, palo=None):
    # Filtrar por valor y/o palo
    if valor and palo:
        resultado = {carta for carta in baraja if carta == (valor, palo)}
    elif valor:
        resultado = {carta for carta in baraja if carta[0] == valor}
    elif palo:
        resultado = {carta for carta in baraja if carta[1] == palo}
    else:
        resultado = baraja

    return resultado

# Ejemplo de uso
print(f"Cartas con un As: {buscar_cartas(baraja, valor='As')}")
print(f"Cartas con los palos de Oros: {buscar_cartas(baraja, palo='Oros')}")
print(f"Saca el Rey de Espadas: {buscar_cartas(baraja, valor='Rey', palo='Espadas')}")

def calcular_probabilidad(baraja, valor=None, palo=None):
    if valor and palo:
        print(f"Cantidad de cartas totales: {len(baraja)}")
        probabilidad = 1/len(baraja)
    elif palo:
        cantidad_palos = {carta for carta in baraja if carta[1]==palo}
        print(f"Cantidad de {palo}: {len(cantidad_palos)}")
        print(f"Cantidad de cartas totales: {len(baraja)}")
        probabilidad = len(cantidad_palos) / len(baraja) 
    elif valor:
        cantidad_valores = {carta for carta in baraja if carta[0]==valor}
        print(f"Cantidad de {valor}: {len(cantidad_valores)}")
        print(f"Cantidad de cartas totales: {len(baraja)}")
        probabilidad = len(cantidad_valores) / len(baraja) 

    return probabilidad

print(f"Probabilidad Rey de Oros:{int(calcular_probabilidad(baraja, valor = 'Rey', palo = 'Oros')*100)}%")
print(f"Probabilidad de sacar cualquier carta de espadas:{int(calcular_probabilidad(baraja, palo='Espadas')*100)}%")
print(f"Probabilidad de sacar un Rey: {int(calcular_probabilidad(baraja, valor='Rey')*100)}%")
Scroll al inicio