Pyscript game version
This commit is contained in:
parent
433984bfb2
commit
54cd9d838b
5 changed files with 257 additions and 79 deletions
|
@ -1,7 +1,9 @@
|
||||||
# Rock Paper Scissors Card Game
|
# Rock Paper Scissors Card Game
|
||||||
|
Play [now](https://codebymrfinchum.pyscriptapps.com/rock-paper-scissors-card-game/latest/).
|
||||||
|
|
||||||
A little game to play the classic Rock Paper Scissors game with a twist.
|
A little game to play the classic Rock Paper Scissors game with a twist.
|
||||||
Instead of freely selecting between Rock, Paper, and Scissors, you get a hand of three cards, potentially with only rocks.
|
Instead of freely selecting between Rock, Paper, and Scissors, you get a hand of three cards, potentially with only rocks.
|
||||||
It is a semi-random 52-card deck with an unbalanced distribution of cards, meaning some cards are less likely to occur. For example, only 5 out of 52 cards are stones, so it is very unlikely the other player has a stone. Selecting scissors gives a higher chance of winning.
|
It is a semi-random 52-card deck with an unbalanced distribution of cards, meaning some cards are less likely to occur. For example, only 5 out of 52 cards are stones, so it is very unlikely the other player has a stone. Selecting scissors gives a higher chance of winning.
|
||||||
|
|
||||||
This project is in its early stages. Some features are planned, but currently, it just runs in the terminal, and you can select cards. The *AI* selects a card completely at random. If there is a draw, you continue with the cards you started with. If one player wins, new cards are dealt.
|
At the moment, there are two versions: a Python version for local usage (terminal), `local.py`, and a PyScript version, `main.py`.
|
||||||
|
The PyScript version can actually be accessed and played [online](https://codebymrfinchum.pyscriptapps.com/rock-paper-scissors-card-game/) on my [PyScript profile](https://pyscript.com/@codebymrfinchum).
|
||||||
|
|
44
src/index.html
Normal file
44
src/index.html
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Rock Paper Scissors Card Game</title>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://pyscript.net/releases/2025.3.1/core.css"
|
||||||
|
/>
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://pyscript.net/releases/2025.3.1/core.js"
|
||||||
|
></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Rock Paper Scissors Card Game</h1>
|
||||||
|
<p>
|
||||||
|
Play Rock Paper Scissors with a twist! Use a 52-card deck with an
|
||||||
|
uneven distribution of cards. Both you and the AI get three cards,
|
||||||
|
and the AI selects randomly. The rules follow the classic game, but
|
||||||
|
with an added element of chance!
|
||||||
|
</p>
|
||||||
|
<p>Select a card to play against the AI! Best out of 5 game mode.</p>
|
||||||
|
|
||||||
|
<h3>Score</h3>
|
||||||
|
<p>
|
||||||
|
You: <span id="user-score">0</span> - AI:
|
||||||
|
<span id="ai-score">0</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="result">Waiting for your move...</h3>
|
||||||
|
|
||||||
|
<div id="card-buttons">
|
||||||
|
<button id="card-0" index="0" py-click="game.play_card">?</button>
|
||||||
|
<button id="card-1" index="1" py-click="game.play_card">?</button>
|
||||||
|
<button id="card-2" index="2" py-click="game.play_card">?</button>
|
||||||
|
</div>
|
||||||
|
<p></p>
|
||||||
|
<button id="reset-game" py-click="game.reset_game">Reset Game</button>
|
||||||
|
|
||||||
|
<script type="py" src="./main.py"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
98
src/local.py
Normal file
98
src/local.py
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import random
|
||||||
|
|
||||||
|
class RPSGame:
|
||||||
|
def __init__(self, best_of = 3):
|
||||||
|
self.deck = self.build_deck()
|
||||||
|
self.user_score = 0
|
||||||
|
self.ai_score = 0
|
||||||
|
self.rounds_to_win = (best_of // 2) + 1
|
||||||
|
|
||||||
|
def build_deck(self):
|
||||||
|
cards = [self.rock, self.paper, self.scissors]
|
||||||
|
deck = []
|
||||||
|
|
||||||
|
random.shuffle(cards)
|
||||||
|
for i in range(2):
|
||||||
|
n = random.randint(5, 20)
|
||||||
|
deck = cards[i](deck, n)
|
||||||
|
|
||||||
|
missing_cards = 52 - len(deck)
|
||||||
|
deck = cards[2](deck, missing_cards)
|
||||||
|
random.shuffle(deck)
|
||||||
|
return deck
|
||||||
|
|
||||||
|
def rock(self, lst, n):
|
||||||
|
lst.extend(["Rock"] * n)
|
||||||
|
return lst
|
||||||
|
|
||||||
|
def paper(self, lst, n):
|
||||||
|
lst.extend(["Paper"] * n)
|
||||||
|
return lst
|
||||||
|
|
||||||
|
def scissors(self, lst, n):
|
||||||
|
lst.extend(["Scissors"] * n)
|
||||||
|
return lst
|
||||||
|
|
||||||
|
def give_cards(self):
|
||||||
|
return [self.deck.pop(0) for _ in range(3)], [self.deck.pop(0) for _ in range(3)]
|
||||||
|
|
||||||
|
def battle(self, user_card, ai_card):
|
||||||
|
if user_card == ai_card:
|
||||||
|
return 0
|
||||||
|
if (user_card == "Rock" and ai_card == "Scissors") or \
|
||||||
|
(user_card == "Paper" and ai_card == "Rock") or \
|
||||||
|
(user_card == "Scissors" and ai_card == "Paper"):
|
||||||
|
return 1
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def play_cards(self, user_hand, ai_hand):
|
||||||
|
while user_hand and ai_hand:
|
||||||
|
print(f"\nYour cards: {user_hand}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
user_choice = int(input(f"Select a card (1-{len(user_hand)}): ")) - 1
|
||||||
|
if 0 <= user_choice < len(user_hand):
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
print("Invalid choice. Try again.")
|
||||||
|
|
||||||
|
user_card = user_hand.pop(user_choice)
|
||||||
|
ai_card = ai_hand.pop(random.randint(0, len(ai_hand) - 1))
|
||||||
|
|
||||||
|
print(f"You played: {user_card}, AI played: {ai_card}")
|
||||||
|
|
||||||
|
result = self.battle(user_card, ai_card)
|
||||||
|
if result == 1:
|
||||||
|
print("You win this round!")
|
||||||
|
return 1
|
||||||
|
elif result == -1:
|
||||||
|
print("AI wins this round!")
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
print("It's a tie! Play again with remaining cards.")
|
||||||
|
|
||||||
|
print("No cards left, this round is a draw.")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def play_game(self):
|
||||||
|
while self.user_score < self.rounds_to_win and self.ai_score < self.rounds_to_win and len(self.deck) >= 6:
|
||||||
|
user_hand, ai_hand = self.give_cards()
|
||||||
|
round_result = self.play_cards(user_hand, ai_hand)
|
||||||
|
|
||||||
|
if round_result == 1:
|
||||||
|
self.user_score += 1
|
||||||
|
elif round_result == -1:
|
||||||
|
self.ai_score += 1
|
||||||
|
|
||||||
|
print(f"Score - You: {self.user_score}, AI: {self.ai_score}")
|
||||||
|
|
||||||
|
if self.user_score > self.ai_score:
|
||||||
|
print("\n🎉 You won the match!")
|
||||||
|
else:
|
||||||
|
print("\n🤖 AI won the match!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
game = RPSGame(best_of = 3)
|
||||||
|
game.play_game()
|
189
src/main.py
189
src/main.py
|
@ -1,103 +1,136 @@
|
||||||
import random
|
import random
|
||||||
|
from pyscript import document
|
||||||
|
|
||||||
def rock(lst, n):
|
class RPSGame:
|
||||||
for _ in range(n):
|
def __init__(self, best_of = 3):
|
||||||
lst.append("Rock")
|
self.user_score = 0
|
||||||
return lst
|
self.ai_score = 0
|
||||||
|
self.deck = self.build_deck()
|
||||||
|
self.user_hand, self.ai_hand = self.give_cards()
|
||||||
|
self.rounds_to_win = (best_of // 2) + 1
|
||||||
|
self.update_ui()
|
||||||
|
|
||||||
def paper(lst, n):
|
def build_deck(self):
|
||||||
for _ in range(n):
|
cards = [self.rock, self.paper, self.scissors]
|
||||||
lst.append("Paper")
|
deck = []
|
||||||
return lst
|
|
||||||
|
|
||||||
def scissors(lst, n):
|
random.shuffle(cards)
|
||||||
for _ in range(n):
|
for i in range(2):
|
||||||
lst.append("Scissors")
|
n = random.randint(5, 20)
|
||||||
return lst
|
deck = cards[i](deck, n)
|
||||||
|
|
||||||
def build_deck():
|
missing_cards = 52 - len(deck)
|
||||||
cards = [rock, paper, scissors]
|
deck = cards[2](deck, missing_cards)
|
||||||
deck = []
|
random.shuffle(deck)
|
||||||
|
return deck
|
||||||
|
|
||||||
random.shuffle(cards)
|
def rock(self, lst, n):
|
||||||
for i in range(2):
|
lst.extend(["Rock"] * n)
|
||||||
n = random.randint(5, 20)
|
return lst
|
||||||
deck = cards[i](deck, n)
|
|
||||||
|
|
||||||
missing_cards = 52 - len(deck)
|
def paper(self, lst, n):
|
||||||
deck = cards[2](deck, missing_cards)
|
lst.extend(["Paper"] * n)
|
||||||
random.shuffle(deck)
|
return lst
|
||||||
return deck
|
|
||||||
|
|
||||||
def give_cards(deck):
|
def scissors(self, lst, n):
|
||||||
"""Give 3 cards to both player and AI, removing them from the deck."""
|
lst.extend(["Scissors"] * n)
|
||||||
return [deck.pop(0) for _ in range(3)], [deck.pop(0) for _ in range(3)]
|
return lst
|
||||||
|
|
||||||
def battle(user_card, ai_card):
|
def give_cards(self):
|
||||||
"""Returns 1 if user wins, -1 if AI wins, 0 for a tie."""
|
return [self.deck.pop(0) for _ in range(3)], [self.deck.pop(0) for _ in range(3)]
|
||||||
if user_card == ai_card:
|
|
||||||
return 0
|
|
||||||
if (user_card == "Rock" and ai_card == "Scissors") or \
|
|
||||||
(user_card == "Paper" and ai_card == "Rock") or \
|
|
||||||
(user_card == "Scissors" and ai_card == "Paper"):
|
|
||||||
return 1
|
|
||||||
return -1
|
|
||||||
|
|
||||||
def play_cards(user_hand, ai_hand):
|
def battle(self, user_card, ai_card):
|
||||||
"""Handles playing cards until a winner is determined or cards run out."""
|
if user_card == ai_card:
|
||||||
while user_hand and ai_hand: # Keep playing until hands are empty
|
return 0
|
||||||
print(f"\nYour cards: {user_hand}")
|
if (user_card == "Rock" and ai_card == "Scissors") or \
|
||||||
|
(user_card == "Paper" and ai_card == "Rock") or \
|
||||||
|
(user_card == "Scissors" and ai_card == "Paper"):
|
||||||
|
return 1
|
||||||
|
return -1
|
||||||
|
|
||||||
while True:
|
def refresh_hand(self):
|
||||||
try:
|
self.user_hand, self.ai_hand = self.give_cards()
|
||||||
user_choice = int(input(f"Select a card (1-{len(user_hand)}): ")) - 1
|
print("New cards")
|
||||||
if 0 <= user_choice < len(user_hand):
|
print(f"AI cards: {self.ai_hand}")
|
||||||
break
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
print("Invalid choice. Try again.")
|
|
||||||
|
|
||||||
user_card = user_hand.pop(user_choice)
|
def play_card(self, event):
|
||||||
ai_choice = random.randint(0, len(ai_hand) - 1)
|
index = int(event.target.getAttribute("index"))
|
||||||
ai_card = ai_hand.pop(ai_choice)
|
#print(f"Button {index} clicked!") # Debugging
|
||||||
|
if index >= len(self.user_hand):
|
||||||
|
return
|
||||||
|
|
||||||
print(f"You played: {user_card}, AI played: {ai_card}")
|
user_card = self.user_hand.pop(index)
|
||||||
|
ai_card = self.ai_hand.pop(random.randint(0, len(self.ai_hand) - 1))
|
||||||
|
|
||||||
result = battle(user_card, ai_card)
|
result = self.battle(user_card, ai_card)
|
||||||
if result == 1:
|
if result == 1:
|
||||||
print("You win this round!")
|
self.user_score += 1
|
||||||
return 1 # User wins
|
round_result = f"You win! {user_card} beats {ai_card}."
|
||||||
|
self.refresh_hand()
|
||||||
elif result == -1:
|
elif result == -1:
|
||||||
print("AI wins this round!")
|
self.ai_score += 1
|
||||||
return -1 # AI wins
|
round_result = f"AI wins! {ai_card} beats {user_card}."
|
||||||
|
self.refresh_hand()
|
||||||
else:
|
else:
|
||||||
print("It's a tie! Play again with remaining cards.")
|
round_result = "It's a tie! Try again"
|
||||||
|
|
||||||
print("No cards left, this round is a draw.")
|
if not self.user_hand or not self.ai_hand:
|
||||||
return 0 # Round is a draw
|
self.refresh_hand()
|
||||||
|
if self.user_score < self.rounds_to_win and self.ai_score < self.rounds_to_win:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if self.user_score < self.ai_score:
|
||||||
|
round_result = "You lost noob D:"
|
||||||
|
self.update_ui(round_result)
|
||||||
|
self.disable_buttons()
|
||||||
|
#self.reset_game()
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
round_result = "You won great :D"
|
||||||
|
self.update_ui(round_result)
|
||||||
|
self.disable_buttons()
|
||||||
|
#self.reset_game()
|
||||||
|
return
|
||||||
|
|
||||||
def play_game(best_of = 3):
|
self.update_ui(round_result)
|
||||||
"""Main game loop."""
|
|
||||||
my_deck = build_deck()
|
|
||||||
user_score, ai_score = 0, 0
|
|
||||||
rounds_to_win = (best_of // 2) + 1
|
|
||||||
|
|
||||||
while user_score < rounds_to_win and ai_score < rounds_to_win and len(my_deck) >= 6:
|
def update_ui(self, result_text="Waiting for your move..."):
|
||||||
user_hand, ai_hand = give_cards(my_deck)
|
print("Update UI")
|
||||||
|
document.querySelector("#user-score").innerText = str(self.user_score)
|
||||||
|
document.querySelector("#ai-score").innerText = str(self.ai_score)
|
||||||
|
document.querySelector("#result").innerText = result_text
|
||||||
|
document.querySelector("#reset-game").disabled = False
|
||||||
|
for i in range(3):
|
||||||
|
btn = document.querySelector(f"#card-{i}")
|
||||||
|
if i < len(self.user_hand):
|
||||||
|
btn.innerText = self.user_hand[i]
|
||||||
|
btn.disabled = False
|
||||||
|
else:
|
||||||
|
btn.innerText = "?"
|
||||||
|
btn.disabled = True
|
||||||
|
|
||||||
round_result = play_cards(user_hand, ai_hand)
|
def disable_buttons(self):
|
||||||
|
for i in range(3):
|
||||||
|
btn = document.querySelector(f"#card-{i}")
|
||||||
|
btn.innerText = "?"
|
||||||
|
btn.disabled = True
|
||||||
|
|
||||||
if round_result == 1:
|
def reset_game(self, event=None):
|
||||||
user_score += 1
|
print("Game Reset")
|
||||||
elif round_result == -1:
|
self.user_score = 0
|
||||||
ai_score += 1
|
self.ai_score = 0
|
||||||
|
self.deck = self.build_deck()
|
||||||
|
self.user_hand, self.ai_hand = self.give_cards()
|
||||||
|
self.deck_overview()
|
||||||
|
self.update_ui("Game reset! Pick a card to start.")
|
||||||
|
|
||||||
print(f"Score - You: {user_score}, AI: {ai_score}")
|
|
||||||
|
|
||||||
if user_score > ai_score:
|
def deck_overview(self):
|
||||||
print("\n🎉 You won the match!")
|
#print(f"{len(self.deck)} Cards left")
|
||||||
else:
|
print(f"{self.deck.count('Rock')} Rock cards")
|
||||||
print("\n🤖 AI won the match!")
|
print(f"{self.deck.count('Paper')} Paper cards")
|
||||||
|
print(f"{self.deck.count('Scissors')} Scissors cards")
|
||||||
|
|
||||||
# Run the game
|
# Start the game
|
||||||
play_game(best_of = 5)
|
game = RPSGame(5)
|
||||||
|
game.deck_overview()
|
||||||
|
|
1
src/pyscript.toml
Normal file
1
src/pyscript.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
name = "Rock Paper Scissors"
|
Loading…
Add table
Add a link
Reference in a new issue