{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "authorship_tag": "ABX9TyODboqZCX7e5Cwu/5wgGnhb",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/financieras/retos_python/blob/main/Cara_y_cruz.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Juego de Cara y Cruz"
      ],
      "metadata": {
        "id": "fxCuXrpQgWcn"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Solución 1 sin POO\n",
        "* Juego muy sencillo del tipo \"cero jugadores\" Se juega automáticamente\n",
        "* Se indica el número de jugadores, mínimo 2.\n",
        "* Se indica el número de rondas\n",
        "* En la línea 27 se usa un **Operador Ternario** (ternary conditional operator) que imprime la palabra punto o puntos según el número de puntos sean 1 o distinto de 1.   \n",
        "`'punto' if max_score==1 else 'puntos'`"
      ],
      "metadata": {
        "id": "TMB9Px3HjFPf"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "#@title Juego de Cara y Cruz sin POO\n",
        "import random\n",
        "random.seed()\n",
        "\n",
        "def coin_flip():\n",
        "    return random.choice(['cara', 'cruz'])\n",
        "\n",
        "def play_game(num_players, num_rounds):\n",
        "    scores = [0] * num_players      # inicializamos el vector de puntuaciones\n",
        "\n",
        "    for round in range(num_rounds):     # para cada ronda\n",
        "        print(f\"\\nRonda {round + 1}:\")    # print ronda\n",
        "        for player in range(num_players):   # para cada nº de jugador\n",
        "            result = coin_flip()            # lanzamos la moneda\n",
        "            if result == 'cara':            # si es cara\n",
        "                scores[player] += 1         # ganamos un punto\n",
        "            print(f\"Jugador {player + 1}: {result}\") # print jugador y resultado\n",
        "\n",
        "    print(\"\\nResultados finales:\")\n",
        "    for player in range(num_players):       # para cada nº de jugador\n",
        "        print(f\"Jugador {player + 1}: {scores[player]} puntos\") # print jugador+puntos\n",
        "\n",
        "    # vector de ganadores\n",
        "    winners = [str(i + 1) for i, score in enumerate(scores) if score == max(scores)]\n",
        "    max_score = max(scores)\n",
        "    if len(winners) == 1:\n",
        "        print(f\"\\nEl jugador {winners[0]} gana con {max_score} puntos!\")\n",
        "    else:\n",
        "        print(f\"\\nEmpate entre los jugadores {', '.join(winners[:-1])} y {winners[-1]} a {max_score} {'punto' if max_score==1 else 'puntos'}!\")\n",
        "if __name__ == \"__main__\":\n",
        "    # Configuración del juego\n",
        "    num_players = int(input(\"Ingrese el número de jugadores: \"))\n",
        "    num_rounds = int(input(\"Ingrese el número de rondas: \"))\n",
        "\n",
        "    # Jugar el juego\n",
        "    play_game(num_players, num_rounds)"
      ],
      "metadata": {
        "id": "AcnIs4Pig0Jr",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "25596ea3-e21f-4e5f-81fe-04f129d4d6b1"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Ingrese el número de jugadores: 10\n",
            "Ingrese el número de rondas: 3\n",
            "\n",
            "Ronda 1:\n",
            "Jugador 1: cara\n",
            "Jugador 2: cara\n",
            "Jugador 3: cara\n",
            "Jugador 4: cara\n",
            "Jugador 5: cara\n",
            "Jugador 6: cruz\n",
            "Jugador 7: cruz\n",
            "Jugador 8: cara\n",
            "Jugador 9: cara\n",
            "Jugador 10: cruz\n",
            "\n",
            "Ronda 2:\n",
            "Jugador 1: cruz\n",
            "Jugador 2: cara\n",
            "Jugador 3: cruz\n",
            "Jugador 4: cruz\n",
            "Jugador 5: cruz\n",
            "Jugador 6: cruz\n",
            "Jugador 7: cara\n",
            "Jugador 8: cruz\n",
            "Jugador 9: cruz\n",
            "Jugador 10: cruz\n",
            "\n",
            "Ronda 3:\n",
            "Jugador 1: cruz\n",
            "Jugador 2: cruz\n",
            "Jugador 3: cruz\n",
            "Jugador 4: cruz\n",
            "Jugador 5: cara\n",
            "Jugador 6: cruz\n",
            "Jugador 7: cara\n",
            "Jugador 8: cruz\n",
            "Jugador 9: cruz\n",
            "Jugador 10: cruz\n",
            "\n",
            "Resultados finales:\n",
            "Jugador 1: 1 puntos\n",
            "Jugador 2: 2 puntos\n",
            "Jugador 3: 1 puntos\n",
            "Jugador 4: 1 puntos\n",
            "Jugador 5: 2 puntos\n",
            "Jugador 6: 0 puntos\n",
            "Jugador 7: 2 puntos\n",
            "Jugador 8: 1 puntos\n",
            "Jugador 9: 1 puntos\n",
            "Jugador 10: 0 puntos\n",
            "\n",
            "Empate entre los jugadores 2, 5 y 7 a 2 puntos!\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Solución 2: con POO\n",
        "* Usando Programación Orientada a Objetos (POO)\n",
        "* Object Oriented Programming (OOP)\n",
        "* La clase `Player` encapsula la lógica de lanzar la moneda y llevar la cuenta de los puntos de cada jugador.\n",
        "* La clase `Game` se encarga de la lógica del juego, incluyendo la creación de los jugadores, el control de las rondas y la determinación del ganador.\n",
        "* La línea de código que permite enlazar las dos clases es:  \n",
        "`self.jugadores = [Player(i+1) for i in range(num_jugadores)]`  \n",
        "Se crea una lista con todos los objetos de los jugadores"
      ],
      "metadata": {
        "id": "qAGSQAfH0YIL"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "#@title Juego de Cara y Cruz con POO\n",
        "import random\n",
        "\n",
        "class Player:\n",
        "    def __init__(self, id):\n",
        "        self.id = id    # id: identificador númerico correlativo automático\n",
        "        self.puntos = 0 # inicializamos a cero los puntos del jugador\n",
        "\n",
        "    def __str__(self):\n",
        "        return f\"~ Jugador {self.id}.\"\n",
        "\n",
        "    def lanzar_moneda(self):\n",
        "        return random.choice(['cara', 'cruz'])\n",
        "\n",
        "    def incrementar_puntos(self):\n",
        "        self.puntos += 1\n",
        "\n",
        "\n",
        "class Game:\n",
        "    def __init__(self, num_jugadores, num_rondas):\n",
        "        self.jugadores = [Player(i+1) for i in range(num_jugadores)]\n",
        "        self.num_rondas = num_rondas\n",
        "        print(\"\\nLista de jugadores\")\n",
        "        for j in self.jugadores:\n",
        "            print(j)\n",
        "\n",
        "    def jugar(self):\n",
        "        for ronda in range(self.num_rondas):\n",
        "            print(f\"\\nRonda {ronda + 1}:\")\n",
        "            for jugador in self.jugadores:\n",
        "                resultado = jugador.lanzar_moneda()\n",
        "                if resultado == 'cara':\n",
        "                    jugador.incrementar_puntos()\n",
        "                print(f\"Jugador {jugador.id}: {resultado}\")\n",
        "\n",
        "        self.mostrar_resultados()\n",
        "\n",
        "    def mostrar_resultados(self):\n",
        "        print(\"\\nResultados finales:\")\n",
        "        for jugador in self.jugadores:\n",
        "            print(f\"» Jugador {jugador.id}: {jugador.puntos} puntos\")\n",
        "\n",
        "        max_puntos = max(jugador.puntos for jugador in self.jugadores)\n",
        "        ganadores = [str(j.id) for j in self.jugadores if j.puntos == max_puntos]\n",
        "\n",
        "        if len(ganadores) == 1:\n",
        "            print(f\"\\nEl jugador {', '.join(ganadores)} gana!\")\n",
        "        else:\n",
        "            print(f\"\\nHay un empate entre los jugadores {', '.join(ganadores)}!\")\n",
        "\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    # Configuración del juego\n",
        "    num_jugadores = int(input(\"Ingrese el número de jugadores: \"))\n",
        "    num_rondas = int(input(\"Ingrese el número de rondas: \"))\n",
        "\n",
        "    # Jugar el juego\n",
        "    game = Game(num_jugadores, num_rondas)\n",
        "    game.jugar()"
      ],
      "metadata": {
        "id": "C7dtu5tT28gW",
        "outputId": "e6e8a99d-43b0-493a-bc63-ba0cce0b072d",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Ingrese el número de jugadores: 3\n",
            "Ingrese el número de rondas: 3\n",
            "\n",
            "Lista de jugadores\n",
            "~ Jugador 1.\n",
            "~ Jugador 2.\n",
            "~ Jugador 3.\n",
            "\n",
            "Ronda 1:\n",
            "Jugador 1: cara\n",
            "Jugador 2: cruz\n",
            "Jugador 3: cara\n",
            "\n",
            "Ronda 2:\n",
            "Jugador 1: cara\n",
            "Jugador 2: cara\n",
            "Jugador 3: cruz\n",
            "\n",
            "Ronda 3:\n",
            "Jugador 1: cara\n",
            "Jugador 2: cruz\n",
            "Jugador 3: cara\n",
            "\n",
            "Resultados finales:\n",
            "» Jugador 1: 3 puntos\n",
            "» Jugador 2: 1 puntos\n",
            "» Jugador 3: 2 puntos\n",
            "\n",
            "El jugador 1 gana!\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Solución 3, con nobre de jugadores\n",
        "* Los jugadores se nombran usando letras mayúsculas del alfabeto\n",
        "* Mínimo 2 jugadores, máximo 26 jugadores"
      ],
      "metadata": {
        "id": "h_C0tCOv86uD"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import random\n",
        "\n",
        "class Player:\n",
        "    def __init__(self, name):\n",
        "        self.name = name\n",
        "        self.score = 0\n",
        "\n",
        "    def __str__(self):\n",
        "        return self.name\n",
        "\n",
        "    def flip_coin(self):\n",
        "        result = random.choice([\"heads\", \"tails\"])\n",
        "        if result == \"heads\":           # solo se obtiene punto si sale cara\n",
        "            self.score += 1\n",
        "            return True\n",
        "        return False\n",
        "\n",
        "class Game:\n",
        "    def __init__(self, num_players, num_rounds):\n",
        "        self.array_players = []         # array de objetos jugador\n",
        "        self.num_rounds = num_rounds\n",
        "\n",
        "        for i in range(num_players):\n",
        "            name = chr(ord('A') + i)    # uppercase letters of the alphabet\n",
        "            player = Player(name)       # instanciamos un jugador\n",
        "            self.array_players.append(player)\n",
        "\n",
        "    def show_players(self): # el array_players pasa a ser una lista de letras\n",
        "        name_players = [str(player) for player in self.array_players]\n",
        "        return \", \".join(name_players)\n",
        "\n",
        "    def play(self):\n",
        "        print()\n",
        "        for round in range(self.num_rounds):\n",
        "            print(f\"Round {round+1}, points for players: \", end=\"\")\n",
        "            for player in self.array_players:   # para cada jugador en el array\n",
        "                successful_player = player.flip_coin() # si es cara da True\n",
        "                if successful_player:           # si salió cara\n",
        "                    print(player, end=\" \") # se imprime la letra\n",
        "                    # sin el método __str__ habría que poner player.name\n",
        "            print()\n",
        "\n",
        "        self.show_ranking() # después de jugar todas las rondas: mostrar ranking\n",
        "\n",
        "    def show_ranking(self):\n",
        "        # ordenamos de mayor a menor puntuación el array de jugadores\n",
        "        self.array_players.sort(key=lambda player: player.score, reverse=True)\n",
        "        max_score = self.array_players[0].score\n",
        "\n",
        "        print(\"\\n=====  RANKING  =====\")\n",
        "        for player in self.array_players:\n",
        "            if player.score == max_score:\n",
        "                print(f\"{player.name}: {player.score} points (winner)\")\n",
        "            else:\n",
        "                print(f\"{player.name}: {player.score} points\")\n",
        "\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    num_players = int(input(\"Enter the number of players (2-26): \"))\n",
        "    num_rounds = int(input(\"Enter the number of rounds: \"))\n",
        "    game = Game(num_players, num_rounds)\n",
        "    print(f'Name of players: {game.show_players()}')\n",
        "    game.play()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "RlWKIJOx8-V9",
        "outputId": "2342a3a4-b732-4229-d0ef-228d9f99dc71"
      },
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Enter the number of players (2-26): 5\n",
            "Enter the number of rounds: 4\n",
            "Name of players: A, B, C, D, E\n",
            "\n",
            "Round 1, points for players: A B E \n",
            "Round 2, points for players: A C E \n",
            "Round 3, points for players: A C E \n",
            "Round 4, points for players: B C \n",
            "\n",
            "=====  RANKING  =====\n",
            "A: 3 points (winner)\n",
            "C: 3 points (winner)\n",
            "E: 3 points (winner)\n",
            "B: 2 points\n",
            "D: 0 points\n"
          ]
        }
      ]
    }
  ]
}