diff --git a/assets/paper.png b/assets/paper.png new file mode 100644 index 0000000..29d3d34 Binary files /dev/null and b/assets/paper.png differ diff --git a/assets/rock.png b/assets/rock.png new file mode 100644 index 0000000..1c8ca9e Binary files /dev/null and b/assets/rock.png differ diff --git a/assets/scissors.png b/assets/scissors.png new file mode 100644 index 0000000..b154870 Binary files /dev/null and b/assets/scissors.png differ diff --git a/mobile-stone-paper-scissors.py b/mobile-stone-paper-scissors.py new file mode 100644 index 0000000..940dc97 --- /dev/null +++ b/mobile-stone-paper-scissors.py @@ -0,0 +1,166 @@ +from kivy.app import App +from kivy.lang import Builder +from kivy.uix.screenmanager import ScreenManager, Screen +from kivy.properties import StringProperty, NumericProperty, ListProperty +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.image import Image +from datetime import datetime +import random +import json +import os + + +class ImageButton(ButtonBehavior, Image): + pass + + +MOVES = {'R': 'Rock', 'P': 'Paper', 'S': 'Scissors'} + + +class HomeScreen(Screen): + pass + + +class GameScreen(Screen): + result_text = StringProperty("") + result_bg_color = ListProperty([1, 1, 1, 1]) + + wins = NumericProperty(0) + losses = NumericProperty(0) + ties = NumericProperty(0) + streak = NumericProperty(0) + + def on_pre_enter(self): + self.load_data() + self.update_stats() + + def adaptive_ai(self): + if len(self.manager.history) < 3: + return random.choice(['R', 'P', 'S']) + last_moves = [h['player'] for h in self.manager.history[-3:]] + most_common = max(set(last_moves), key=last_moves.count) + counter = {'R': 'P', 'P': 'S', 'S': 'R'} + return counter[most_common] + + def play(self, user_move): + computer_move = self.adaptive_ai() + result = self.determine_winner(user_move, computer_move) + self.manager.history.append({ + 'time': datetime.now().strftime("%Y-%m-%d %H:%M"), + 'player': user_move, + 'computer': computer_move, + 'result': result + }) + + feedback = { + 'win': ("You Win!", [0.36, 0.85, 0.35, 1]), + 'loss': ("Computer Wins!", [0.95, 0.42, 0.42, 1]), + 'tie': ("It's a Draw!", [0.99, 0.85, 0.24, 1]) + } + text, color = feedback[result] + self.result_text = f"{MOVES[user_move]} vs {MOVES[computer_move]} — {text}" + self.result_bg_color = color + self.update_stats() + self.save_data() + + def determine_winner(self, player, computer): + if player == computer: + self.ties += 1 + self.streak = 0 + return 'tie' + elif (player == 'R' and computer == 'S') or \ + (player == 'P' and computer == 'R') or \ + (player == 'S' and computer == 'P'): + self.wins += 1 + self.streak += 1 + return 'win' + else: + self.losses += 1 + self.streak = 0 + return 'loss' + + def update_stats(self): + total = self.wins + self.losses + self.ties + win_rate = (self.wins / total * 100) if total > 0 else 0 + self.ids.stats_label.text = f"Wins: {self.wins} Losses: {self.losses} Ties: {self.ties}\nStreak: {self.streak} Win Rate: {win_rate:.1f}%" + + def load_data(self): + if os.path.exists('rps_kivy_save.json'): + try: + with open('rps_kivy_save.json', 'r') as f: + data = json.load(f) + self.wins = data.get('wins', 0) + self.losses = data.get('losses', 0) + self.ties = data.get('ties', 0) + self.streak = data.get('streak', 0) + self.manager.history = data.get('history', []) + except: + pass + + def save_data(self): + data = { + 'wins': self.wins, + 'losses': self.losses, + 'ties': self.ties, + 'streak': self.streak, + 'history': self.manager.history + } + with open('rps_kivy_save.json', 'w') as f: + json.dump(data, f) + + def reset_game(self): + self.wins = self.losses = self.ties = self.streak = 0 + self.manager.history = [] + self.update_stats() + self.result_text = "" + self.result_bg_color = [1, 1, 1, 1] + self.save_data() + + +class HistoryScreen(Screen): + def on_pre_enter(self): + self.ids.history_text.text = "\n".join([ + f"{h['time']} | {MOVES[h['player']]} vs {MOVES[h['computer']]} : {h['result'].capitalize()}" + for h in self.manager.history[-10:] + ]) or "No history yet." + + +class LeaderboardScreen(Screen): + def on_pre_enter(self): + gs = self.manager.get_screen('game') + max_streak = 0 + current_streak = 0 + for h in self.manager.history: + if h['result'] == 'win': + current_streak += 1 + max_streak = max(max_streak, current_streak) + else: + current_streak = 0 + total = len(self.manager.history) + win_rate = (gs.wins / total * 100) if total > 0 else 0 + + self.ids.leaderboard_label.text = f""" +Total Games: {total} +Wins: {gs.wins} +Losses: {gs.losses} +Ties: {gs.ties} +Longest Win Streak: {max_streak} +Current Streak: {gs.streak} +Win Rate: {win_rate:.1f}% + """ + + +class RPSApp(App): + def build(self): + Builder.load_file('rps.kv') + sm = ScreenManager() + sm.history = [] + sm.add_widget(HomeScreen(name='home')) + sm.add_widget(GameScreen(name='game')) + sm.add_widget(HistoryScreen(name='history')) + sm.add_widget(LeaderboardScreen(name='leaderboard')) + return sm + + +if __name__ == '__main__': + RPSApp().run() diff --git a/rps.kv b/rps.kv new file mode 100644 index 0000000..d524c63 --- /dev/null +++ b/rps.kv @@ -0,0 +1,164 @@ +#:import Window kivy.core.window.Window +#:import dp kivy.metrics.dp +#:import FadeTransition kivy.uix.screenmanager.FadeTransition +#:import ImageButton mobile-stone-paper-scissors.ImageButton + +ScreenManager: + transition: FadeTransition() + HomeScreen: + GameScreen: + HistoryScreen: + LeaderboardScreen: + +: + name: "home" + BoxLayout: + orientation: 'vertical' + padding: dp(20) + spacing: dp(20) + canvas.before: + Color: + rgba: .1, .1, .1, 1 + Rectangle: + pos: self.pos + size: self.size + Label: + text: "Rock Paper Scissors" + font_size: Window.width / 15 + color: 1, 1, 1, 1 + Button: + text: "Start Game" + font_size: Window.width / 25 + size_hint_y: None + height: dp(60) + on_press: root.manager.current = "game" + Button: + text: "Quit" + font_size: Window.width / 25 + size_hint_y: None + height: dp(60) + on_press: app.stop() + +: + name: "game" + BoxLayout: + orientation: 'vertical' + padding: dp(20) + spacing: dp(20) + canvas.before: + Color: + rgba: 0.05, 0.05, 0.05, 1 + Rectangle: + pos: self.pos + size: self.size + Label: + id: stats_label + text: "" + font_size: Window.width / 30 + color: 1, 1, 1, 1 + GridLayout: + cols: 3 + spacing: dp(15) + size_hint_y: None + height: dp(180) + + ImageButton: + source: "assets/rock.png" + on_release: root.play('R') + + ImageButton: + source: "assets/paper.png" + on_release: root.play('P') + + ImageButton: + source: "assets/scissors.png" + on_release: root.play('S') + + Label: + text: root.result_text + font_size: Window.width / 30 + color: 1, 1, 1, 1 + size_hint_y: None + height: dp(120) + canvas.before: + Color: + rgba: root.result_bg_color + RoundedRectangle: + pos: self.pos + size: self.size + radius: [20,] + BoxLayout: + size_hint_y: None + height: dp(50) + spacing: dp(10) + Button: + text: "History" + on_press: root.manager.current = "history" + Button: + text: "Leaderboard" + on_press: root.manager.current = "leaderboard" + Button: + text: "Reset" + on_press: root.reset_game() + Button: + text: "Back to Home" + size_hint_y: None + height: dp(50) + on_press: root.manager.current = "home" + +: + name: "history" + BoxLayout: + orientation: 'vertical' + padding: dp(20) + spacing: dp(20) + canvas.before: + Color: + rgba: 0.1, 0.1, 0.1, 1 + Rectangle: + pos: self.pos + size: self.size + Label: + text: "Last 10 Matches" + font_size: Window.width / 20 + color: 1, 1, 1, 1 + ScrollView: + Label: + id: history_text + size_hint_y: None + height: self.texture_size[1] + text_size: self.width, None + font_size: Window.width / 35 + color: 1, 1, 1, 1 + Button: + text: "Back" + size_hint_y: None + height: dp(50) + on_press: root.manager.current = "game" + +: + name: "leaderboard" + BoxLayout: + orientation: 'vertical' + padding: dp(20) + spacing: dp(20) + canvas.before: + Color: + rgba: 0.1, 0.1, 0.1, 1 + Rectangle: + pos: self.pos + size: self.size + Label: + text: "Leaderboard" + font_size: Window.width / 20 + color: 1, 1, 1, 1 + Label: + id: leaderboard_label + text: "" + font_size: Window.width / 35 + color: 1, 1, 1, 1 + Button: + text: "Back" + size_hint_y: None + height: dp(50) + on_press: root.manager.current = "game" diff --git a/snake game/snake_game.py b/snake game/snake_game.py new file mode 100644 index 0000000..d8934e0 --- /dev/null +++ b/snake game/snake_game.py @@ -0,0 +1,160 @@ +import tkinter as tk +import random +import json +import os + +CELL_SIZE = 20 +GRID_WIDTH = 25 +GRID_HEIGHT = 25 +UPDATE_DELAY = 100 # ms + +SAVE_FILE = 'snake_game_save.json' + +class SnakeGame: + def __init__(self, root): + self.root = root + self.root.title("🐍 Snake Game Deluxe 🐍") + self.root.resizable(False, False) + + self.canvas = tk.Canvas(root, width=CELL_SIZE * GRID_WIDTH, + height=CELL_SIZE * GRID_HEIGHT, bg="#1e1e1e", bd=0, highlightthickness=0) + self.canvas.pack() + + self.score = 0 + self.high_score = 0 + self.snake = [(5, 5)] + self.direction = (1, 0) + self.food = None + self.game_running = False + + self.load_data() + self.draw_ui() + self.reset_game() + + self.root.bind("", self.change_direction) + + def draw_ui(self): + self.top_frame = tk.Frame(self.root, bg="#282c34") + self.top_frame.pack(fill="x") + + self.score_label = tk.Label(self.top_frame, text="Score: 0", fg="white", bg="#282c34", + font=("Consolas", 14, "bold")) + self.score_label.pack(side="left", padx=10) + + self.high_score_label = tk.Label(self.top_frame, text=f"High Score: {self.high_score}", fg="white", + bg="#282c34", font=("Consolas", 14, "bold")) + self.high_score_label.pack(side="right", padx=10) + + self.reset_button = tk.Button(self.top_frame, text="🔁 Restart", command=self.reset_game, + bg="#61afef", fg="white", font=("Consolas", 12, "bold"), bd=0, relief="flat") + self.reset_button.pack(side="left", padx=10) + + def load_data(self): + if os.path.exists(SAVE_FILE): + try: + with open(SAVE_FILE, 'r') as f: + data = json.load(f) + self.high_score = data.get("high_score", 0) + except: + self.high_score = 0 + + def save_data(self): + with open(SAVE_FILE, 'w') as f: + json.dump({"high_score": self.high_score}, f) + + def reset_game(self): + self.snake = [(5, 5)] + self.direction = (1, 0) + self.score = 0 + self.game_running = True + self.spawn_food() + self.update_ui() + self.game_loop() + + def spawn_food(self): + while True: + x = random.randint(0, GRID_WIDTH - 1) + y = random.randint(0, GRID_HEIGHT - 1) + if (x, y) not in self.snake: + self.food = (x, y) + break + + def change_direction(self, event): + key = event.keysym + new_dir = { + 'Up': (0, -1), + 'Down': (0, 1), + 'Left': (-1, 0), + 'Right': (1, 0) + }.get(key) + + if new_dir: + opposite = (-self.direction[0], -self.direction[1]) + if new_dir != opposite: # Prevent reversing + self.direction = new_dir + + def game_loop(self): + if not self.game_running: + return + + head_x, head_y = self.snake[-1] + dx, dy = self.direction + new_head = (head_x + dx, head_y + dy) + + if (new_head in self.snake or + new_head[0] < 0 or new_head[0] >= GRID_WIDTH or + new_head[1] < 0 or new_head[1] >= GRID_HEIGHT): + self.end_game() + return + + self.snake.append(new_head) + + if new_head == self.food: + self.score += 1 + self.spawn_food() + else: + self.snake.pop(0) + + self.update_ui() + self.root.after(UPDATE_DELAY, self.game_loop) + + def update_ui(self): + self.canvas.delete("all") + + # Draw snake + for segment in self.snake: + x1 = segment[0] * CELL_SIZE + y1 = segment[1] * CELL_SIZE + x2 = x1 + CELL_SIZE + y2 = y1 + CELL_SIZE + self.canvas.create_rectangle(x1, y1, x2, y2, fill="#98c379", outline="#1e1e1e") + + # Draw head with highlight + hx, hy = self.snake[-1] + self.canvas.create_rectangle(hx * CELL_SIZE, hy * CELL_SIZE, + hx * CELL_SIZE + CELL_SIZE, hy * CELL_SIZE + CELL_SIZE, + fill="#e06c75", outline="#1e1e1e") + + # Draw food + fx, fy = self.food + self.canvas.create_oval(fx * CELL_SIZE, fy * CELL_SIZE, + fx * CELL_SIZE + CELL_SIZE, fy * CELL_SIZE + CELL_SIZE, + fill="#d19a66", outline="#1e1e1e") + + self.score_label.config(text=f"Score: {self.score}") + + def end_game(self): + self.game_running = False + if self.score > self.high_score: + self.high_score = self.score + self.save_data() + self.high_score_label.config(text=f"High Score: {self.high_score}") + self.canvas.create_text(CELL_SIZE * GRID_WIDTH // 2, + CELL_SIZE * GRID_HEIGHT // 2, + text="Game Over", fill="white", + font=("Consolas", 24, "bold")) + +if __name__ == "__main__": + root = tk.Tk() + app = SnakeGame(root) + root.mainloop() diff --git a/snake game/snake_game_save.json b/snake game/snake_game_save.json new file mode 100644 index 0000000..1480e41 --- /dev/null +++ b/snake game/snake_game_save.json @@ -0,0 +1 @@ +{"high_score": 3} \ No newline at end of file diff --git a/stone-paper-scissors.py b/stone-paper-scissors.py new file mode 100644 index 0000000..ac04aab --- /dev/null +++ b/stone-paper-scissors.py @@ -0,0 +1,210 @@ +import tkinter as tk +import random +import json +import os +from datetime import datetime + +MOVES = {'R': 'Rock 🪨', 'P': 'Paper 📄', 'S': 'Scissors ✂️'} + +class RPSGame: + def __init__(self, root): + self.root = root + self.root.title("🎉 Rock Paper Scissors Ultimate 🎉") + self.root.geometry("500x600") + self.root.configure(bg="#FFFAE3") + + self.wins = 0 + self.losses = 0 + self.ties = 0 + self.streak = 0 + self.history = [] + self.load_data() + + self.build_ui() + + def build_ui(self): + tk.Label(self.root, text="ROCK PAPER SCISSORS!", font=("Comic Sans MS", 28, "bold"), + bg="#FFFAE3", fg="#FF6B6B").pack(pady=20) + + self.stats_label = tk.Label(self.root, font=("Comic Sans MS", 14), + bg="#FFFAE3", fg="#444") + self.stats_label.pack(pady=10) + + self.result_label = tk.Label(self.root, font=("Comic Sans MS", 20, "bold"), + width=30, height=2, bg="#FFFAE3") + self.result_label.pack(pady=20) + + btn_frame = tk.Frame(self.root, bg="#FFFAE3") + btn_frame.pack(pady=20) + + rock_btn = tk.Button(btn_frame, text="🪨 Rock", command=lambda: self.play('R')) + paper_btn = tk.Button(btn_frame, text="📄 Paper", command=lambda: self.play('P')) + scissors_btn = tk.Button(btn_frame, text="✂️ Scissors", command=lambda: self.play('S')) + + for btn in (rock_btn, paper_btn, scissors_btn): + btn.config(font=("Comic Sans MS", 14, "bold"), + bg="#FFD93D", fg="#444", + activebackground="#FF6B6B", activeforeground="#fff", + width=10, height=2, bd=4, relief="groove", cursor="hand2") + btn.pack(side="left", padx=15) + + tk.Button(self.root, text="📋 View History", command=self.show_history, + font=("Comic Sans MS", 12), bg="#5CD859", fg="white", + width=20, height=2).pack(pady=10) + + tk.Button(self.root, text="🏆 View Leaderboard", command=self.show_leaderboard, + font=("Comic Sans MS", 12), bg="#FF6B6B", fg="white", + width=20, height=2).pack(pady=10) + + tk.Button(self.root, text="🔄 Reset Stats", command=self.reset_game, + font=("Comic Sans MS", 12), bg="#FFD93D", fg="#444", + width=20, height=2).pack(pady=10) + + tk.Button(self.root, text="🚪 Quit", command=self.quit_game, + font=("Comic Sans MS", 12), bg="#FF6B6B", fg="white", + width=20, height=2).pack(pady=10) + + self.update_stats() + + def load_data(self): + if os.path.exists('rps_gui_save.json'): + try: + with open('rps_gui_save.json', 'r') as f: + data = json.load(f) + self.wins = data.get('wins', 0) + self.losses = data.get('losses', 0) + self.ties = data.get('ties', 0) + self.streak = data.get('streak', 0) + self.history = data.get('history', []) + except: + pass + + def save_data(self): + data = { + 'wins': self.wins, + 'losses': self.losses, + 'ties': self.ties, + 'streak': self.streak, + 'history': self.history + } + with open('rps_gui_save.json', 'w') as f: + json.dump(data, f) + + def adaptive_ai(self): + if len(self.history) < 3: + return random.choice(['R', 'P', 'S']) + last_moves = [h['player'] for h in self.history[-3:]] + most_common = max(set(last_moves), key=last_moves.count) + counter = {'R': 'P', 'P': 'S', 'S': 'R'} + return counter[most_common] + + def play(self, user_move): + computer_move = self.adaptive_ai() + result = self.determine_winner(user_move, computer_move) + + self.history.append({ + 'time': datetime.now().strftime("%Y-%m-%d %H:%M"), + 'player': user_move, + 'computer': computer_move, + 'result': result + }) + + feedback = { + 'win': ("You Win! 🥳", "#5CD859"), + 'loss': ("Computer Wins! 😝", "#FF6B6B"), + 'tie': ("It's a Draw! 🤝", "#FFD93D") + } + + text, color = feedback[result] + self.result_label.config(text=f"{MOVES[user_move]} vs {MOVES[computer_move]} — {text}", bg=color) + self.update_stats() + self.save_data() + + def determine_winner(self, player, computer): + if player == computer: + self.ties += 1 + self.streak = 0 + return 'tie' + elif (player == 'R' and computer == 'S') or \ + (player == 'P' and computer == 'R') or \ + (player == 'S' and computer == 'P'): + self.wins += 1 + self.streak += 1 + return 'win' + else: + self.losses += 1 + self.streak = 0 + return 'loss' + + def update_stats(self): + total = self.wins + self.losses + self.ties + win_rate = (self.wins / total * 100) if total > 0 else 0 + self.stats_label.config( + text=f"Wins: {self.wins} Losses: {self.losses} Ties: {self.ties}\n" + f"Streak: {self.streak} Win Rate: {win_rate:.1f}%" + ) + + def show_history(self): + history_window = tk.Toplevel(self.root) + history_window.title("📋 Game History") + history_window.configure(bg="#FFFAE3") + + tk.Label(history_window, text="Last 10 Matches", font=("Comic Sans MS", 16, "bold"), + bg="#FFFAE3").pack(pady=10) + + text = tk.Text(history_window, width=50, height=15, bg="#fff", font=("Comic Sans MS", 12)) + text.pack(padx=10, pady=10) + + for h in self.history[-10:]: + result = "Win" if h['result'] == 'win' else "Loss" if h['result'] == 'loss' else "Tie" + text.insert(tk.END, f"{h['time']}: You chose {MOVES[h['player']]}, Computer chose {MOVES[h['computer']]} — {result}\n") + + text.config(state='disabled') + + def show_leaderboard(self): + leaderboard_window = tk.Toplevel(self.root) + leaderboard_window.title("🏆 Leaderboard") + leaderboard_window.configure(bg="#FFFAE3") + + max_streak = 0 + current_streak = 0 + for h in self.history: + if h['result'] == 'win': + current_streak += 1 + max_streak = max(max_streak, current_streak) + else: + current_streak = 0 + + total_games = len(self.history) + win_rate = (self.wins / total_games * 100) if total_games > 0 else 0 + + tk.Label(leaderboard_window, text="Your Leaderboard", font=("Comic Sans MS", 16, "bold"), + bg="#FFFAE3").pack(pady=10) + + stats = f""" + Total Games: {total_games} + Wins: {self.wins} + Losses: {self.losses} + Ties: {self.ties} + Longest Win Streak: {max_streak} + Current Win Streak: {self.streak} + Win Rate: {win_rate:.1f}% + """ + tk.Label(leaderboard_window, text=stats.strip(), justify='left', + bg="#FFFAE3", font=("Comic Sans MS", 12)).pack(pady=20) + + def reset_game(self): + self.wins = self.losses = self.ties = self.streak = 0 + self.history = [] + self.update_stats() + self.result_label.config(text="", bg="#FFFAE3") + self.save_data() + + def quit_game(self): + self.save_data() + self.root.quit() + + +root = tk.Tk() +app = RPSGame(root) +root.mainloop() diff --git a/stone-paper-sssc.py b/stone-paper-sssc.py deleted file mode 100644 index 47c766f..0000000 --- a/stone-paper-sssc.py +++ /dev/null @@ -1,59 +0,0 @@ -import random, sys - -print("Let's Play ROCK PAPER SCISSORS GAME!") - -wins = 0 -losses = 0 -ties = 0 - -while True: - print("Current streak: %s Wins, %s Losses, %s Ties" % (wins, losses, ties)) - while True: - print("Type 'Q' to quit \n'R' for ROCK, 'P' for PAPER, 'S' for SCISSORS") - playermove = input().upper() - if playermove == "Q": - sys.exit() - if playermove == "R" or playermove == "P" or playermove == "S": - break - - if playermove == "R": - print("ROCK versus...") - if playermove == "P": - print("PAPER versus...") - if playermove == "S": - print("SCISSORS versus...") - - randomNum = random.randint(1, 3) - if randomNum == 1: - compMove = "R" - print("ROCK") - if randomNum == 2: - compMove = "P" - print("PAPER") - if randomNum == 3: - compMove = "S" - print("SCISSORS") - - if playermove == compMove: - print("It's a tie!") - ties += 1 - elif playermove == "R" and compMove == "P": - print("It's a loss!") - losses += 1 - elif playermove == "R" and compMove == "S": - print("It's a win!") - wins += 1 - elif playermove == "P" and compMove == "S": - print("It's a loss!") - losses += 1 - elif playermove == "P" and compMove == "R": - print("It's a win!") - wins += 1 - elif playermove == "S" and compMove == "R": - print("It's a loss!") - losses += 1 - elif playermove == "S" and compMove == "P": - print("It's a win!") - wins += 1 - else: - print("Thanks for trying my game")