From da4b16793684515d3c7d87d4ad260ef2e8141b69 Mon Sep 17 00:00:00 2001 From: Parshya30 Date: Tue, 30 Sep 2025 13:39:41 +0530 Subject: [PATCH 1/5] I have enhanced this code making it more interactive "Implement Immediate Time-Out Response in Alphabetize Quiz Game" --- .../alphabet_quiz_highscore.txt | 3 + src/gamesbyexample/alphabetizequiz.py | 188 +++++++++++++----- 2 files changed, 137 insertions(+), 54 deletions(-) create mode 100644 src/gamesbyexample/alphabet_quiz_highscore.txt diff --git a/src/gamesbyexample/alphabet_quiz_highscore.txt b/src/gamesbyexample/alphabet_quiz_highscore.txt new file mode 100644 index 0000000..4cf34e6 --- /dev/null +++ b/src/gamesbyexample/alphabet_quiz_highscore.txt @@ -0,0 +1,3 @@ +letters:3 +I have enhanced this code making it more interactive +"Implement Immediate Time-Out Response in Alphabetize Quiz Game" \ No newline at end of file diff --git a/src/gamesbyexample/alphabetizequiz.py b/src/gamesbyexample/alphabetizequiz.py index e8344f2..cbc2bce 100644 --- a/src/gamesbyexample/alphabetizequiz.py +++ b/src/gamesbyexample/alphabetizequiz.py @@ -1,74 +1,154 @@ -"""Alphabetize Quiz, by Al Sweigart al@inventwithpython.com -A time-based quiz game to see how fast you can alphabetize letters. -This and other games are available at https://nostarch.com/XX -Tags: short, game, word""" -__version__ = 0 +"""Alphabetize Quiz - Advanced Version +By Al Sweigart (improved by ChatGPT) + +A time-based quiz game to see how fast you can alphabetize letters, words, or numbers. +Now with multiple difficulty levels, countdown timer, and high-score saving! +""" + import random import time +import os +from colorama import Fore, Style, init -# Set up the constants: -# (!) Try changing these constants: -QUESTION_SIZE = 5 # Each question shows 5 letters to alphabetize. -QUIZ_DURATION = 30 # The quiz lasts 30 seconds. +init(autoreset=True) # For colored output +# Constants (you can tweak these) +QUESTION_SIZE = 5 +QUIZ_DURATION = 30 ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' -REVERSE_ALPHABET = 'ZYXWVUTSRQPONMLKJIHGFEDCBA' +NUMBERS = [str(i) for i in range(10)] +HIGHSCORE_FILE = "alphabet_quiz_highscore.txt" def main(): - # Fancy animation for the title: - slowPrint(ALPHABET, 0.02) # (!) Try changing 0.02 to 0.0 or 1.0. - slowPrint(' Alphabetize Quiz', 0.02) - slowPrint(REVERSE_ALPHABET, 0.02) - time.sleep(0.5) - - print('''By Al Sweigart al@inventwithpython.com - -Enter the alphabetical order of the letters shown as fast -as possible. Try to alphabetize as many as possible in {} seconds! - -Example: - P M O T Q <-- The letters. - > mopqt <-- Enter the correct alphabetical order. - '''.format(QUIZ_DURATION)) - input('Press Enter to begin...') - - startTime = time.time() # Get the current time for the start time. - numCorrect = 0 # Number of questions answered correctly. - while True: # Main game loop. - # Come up with letters for the question: - quizLetters = random.sample(ALPHABET, QUESTION_SIZE) - print(' '.join(quizLetters)) - response = input('> ').upper() - response = response.replace(' ', '') # Remove spaces. - - # Check if the quiz's time is up: - if time.time() - 30 > startTime: - print("TIME'S UP!") + showIntro() + + # Difficulty selection + difficulty = chooseDifficulty() + + # Highscore loading + highscore = loadHighScore(difficulty) + + input(Fore.CYAN + "\nPress Enter to begin the quiz...") + + startTime = time.time() + numCorrect = 0 + numAttempted = 0 + + while True: + # Check if time is up + elapsed = time.time() - startTime + if elapsed >= QUIZ_DURATION: + print(Fore.RED + "\nTIME'S UP!") break - # Check if the response is correct: + # Generate question + quizLetters = generateQuestion(difficulty) + print(Fore.YELLOW + " ".join(quizLetters)) + + # Countdown display + remaining = int(QUIZ_DURATION - elapsed) + print(Fore.MAGENTA + f"[{remaining}s left]") + + response = input("> ").upper().replace(" ", "") + numAttempted += 1 + if list(response) == sorted(quizLetters): - print(' Correct!\n') - numCorrect += 1 # Increase the score by 1. + print(Fore.GREEN + " ✅ Correct!\n") + numCorrect += 1 else: - print(' Sorry, wrong. :(\n') + print(Fore.RED + " ❌ Wrong. Answer was:", "".join(sorted(quizLetters)), "\n") + + # Final score + accuracy = (numCorrect / numAttempted * 100) if numAttempted else 0 + print(Style.BRIGHT + f"\n⏱ In {QUIZ_DURATION} seconds you attempted {numAttempted} questions.") + print(Fore.CYAN + f"✔ Correct: {numCorrect}") + print(Fore.RED + f"✘ Wrong: {numAttempted - numCorrect}") + print(Fore.YELLOW + f"🎯 Accuracy: {accuracy:.2f}%") + + # Save high score if beaten + if numCorrect > highscore: + print(Fore.GREEN + f"🏆 NEW HIGHSCORE! You beat the previous best of {highscore}.") + saveHighScore(difficulty, numCorrect) + else: + print(Fore.CYAN + f"Your highscore for {difficulty} is still {highscore}.") + + print(Fore.BLUE + "\nThanks for playing!") - # After the loop exits, the quiz is over. Show the final score: - print('In {} seconds you'.format(QUIZ_DURATION)) - print('got {} correct!'.format(numCorrect)) - print('Thanks for playing!') + +def showIntro(): + """Prints the intro animation and instructions.""" + slowPrint(ALPHABET, 0.01) + slowPrint(" Alphabetize Quiz - Advanced", 0.02) + slowPrint(ALPHABET[::-1], 0.01) + time.sleep(0.3) + + print('''\nWelcome to the Alphabetize Quiz! +Enter the correct alphabetical (or numerical) order of the shown characters. +Try to get as many correct as possible in the given time!\n''') + + +def chooseDifficulty(): + """Let the user select difficulty type.""" + print("\nChoose Difficulty:") + print("1. Letters (easy)") + print("2. Numbers (medium)") + print("3. Words (hard)") + + while True: + choice = input("> ").strip() + if choice == "1": + return "letters" + elif choice == "2": + return "numbers" + elif choice == "3": + return "words" + else: + print("Invalid choice. Enter 1, 2, or 3.") + + +def generateQuestion(difficulty): + """Generate a question based on difficulty.""" + if difficulty == "letters": + return random.sample(ALPHABET, QUESTION_SIZE) + elif difficulty == "numbers": + return random.sample(NUMBERS, QUESTION_SIZE) + elif difficulty == "words": + return random.sample( + ["CAT", "DOG", "MOON", "TREE", "PYTHON", "ZEBRA", "APPLE", "MANGO", "QUIZ", "CODE"], + QUESTION_SIZE + ) def slowPrint(text, pauseAmount=0.1): - """Slowly print out the characters in text one at a time.""" + """Slowly print out characters.""" for character in text: - # Set flush=True here so the text is immediately printed: - print(character, flush=True, end='') # end='' means no newline. - time.sleep(pauseAmount) # Pause in between each character. - print() # Print a newline. + print(character, flush=True, end="") + time.sleep(pauseAmount) + print() + + +def loadHighScore(difficulty): + """Load highscore for selected difficulty.""" + if not os.path.exists(HIGHSCORE_FILE): + return 0 + with open(HIGHSCORE_FILE, "r") as f: + scores = dict(line.strip().split(":") for line in f if ":" in line) + return int(scores.get(difficulty, 0)) + + +def saveHighScore(difficulty, score): + """Save highscore for selected difficulty.""" + scores = {} + if os.path.exists(HIGHSCORE_FILE): + with open(HIGHSCORE_FILE, "r") as f: + scores = dict(line.strip().split(":") for line in f if ":" in line) + scores[difficulty] = str(score) + with open(HIGHSCORE_FILE, "w") as f: + for k, v in scores.items(): + f.write(f"{k}:{v}\n") -# If this program was run (instead of imported), run the game: -if __name__ == '__main__': +# Run game +if __name__ == "__main__": main() From b1a6e012ea32e9b3629a6da87a84b16c9520b808 Mon Sep 17 00:00:00 2001 From: Parshya30 Date: Tue, 30 Sep 2025 14:07:18 +0530 Subject: [PATCH 2/5] Clickbait.py Sabing files which are generated --- src/gamesbyexample/clickbait.py | 193 +++++++++++++-------- src/gamesbyexample/clickbait_headlines.txt | 7 + 2 files changed, 128 insertions(+), 72 deletions(-) create mode 100644 src/gamesbyexample/clickbait_headlines.txt diff --git a/src/gamesbyexample/clickbait.py b/src/gamesbyexample/clickbait.py index 5075628..82bd63b 100644 --- a/src/gamesbyexample/clickbait.py +++ b/src/gamesbyexample/clickbait.py @@ -1,11 +1,6 @@ -"""Clickbait Headline Generator, by Al Sweigart al@inventwithpython.com -A clickbait headline generator for your soulless content farm website. -This code is available at https://nostarch.com/big-book-small-python-programming -Tags: large, beginner, humor, word""" -__version__ = 0 import random -# Set up the constants: +# Constants OBJECT_PRONOUNS = ['Her', 'Him', 'Them'] POSSESIVE_PRONOUNS = ['Her', 'His', 'Their'] PERSONAL_PRONOUNS = ['She', 'He', 'They'] @@ -13,119 +8,173 @@ 'Illinois', 'Ohio', 'Georgia', 'North Carolina', 'Michigan'] NOUNS = ['Athlete', 'Clown', 'Shovel', 'Paleo Diet', 'Doctor', 'Parent', 'Cat', 'Dog', 'Chicken', 'Robot', 'Video Game', 'Avocado', - 'Plastic Straw','Serial Killer', 'Telephone Psychic'] + 'Plastic Straw', 'Serial Killer', 'Telephone Psychic'] PLACES = ['House', 'Attic', 'Bank Deposit Box', 'School', 'Basement', 'Workplace', 'Donut Shop', 'Apocalypse Bunker'] WHEN = ['Soon', 'This Year', 'Later Today', 'RIGHT NOW', 'Next Week'] +WEBSITES = ['wobsite', 'blag', 'Facebuuk', 'Googles', 'Facesbook', 'Tweedie', 'Pastagram'] def main(): print('Clickbait Headline Generator') - print('By Al Sweigart al@inventwithpython.com') - print() + print('By Al Sweigart al@inventwithpython.com\n') - print('Our website needs to trick people into looking at ads!') + print("Let's generate some irresistible clickbait headlines to boost those ad clicks!") + + while True: + number_of_headlines = get_number_of_headlines() + headlines = [generate_random_headline() for _ in range(number_of_headlines)] + + print("\nHere are your clickbait headlines:\n") + for idx, headline in enumerate(headlines, 1): + print(f"{idx}. {headline}") + + # Optionally save headlines to a file + if prompt_yes_no("\nWould you like to save these headlines to a file? (y/n): "): + save_headlines(headlines) + + print() + website = random.choice(WEBSITES) + when = random.choice(WHEN).lower() + print(f"Post these to our {website} {when} or you’re fired!") + + if not prompt_yes_no("\nGenerate more headlines? (y/n): "): + print("\nThanks for using the Clickbait Headline Generator. Stay sneaky!") + break + + +def get_number_of_headlines(): + """Prompt user until a valid number is entered.""" + while True: + response = input("Enter the number of clickbait headlines to generate: ") + if response.isdecimal() and int(response) > 0: + return int(response) + print("Please enter a positive whole number.") + + +def prompt_yes_no(prompt): + """Prompt user with yes/no question, return True for yes.""" while True: - print('Enter the number of clickbait headlines to generate:') - response = input('> ') - if not response.isdecimal(): - print('Please enter a number.') - else: - numberOfHeadlines = int(response) - break # Exit the loop once a valid number is entered. - - for i in range(numberOfHeadlines): - clickbaitType = random.randint(1, 8) - - if clickbaitType == 1: - headline = generateAreMillenialsKillingHeadline() - elif clickbaitType == 2: - headline = generateWhatYouDontKnowHeadline() - elif clickbaitType == 3: - headline = generateBigCompaniesHateHerHeadline() - elif clickbaitType == 4: - headline = generateYouWontBelieveHeadline() - elif clickbaitType == 5: - headline = generateDontWantYouToKnowHeadline() - elif clickbaitType == 6: - headline = generateGiftIdeaHeadline() - elif clickbaitType == 7: - headline = generateReasonsWhyHeadline() - elif clickbaitType == 8: - headline = generateJobAutomatedHeadline() - - print(headline) - print() - - website = random.choice(['wobsite', 'blag', 'Facebuuk', 'Googles', - 'Facesbook', 'Tweedie', 'Pastagram']) - when = random.choice(WHEN).lower() - print('Post these to our', website, when, 'or you\'re fired!') - - -# Each of these functions returns a different type of headline: -def generateAreMillenialsKillingHeadline(): + response = input(prompt).strip().lower() + if response in ('y', 'yes'): + return True + elif response in ('n', 'no'): + return False + print("Please enter 'y' or 'n'.") + + +def save_headlines(headlines): + """Save the generated headlines to a text file.""" + filename = "clickbait_headlines.txt" + try: + with open(filename, 'a') as file: + file.write('\n'.join(headlines) + '\n') + print(f"Headlines saved to {filename}") + except Exception as e: + print(f"Error saving file: {e}") + + +def generate_random_headline(): + """Randomly pick and generate one of the headline types.""" + clickbait_type = random.randint(1, 10) # Increased variety with 10 types + + if clickbait_type == 1: + return generate_are_millenials_killing_headline() + elif clickbait_type == 2: + return generate_what_you_dont_know_headline() + elif clickbait_type == 3: + return generate_big_companies_hate_her_headline() + elif clickbait_type == 4: + return generate_you_wont_believe_headline() + elif clickbait_type == 5: + return generate_dont_want_you_to_know_headline() + elif clickbait_type == 6: + return generate_gift_idea_headline() + elif clickbait_type == 7: + return generate_reasons_why_headline() + elif clickbait_type == 8: + return generate_job_automated_headline() + elif clickbait_type == 9: + return generate_shocking_truth_headline() + elif clickbait_type == 10: + return generate_secret_revealed_headline() + + +# Headline generator functions + +def generate_are_millenials_killing_headline(): noun = random.choice(NOUNS) - return 'Are Millenials Killing the {} Industry?'.format(noun) + return f"Are Millennials Killing the {noun} Industry?" -def generateWhatYouDontKnowHeadline(): +def generate_what_you_dont_know_headline(): noun = random.choice(NOUNS) - pluralNoun = random.choice(NOUNS) + 's' + plural_noun = random.choice(NOUNS) + 's' when = random.choice(WHEN) - return 'Without This {}, {} Could Kill You {}'.format(noun, pluralNoun, when) + return f"Without This {noun}, {plural_noun} Could Kill You {when}" -def generateBigCompaniesHateHerHeadline(): +def generate_big_companies_hate_her_headline(): pronoun = random.choice(OBJECT_PRONOUNS) state = random.choice(STATES) noun1 = random.choice(NOUNS) noun2 = random.choice(NOUNS) - return 'Big Companies Hate {}! See How This {} {} Invented a Cheaper {}'.format(pronoun, state, noun1, noun2) + return f"Big Companies Hate {pronoun}! See How This {state} {noun1} Invented a Cheaper {noun2}" -def generateYouWontBelieveHeadline(): +def generate_you_wont_believe_headline(): state = random.choice(STATES) noun = random.choice(NOUNS) pronoun = random.choice(POSSESIVE_PRONOUNS) place = random.choice(PLACES) - return 'You Won\'t Believe What This {} {} Found in {} {}'.format(state, noun, pronoun, place) + return f"You Won't Believe What This {state} {noun} Found in {pronoun} {place}" -def generateDontWantYouToKnowHeadline(): - pluralNoun1 = random.choice(NOUNS) + 's' - pluralNoun2 = random.choice(NOUNS) + 's' - return 'What {} Don\'t Want You To Know About {}'.format(pluralNoun1, pluralNoun2) +def generate_dont_want_you_to_know_headline(): + plural_noun1 = random.choice(NOUNS) + 's' + plural_noun2 = random.choice(NOUNS) + 's' + return f"What {plural_noun1} Don't Want You To Know About {plural_noun2}" -def generateGiftIdeaHeadline(): +def generate_gift_idea_headline(): number = random.randint(7, 15) noun = random.choice(NOUNS) state = random.choice(STATES) - return '{} Gift Ideas to Give Your {} From {}'.format(number, noun, state) + return f"{number} Gift Ideas to Give Your {noun} From {state}" -def generateReasonsWhyHeadline(): +def generate_reasons_why_headline(): number1 = random.randint(3, 19) - pluralNoun = random.choice(NOUNS) + 's' - # number2 should be no larger than number1: + plural_noun = random.choice(NOUNS) + 's' number2 = random.randint(1, number1) - return '{} Reasons Why {} Are More Interesting Than You Think (Number {} Will Surprise You!)'.format(number1, pluralNoun, number2) + return (f"{number1} Reasons Why {plural_noun} Are More Interesting Than You Think " + f"(Number {number2} Will Surprise You!)") -def generateJobAutomatedHeadline(): +def generate_job_automated_headline(): state = random.choice(STATES) noun = random.choice(NOUNS) - i = random.randint(0, 2) pronoun1 = POSSESIVE_PRONOUNS[i] pronoun2 = PERSONAL_PRONOUNS[i] + if pronoun1 == 'Their': - return 'This {} {} Didn\'t Think Robots Would Take {} Job. {} Were Wrong.'.format(state, noun, pronoun1, pronoun2) + return f"This {state} {noun} Didn't Think Robots Would Take {pronoun1} Job. {pronoun2} Were Wrong." else: - return 'This {} {} Didn\'t Think Robots Would Take {} Job. {} Was Wrong.'.format(state, noun, pronoun1, pronoun2) + return f"This {state} {noun} Didn't Think Robots Would Take {pronoun1} Job. {pronoun2} Was Wrong." + + +def generate_shocking_truth_headline(): + noun = random.choice(NOUNS) + place = random.choice(PLACES) + return f"The Shocking Truth About {noun}s Hidden in Your {place}" + + +def generate_secret_revealed_headline(): + state = random.choice(STATES) + plural_noun = random.choice(NOUNS) + 's' + return f"Secret Revealed: Why {state} {plural_noun} Are Taking Over the World" -# If the program is run (instead of imported), run the game: if __name__ == '__main__': main() diff --git a/src/gamesbyexample/clickbait_headlines.txt b/src/gamesbyexample/clickbait_headlines.txt new file mode 100644 index 0000000..8b1e7d5 --- /dev/null +++ b/src/gamesbyexample/clickbait_headlines.txt @@ -0,0 +1,7 @@ +You Won't Believe What This New York Parent Found in Their Donut Shop +12 Gift Ideas to Give Your Paleo Diet From Ohio +6 Reasons Why Athletes Are More Interesting Than You Think (Number 2 Will Surprise You!) +You Won't Believe What This Georgia Chicken Found in Her Attic +This Georgia Serial Killer Didn't Think Robots Would Take Her Job. She Was Wrong. +Are Millennials Killing the Serial Killer Industry? +Big Companies Hate Her! See How This Pennsylvania Robot Invented a Cheaper Avocado From 8c9de003b28edfc95dcb313512dd1175245e6d55 Mon Sep 17 00:00:00 2001 From: Prashant <163377132+Parshya30@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:31:29 +0530 Subject: [PATCH 3/5] Add MIT License to the project --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d090b5f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Prashant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 458f6320987e78474736bf4a2cedf9cca12b56df Mon Sep 17 00:00:00 2001 From: Parshya30 Date: Fri, 31 Oct 2025 00:53:26 +0530 Subject: [PATCH 4/5] PUSHCODE --- .../alphabet_quiz_highscore.txt | 3 +- src/gamesbyexample/clickbait.py | 512 ++++++++++++------ src/gamesbyexample/clickbait_headlines.txt | 5 + src/gamesbyexample/viral_headlines.txt | 32 ++ 4 files changed, 387 insertions(+), 165 deletions(-) create mode 100644 src/gamesbyexample/viral_headlines.txt diff --git a/src/gamesbyexample/alphabet_quiz_highscore.txt b/src/gamesbyexample/alphabet_quiz_highscore.txt index 4cf34e6..7fc18d3 100644 --- a/src/gamesbyexample/alphabet_quiz_highscore.txt +++ b/src/gamesbyexample/alphabet_quiz_highscore.txt @@ -1,3 +1,2 @@ letters:3 -I have enhanced this code making it more interactive -"Implement Immediate Time-Out Response in Alphabetize Quiz Game" \ No newline at end of file +numbers:5 diff --git a/src/gamesbyexample/clickbait.py b/src/gamesbyexample/clickbait.py index 82bd63b..6957723 100644 --- a/src/gamesbyexample/clickbait.py +++ b/src/gamesbyexample/clickbait.py @@ -1,6 +1,9 @@ +import tkinter as tk +from tkinter import messagebox, ttk import random +from typing import List -# Constants +# Data from your code OBJECT_PRONOUNS = ['Her', 'Him', 'Them'] POSSESIVE_PRONOUNS = ['Her', 'His', 'Their'] PERSONAL_PRONOUNS = ['She', 'He', 'They'] @@ -14,167 +17,350 @@ WHEN = ['Soon', 'This Year', 'Later Today', 'RIGHT NOW', 'Next Week'] WEBSITES = ['wobsite', 'blag', 'Facebuuk', 'Googles', 'Facesbook', 'Tweedie', 'Pastagram'] - -def main(): - print('Clickbait Headline Generator') - print('By Al Sweigart al@inventwithpython.com\n') - - print("Let's generate some irresistible clickbait headlines to boost those ad clicks!") - - while True: - number_of_headlines = get_number_of_headlines() - headlines = [generate_random_headline() for _ in range(number_of_headlines)] - - print("\nHere are your clickbait headlines:\n") - for idx, headline in enumerate(headlines, 1): - print(f"{idx}. {headline}") - - # Optionally save headlines to a file - if prompt_yes_no("\nWould you like to save these headlines to a file? (y/n): "): - save_headlines(headlines) - - print() +class ModernClickbaitApp(tk.Tk): + def __init__(self): + super().__init__() + self.title("🔥 Viral Headline Generator 2.0") + self.geometry("700x600") + self.resizable(True, True) + self.configure(bg='#2C2C2C') + + # Modern color scheme + self.colors = { + 'bg': '#2C2C2C', + 'card_bg': '#3A3A3A', + 'accent': '#FF6B35', + 'secondary': '#4ECDC4', + 'text': '#FFFFFF', + 'text_secondary': '#CCCCCC' + } + + self.headlines = [] + self.setup_styles() + self.create_widgets() + + def setup_styles(self): + """Configure custom styles for ttk widgets""" + style = ttk.Style() + style.theme_use('clam') + + # Configure styles + style.configure('Accent.TButton', + background=self.colors['accent'], + foreground=self.colors['text'], + borderwidth=0, + focuscolor='none') + style.configure('Secondary.TButton', + background=self.colors['secondary'], + foreground=self.colors['text'], + borderwidth=0) + style.configure('Card.TFrame', + background=self.colors['card_bg']) + style.configure('Title.TLabel', + background=self.colors['bg'], + foreground=self.colors['text'], + font=('Arial', 16, 'bold')) + style.configure('Subtitle.TLabel', + background=self.colors['bg'], + foreground=self.colors['text_secondary'], + font=('Arial', 11)) + + def create_widgets(self): + # Header section + header_frame = tk.Frame(self, bg=self.colors['bg'], pady=20) + header_frame.pack(fill='x', padx=20) + + # Title with emoji + title_label = tk.Label(header_frame, + text="🔥 Viral Headline Generator 2.0", + font=('Arial', 20, 'bold'), + fg=self.colors['accent'], + bg=self.colors['bg']) + title_label.pack() + + subtitle_label = tk.Label(header_frame, + text="Generate click-worthy headlines that drive traffic!", + font=('Arial', 12), + fg=self.colors['text_secondary'], + bg=self.colors['bg']) + subtitle_label.pack(pady=(5, 0)) + + # Main card container + main_card = tk.Frame(self, bg=self.colors['card_bg'], padx=25, pady=20, relief='flat') + main_card.pack(fill='both', expand=True, padx=20, pady=10) + + # Input section + input_frame = tk.Frame(main_card, bg=self.colors['card_bg']) + input_frame.pack(fill='x', pady=(0, 15)) + + # Number of headlines input + input_label = tk.Label(input_frame, + text="Number of headlines to generate:", + font=('Arial', 11, 'bold'), + fg=self.colors['text'], + bg=self.colors['card_bg']) + input_label.pack(anchor='w') + + input_subframe = tk.Frame(input_frame, bg=self.colors['card_bg']) + input_subframe.pack(fill='x', pady=(8, 0)) + + self.num_entry = tk.Entry(input_subframe, + width=8, + font=('Arial', 12), + justify='center', + bg='#4A4A4A', + fg=self.colors['text'], + insertbackground=self.colors['text'], + relief='flat') + self.num_entry.pack(side='left') + self.num_entry.insert(0, "5") + + # Buttons container + buttons_frame = tk.Frame(main_card, bg=self.colors['card_bg']) + buttons_frame.pack(fill='x', pady=(0, 20)) + + # Generate button + gen_btn = tk.Button(buttons_frame, + text="🎯 Generate Headlines", + command=self.generate_headlines, + font=('Arial', 11, 'bold'), + bg=self.colors['accent'], + fg='white', + relief='flat', + padx=20, + pady=10, + cursor='hand2') + gen_btn.pack(side='left', padx=(0, 10)) + + # Save button + save_btn = tk.Button(buttons_frame, + text="💾 Save to File", + command=self.save_headlines, + font=('Arial', 11), + bg=self.colors['secondary'], + fg='white', + relief='flat', + padx=20, + pady=10, + cursor='hand2') + save_btn.pack(side='left', padx=(0, 10)) + + # Copy button + copy_btn = tk.Button(buttons_frame, + text="📋 Copy All", + command=self.copy_headlines, + font=('Arial', 11), + bg='#9C27B0', + fg='white', + relief='flat', + padx=20, + pady=10, + cursor='hand2') + copy_btn.pack(side='left') + + # Results section + results_label = tk.Label(main_card, + text="✨ Generated Headlines:", + font=('Arial', 12, 'bold'), + fg=self.colors['text'], + bg=self.colors['card_bg']) + results_label.pack(anchor='w', pady=(10, 8)) + + # Text widget with scrollbar + text_frame = tk.Frame(main_card, bg=self.colors['card_bg']) + text_frame.pack(fill='both', expand=True) + + # Add scrollbar + scrollbar = tk.Scrollbar(text_frame) + scrollbar.pack(side='right', fill='y') + + self.text = tk.Text(text_frame, + height=12, + wrap="word", + font=('Arial', 10), + bg='#4A4A4A', + fg=self.colors['text'], + insertbackground=self.colors['text'], + selectbackground=self.colors['accent'], + relief='flat', + padx=15, + pady=15, + yscrollcommand=scrollbar.set) + self.text.pack(side='left', fill='both', expand=True) + scrollbar.config(command=self.text.yview) + + # Footer + footer_frame = tk.Frame(self, bg=self.colors['bg'], pady=10) + footer_frame.pack(fill='x', side='bottom') + + footer_label = tk.Label(footer_frame, + text="💡 Pro Tip: Use these headlines for social media, blogs, or marketing campaigns!", + font=('Arial', 9), + fg=self.colors['text_secondary'], + bg=self.colors['bg']) + footer_label.pack() + + # Bind Enter key to generate headlines + self.bind('', lambda e: self.generate_headlines()) + + def generate_headlines(self): + self.text.delete('1.0', tk.END) + try: + count = int(self.num_entry.get()) + if count <= 0: + raise ValueError + if count > 20: + messagebox.showwarning("Too many", "Generating 20 headlines maximum.") + count = 20 + self.num_entry.delete(0, tk.END) + self.num_entry.insert(0, "20") + except ValueError: + messagebox.showerror("Invalid input", "❌ Please enter a positive whole number.") + return + + # Add loading animation + self.text.insert(tk.END, "🎬 Generating viral headlines...\n\n") + self.update() + + self.headlines = [self.generate_random_headline() for _ in range(count)] + + # Clear and display with formatting + self.text.delete('1.0', tk.END) + for i, headline in enumerate(self.headlines, 1): + # Add different emojis based on position + emoji = "🔥" if i == 1 else "🚀" if i == 2 else "💫" if i == 3 else "📈" + self.text.insert(tk.END, f"{emoji} Headline #{i}:\n", 'bold') + self.text.insert(tk.END, f" {headline}\n\n") + + # Configure tags for formatting + self.text.tag_configure('bold', font=('Arial', 10, 'bold'), foreground=self.colors['accent']) + + # Add footer message website = random.choice(WEBSITES) when = random.choice(WHEN).lower() - print(f"Post these to our {website} {when} or you’re fired!") - - if not prompt_yes_no("\nGenerate more headlines? (y/n): "): - print("\nThanks for using the Clickbait Headline Generator. Stay sneaky!") - break - - -def get_number_of_headlines(): - """Prompt user until a valid number is entered.""" - while True: - response = input("Enter the number of clickbait headlines to generate: ") - if response.isdecimal() and int(response) > 0: - return int(response) - print("Please enter a positive whole number.") - - -def prompt_yes_no(prompt): - """Prompt user with yes/no question, return True for yes.""" - while True: - response = input(prompt).strip().lower() - if response in ('y', 'yes'): - return True - elif response in ('n', 'no'): - return False - print("Please enter 'y' or 'n'.") - - -def save_headlines(headlines): - """Save the generated headlines to a text file.""" - filename = "clickbait_headlines.txt" - try: - with open(filename, 'a') as file: - file.write('\n'.join(headlines) + '\n') - print(f"Headlines saved to {filename}") - except Exception as e: - print(f"Error saving file: {e}") - - -def generate_random_headline(): - """Randomly pick and generate one of the headline types.""" - clickbait_type = random.randint(1, 10) # Increased variety with 10 types - - if clickbait_type == 1: - return generate_are_millenials_killing_headline() - elif clickbait_type == 2: - return generate_what_you_dont_know_headline() - elif clickbait_type == 3: - return generate_big_companies_hate_her_headline() - elif clickbait_type == 4: - return generate_you_wont_believe_headline() - elif clickbait_type == 5: - return generate_dont_want_you_to_know_headline() - elif clickbait_type == 6: - return generate_gift_idea_headline() - elif clickbait_type == 7: - return generate_reasons_why_headline() - elif clickbait_type == 8: - return generate_job_automated_headline() - elif clickbait_type == 9: - return generate_shocking_truth_headline() - elif clickbait_type == 10: - return generate_secret_revealed_headline() - - -# Headline generator functions - -def generate_are_millenials_killing_headline(): - noun = random.choice(NOUNS) - return f"Are Millennials Killing the {noun} Industry?" - - -def generate_what_you_dont_know_headline(): - noun = random.choice(NOUNS) - plural_noun = random.choice(NOUNS) + 's' - when = random.choice(WHEN) - return f"Without This {noun}, {plural_noun} Could Kill You {when}" - - -def generate_big_companies_hate_her_headline(): - pronoun = random.choice(OBJECT_PRONOUNS) - state = random.choice(STATES) - noun1 = random.choice(NOUNS) - noun2 = random.choice(NOUNS) - return f"Big Companies Hate {pronoun}! See How This {state} {noun1} Invented a Cheaper {noun2}" - - -def generate_you_wont_believe_headline(): - state = random.choice(STATES) - noun = random.choice(NOUNS) - pronoun = random.choice(POSSESIVE_PRONOUNS) - place = random.choice(PLACES) - return f"You Won't Believe What This {state} {noun} Found in {pronoun} {place}" - - -def generate_dont_want_you_to_know_headline(): - plural_noun1 = random.choice(NOUNS) + 's' - plural_noun2 = random.choice(NOUNS) + 's' - return f"What {plural_noun1} Don't Want You To Know About {plural_noun2}" - - -def generate_gift_idea_headline(): - number = random.randint(7, 15) - noun = random.choice(NOUNS) - state = random.choice(STATES) - return f"{number} Gift Ideas to Give Your {noun} From {state}" - - -def generate_reasons_why_headline(): - number1 = random.randint(3, 19) - plural_noun = random.choice(NOUNS) + 's' - number2 = random.randint(1, number1) - return (f"{number1} Reasons Why {plural_noun} Are More Interesting Than You Think " - f"(Number {number2} Will Surprise You!)") - - -def generate_job_automated_headline(): - state = random.choice(STATES) - noun = random.choice(NOUNS) - i = random.randint(0, 2) - pronoun1 = POSSESIVE_PRONOUNS[i] - pronoun2 = PERSONAL_PRONOUNS[i] - - if pronoun1 == 'Their': - return f"This {state} {noun} Didn't Think Robots Would Take {pronoun1} Job. {pronoun2} Were Wrong." - else: - return f"This {state} {noun} Didn't Think Robots Would Take {pronoun1} Job. {pronoun2} Was Wrong." - - -def generate_shocking_truth_headline(): - noun = random.choice(NOUNS) - place = random.choice(PLACES) - return f"The Shocking Truth About {noun}s Hidden in Your {place}" - - -def generate_secret_revealed_headline(): - state = random.choice(STATES) - plural_noun = random.choice(NOUNS) + 's' - return f"Secret Revealed: Why {state} {plural_noun} Are Taking Over the World" - - -if __name__ == '__main__': - main() + self.text.insert(tk.END, f"\n💡 Post these to {website} {when} for maximum engagement!", 'footer') + self.text.tag_configure('footer', font=('Arial', 9, 'italic'), foreground=self.colors['secondary']) + + def save_headlines(self): + if not self.headlines: + messagebox.showinfo("Info", "📝 No headlines to save. Generate some first!") + return + + filename = "viral_headlines.txt" + try: + with open(filename, 'a', encoding='utf-8') as file: + file.write("=" * 50 + "\n") + file.write(f"Viral Headlines - {self.get_timestamp()}\n") + file.write("=" * 50 + "\n") + for i, headline in enumerate(self.headlines, 1): + file.write(f"{i}. {headline}\n") + file.write("\n" + "=" * 50 + "\n\n") + messagebox.showinfo("✅ Saved", f"Headlines saved to {filename}") + except Exception as e: + messagebox.showerror("❌ Error", f"Failed to save file:\n{e}") + + def copy_headlines(self): + if not self.headlines: + messagebox.showinfo("Info", "📋 No headlines to copy. Generate some first!") + return + + headlines_text = "\n".join([f"{i+1}. {headline}" for i, headline in enumerate(self.headlines)]) + self.clipboard_clear() + self.clipboard_append(headlines_text) + messagebox.showinfo("✅ Copied", "All headlines copied to clipboard!") + + def get_timestamp(self): + from datetime import datetime + return datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + def generate_random_headline(self): + clickbait_type = random.randint(1, 10) + if clickbait_type == 1: + return self.generate_are_millenials_killing_headline() + elif clickbait_type == 2: + return self.generate_what_you_dont_know_headline() + elif clickbait_type == 3: + return self.generate_big_companies_hate_her_headline() + elif clickbait_type == 4: + return self.generate_you_wont_believe_headline() + elif clickbait_type == 5: + return self.generate_dont_want_you_to_know_headline() + elif clickbait_type == 6: + return self.generate_gift_idea_headline() + elif clickbait_type == 7: + return self.generate_reasons_why_headline() + elif clickbait_type == 8: + return self.generate_job_automated_headline() + elif clickbait_type == 9: + return self.generate_shocking_truth_headline() + elif clickbait_type == 10: + return self.generate_secret_revealed_headline() + + # Headline generator methods + def generate_are_millenials_killing_headline(self): + noun = random.choice(NOUNS) + return f"Are Millennials Killing the {noun} Industry? 🤔" + + def generate_what_you_dont_know_headline(self): + noun = random.choice(NOUNS) + plural_noun = random.choice(NOUNS) + 's' + when = random.choice(WHEN) + return f"Without This {noun}, {plural_noun} Could Kill You {when} ⚠️" + + def generate_big_companies_hate_her_headline(self): + pronoun = random.choice(OBJECT_PRONOUNS) + state = random.choice(STATES) + noun1 = random.choice(NOUNS) + noun2 = random.choice(NOUNS) + return f"Big Companies Hate {pronoun}! See How This {state} {noun1} Invented a Cheaper {noun2} 💡" + + def generate_you_wont_believe_headline(self): + state = random.choice(STATES) + noun = random.choice(NOUNS) + pronoun = random.choice(POSSESIVE_PRONOUNS) + place = random.choice(PLACES) + return f"You Won't Believe What This {state} {noun} Found in {pronoun} {place} 🤯" + + def generate_dont_want_you_to_know_headline(self): + plural_noun1 = random.choice(NOUNS) + 's' + plural_noun2 = random.choice(NOUNS) + 's' + return f"What {plural_noun1} Don't Want You To Know About {plural_noun2} 🤫" + + def generate_gift_idea_headline(self): + number = random.randint(7, 15) + noun = random.choice(NOUNS) + state = random.choice(STATES) + return f"{number} Gift Ideas to Give Your {noun} From {state} 🎁" + + def generate_reasons_why_headline(self): + number1 = random.randint(3, 19) + plural_noun = random.choice(NOUNS) + 's' + number2 = random.randint(1, number1) + return (f"{number1} Reasons Why {plural_noun} Are More Interesting Than You Think " + f"(Number {number2} Will Surprise You!) 🎯") + + def generate_job_automated_headline(self): + state = random.choice(STATES) + noun = random.choice(NOUNS) + i = random.randint(0, 2) + pronoun1 = POSSESIVE_PRONOUNS[i] + pronoun2 = PERSONAL_PRONOUNS[i] + if pronoun1 == 'Their': + return f"This {state} {noun} Didn't Think Robots Would Take {pronoun1} Job. {pronoun2} Were Wrong. 🤖" + else: + return f"This {state} {noun} Didn't Think Robots Would Take {pronoun1} Job. {pronoun2} Was Wrong. 🤖" + + def generate_shocking_truth_headline(self): + noun = random.choice(NOUNS) + place = random.choice(PLACES) + return f"The Shocking Truth About {noun}s Hidden in Your {place} 💥" + + def generate_secret_revealed_headline(self): + state = random.choice(STATES) + plural_noun = random.choice(NOUNS) + 's' + return f"Secret Revealed: Why {state} {plural_noun} Are Taking Over the World 🌍" + + +if __name__ == "__main__": + app = ModernClickbaitApp() + app.mainloop() \ No newline at end of file diff --git a/src/gamesbyexample/clickbait_headlines.txt b/src/gamesbyexample/clickbait_headlines.txt index 8b1e7d5..02430c8 100644 --- a/src/gamesbyexample/clickbait_headlines.txt +++ b/src/gamesbyexample/clickbait_headlines.txt @@ -5,3 +5,8 @@ You Won't Believe What This Georgia Chicken Found in Her Attic This Georgia Serial Killer Didn't Think Robots Would Take Her Job. She Was Wrong. Are Millennials Killing the Serial Killer Industry? Big Companies Hate Her! See How This Pennsylvania Robot Invented a Cheaper Avocado +You Won't Believe What This Ohio Clown Found in Their Donut Shop +Secret Revealed: Why Illinois Cats Are Taking Over the World +This Illinois Video Game Didn't Think Robots Would Take His Job. He Was Wrong. +You Won't Believe What This Texas Paleo Diet Found in His School +What Chickens Don't Want You To Know About Shovels diff --git a/src/gamesbyexample/viral_headlines.txt b/src/gamesbyexample/viral_headlines.txt new file mode 100644 index 0000000..caba425 --- /dev/null +++ b/src/gamesbyexample/viral_headlines.txt @@ -0,0 +1,32 @@ +================================================== +Viral Headlines - 2025-10-30 22:13:09 +================================================== +1. The Shocking Truth About Paleo Diets Hidden in Your Bank Deposit Box 💥 +2. Secret Revealed: Why Illinois Athletes Are Taking Over the World 🌍 +3. This Florida Shovel Didn't Think Robots Would Take Their Job. They Were Wrong. 🤖 +4. 13 Reasons Why Plastic Straws Are More Interesting Than You Think (Number 13 Will Surprise You!) 🎯 +5. Are Millennials Killing the Shovel Industry? 🤔 + +================================================== + +================================================== +Viral Headlines - 2025-10-30 22:13:29 +================================================== +1. Without This Chicken, Serial Killers Could Kill You Soon ⚠️ +2. Big Companies Hate Him! See How This Illinois Shovel Invented a Cheaper Avocado 💡 +3. Secret Revealed: Why Illinois Paleo Diets Are Taking Over the World 🌍 +4. Big Companies Hate Him! See How This New York Clown Invented a Cheaper Dog 💡 +5. Without This Robot, Athletes Could Kill You Soon ⚠️ +6. This Illinois Paleo Diet Didn't Think Robots Would Take His Job. He Was Wrong. 🤖 +7. 17 Reasons Why Athletes Are More Interesting Than You Think (Number 5 Will Surprise You!) 🎯 +8. Without This Chicken, Parents Could Kill You Soon ⚠️ +9. Without This Video Game, Clowns Could Kill You Next Week ⚠️ +10. The Shocking Truth About Plastic Straws Hidden in Your Donut Shop 💥 +11. This Texas Shovel Didn't Think Robots Would Take Their Job. They Were Wrong. 🤖 +12. What Dogs Don't Want You To Know About Serial Killers 🤫 +13. 5 Reasons Why Robots Are More Interesting Than You Think (Number 1 Will Surprise You!) 🎯 +14. Without This Paleo Diet, Avocados Could Kill You This Year ⚠️ +15. This Illinois Clown Didn't Think Robots Would Take His Job. He Was Wrong. 🤖 + +================================================== + From 4bfa639557752ec4dc80458a0b146d146608cc69 Mon Sep 17 00:00:00 2001 From: Parshya30 Date: Fri, 31 Oct 2025 01:01:20 +0530 Subject: [PATCH 5/5] PUSH2 --- src/gamesbyexample/cosmic.py | 531 ++++++++++++++++++++++++++++++++++ src/gamesbyexample/crawler.py | 360 +++++++++++++++++++++++ 2 files changed, 891 insertions(+) create mode 100644 src/gamesbyexample/cosmic.py create mode 100644 src/gamesbyexample/crawler.py diff --git a/src/gamesbyexample/cosmic.py b/src/gamesbyexample/cosmic.py new file mode 100644 index 0000000..8642d10 --- /dev/null +++ b/src/gamesbyexample/cosmic.py @@ -0,0 +1,531 @@ +import tkinter as tk +import random +import math +from typing import List, Tuple + +class SpaceShooter: + def __init__(self, root): + self.root = root + self.root.title("🚀 Cosmic Defender") + self.root.resizable(False, False) + self.root.configure(bg="#0a0a2a") + + # Game constants + self.WIDTH = 800 + self.HEIGHT = 600 + self.PLAYER_SPEED = 8 + self.BULLET_SPEED = 12 + self.ENEMY_SPEED = 3 + self.POWERUP_DURATION = 300 # frames + + # Colors + self.BG_COLOR = "#0a0a2a" + self.PLAYER_COLOR = "#4FC3F7" + self.ENEMY_COLOR = "#FF5252" + self.BULLET_COLOR = "#FFEB3B" + self.POWERUP_COLOR = "#69F0AE" + self.TEXT_COLOR = "white" + self.STAR_COLORS = ["#FFFFFF", "#FFEB3B", "#4FC3F7", "#FF5252"] + + # Game state + self.score = 0 + self.high_score = 0 + self.lives = 3 + self.level = 1 + self.game_running = False + self.powerup_active = False + self.powerup_timer = 0 + self.powerup_type = None + + # Game objects + self.player = None + self.bullets: List[dict] = [] + self.enemies: List[dict] = [] + self.powerups: List[dict] = [] + self.particles: List[dict] = [] + self.stars: List[dict] = [] + + # Initialize UI and game + self.setup_ui() + self.init_stars() + self.reset_game() + + def setup_ui(self): + # Header + header_frame = tk.Frame(self.root, bg=self.BG_COLOR) + header_frame.pack(pady=10) + + self.title_label = tk.Label( + header_frame, + text="🚀 Cosmic Defender", + font=("Arial", 24, "bold"), + fg=self.TEXT_COLOR, + bg=self.BG_COLOR + ) + self.title_label.pack() + + # Stats display + stats_frame = tk.Frame(self.root, bg=self.BG_COLOR) + stats_frame.pack(pady=5) + + self.stats_label = tk.Label( + stats_frame, + text="Score: 0 | High Score: 0 | Lives: 3 | Level: 1", + font=("Arial", 12), + fg=self.TEXT_COLOR, + bg=self.BG_COLOR + ) + self.stats_label.pack() + + # Game canvas + self.canvas = tk.Canvas( + self.root, + width=self.WIDTH, + height=self.HEIGHT, + bg=self.BG_COLOR, + highlightthickness=0 + ) + self.canvas.pack(pady=10) + + # Controls info + controls_frame = tk.Frame(self.root, bg=self.BG_COLOR) + controls_frame.pack(pady=5) + + controls_text = "🎮 Controls: Arrow Keys to move | Space to shoot | P to pause | R to restart" + self.controls_label = tk.Label( + controls_frame, + text=controls_text, + font=("Arial", 10), + fg="#AAAAAA", + bg=self.BG_COLOR + ) + self.controls_label.pack() + + # Message display + self.message_label = tk.Label( + self.root, + text="Press SPACE to start!", + font=("Arial", 14, "bold"), + fg="#FFD700", + bg=self.BG_COLOR + ) + self.message_label.pack(pady=5) + + # Bind keys + self.root.bind('', self.move_player) + self.root.bind('', self.move_player) + self.root.bind('', self.move_player) + self.root.bind('', self.move_player) + self.root.bind('', self.shoot) + self.root.bind('p', self.toggle_pause) + self.root.bind('P', self.toggle_pause) + self.root.bind('r', self.reset_game) + self.root.bind('R', self.reset_game) + + def init_stars(self): + """Initialize background stars""" + self.stars = [] + for _ in range(100): + star = { + 'x': random.randint(0, self.WIDTH), + 'y': random.randint(0, self.HEIGHT), + 'size': random.uniform(0.5, 2), + 'speed': random.uniform(0.5, 2), + 'color': random.choice(self.STAR_COLORS) + } + self.stars.append(star) + + def reset_game(self, event=None): + """Reset the game to initial state""" + self.player = {'x': self.WIDTH // 2, 'y': self.HEIGHT - 80, 'width': 50, 'height': 40} + self.bullets = [] + self.enemies = [] + self.powerups = [] + self.particles = [] + self.score = 0 + self.lives = 3 + self.level = 1 + self.game_running = False + self.powerup_active = False + self.powerup_timer = 0 + self.message_label.config(text="Press SPACE to start!") + self.update_stats() + self.draw_game() + + def update_stats(self): + """Update the stats display""" + powerup_text = "" + if self.powerup_active: + powerup_text = f" | 🔥 {self.powerup_type.upper()}" + + self.stats_label.config( + text=f"Score: {self.score} | High Score: {self.high_score} | Lives: {self.lives} | Level: {self.level}{powerup_text}" + ) + + def draw_game(self): + """Draw the current game state""" + self.canvas.delete("all") + + # Draw stars (parallax background) + for star in self.stars: + self.canvas.create_oval( + star['x'], star['y'], + star['x'] + star['size'], star['y'] + star['size'], + fill=star['color'], outline="" + ) + + # Draw player (spaceship) + if self.player: + # Spaceship body + points = [ + self.player['x'], self.player['y'] - 20, + self.player['x'] - 25, self.player['y'] + 20, + self.player['x'] + 25, self.player['y'] + 20 + ] + self.canvas.create_polygon(points, fill=self.PLAYER_COLOR, outline="white", width=2) + + # Cockpit + self.canvas.create_oval( + self.player['x'] - 8, self.player['y'] - 10, + self.player['x'] + 8, self.player['y'] + 5, + fill="#1A237E", outline="white", width=1 + ) + + # Engines + engine_color = "#FF6D00" if random.random() > 0.7 else "#FF9800" + self.canvas.create_polygon([ + self.player['x'] - 15, self.player['y'] + 20, + self.player['x'] - 5, self.player['y'] + 35, + self.player['x'] + 5, self.player['y'] + 35, + self.player['x'] + 15, self.player['y'] + 20 + ], fill=engine_color, outline="") + + # Draw bullets + for bullet in self.bullets: + self.canvas.create_oval( + bullet['x'] - 3, bullet['y'] - 8, + bullet['x'] + 3, bullet['y'] + 8, + fill=self.BULLET_COLOR, outline="" + ) + + # Bullet trail + for i in range(3): + self.canvas.create_oval( + bullet['x'] - 1, bullet['y'] + 8 + i * 4, + bullet['x'] + 1, bullet['y'] + 12 + i * 4, + fill="#FFA000", outline="" + ) + + # Draw enemies + for enemy in self.enemies: + # Enemy ship + points = [ + enemy['x'], enemy['y'] + 20, + enemy['x'] - 20, enemy['y'] - 10, + enemy['x'] - 10, enemy['y'] - 20, + enemy['x'] + 10, enemy['y'] - 20, + enemy['x'] + 20, enemy['y'] - 10 + ] + self.canvas.create_polygon(points, fill=self.ENEMY_COLOR, outline="#B71C1C", width=2) + + # Enemy details + self.canvas.create_oval( + enemy['x'] - 6, enemy['y'] - 5, + enemy['x'] + 6, enemy['y'] + 5, + fill="#1A237E", outline="" + ) + + # Draw powerups + for powerup in self.powerups: + color = self.POWERUP_COLOR + if powerup['type'] == 'rapid': + color = "#FF4081" + elif powerup['type'] == 'shield': + color = "#40C4FF" + + self.canvas.create_rectangle( + powerup['x'] - 15, powerup['y'] - 15, + powerup['x'] + 15, powerup['y'] + 15, + fill=color, outline="white", width=2 + ) + + # Powerup icon + if powerup['type'] == 'rapid': + self.canvas.create_text(powerup['x'], powerup['y'], text="⚡", font=("Arial", 12)) + elif powerup['type'] == 'shield': + self.canvas.create_text(powerup['x'], powerup['y'], text="🛡️", font=("Arial", 12)) + else: + self.canvas.create_text(powerup['x'], powerup['y'], text="💎", font=("Arial", 12)) + + # Draw particles + for particle in self.particles: + self.canvas.create_oval( + particle['x'] - particle['size'], particle['y'] - particle['size'], + particle['x'] + particle['size'], particle['y'] + particle['size'], + fill=particle['color'], outline="" + ) + + # Draw player shield if active + if self.powerup_active and self.powerup_type == 'shield': + self.canvas.create_oval( + self.player['x'] - 35, self.player['y'] - 35, + self.player['x'] + 35, self.player['y'] + 45, + outline="#40C4FF", width=3, dash=(5, 2) + ) + + def move_player(self, event): + """Move the player based on key press""" + if not self.game_running: + return + + if event.keysym == 'Left' and self.player['x'] > 40: + self.player['x'] -= self.PLAYER_SPEED + elif event.keysym == 'Right' and self.player['x'] < self.WIDTH - 40: + self.player['x'] += self.PLAYER_SPEED + elif event.keysym == 'Up' and self.player['y'] > 50: + self.player['y'] -= self.PLAYER_SPEED + elif event.keysym == 'Down' and self.player['y'] < self.HEIGHT - 50: + self.player['y'] += self.PLAYER_SPEED + + def shoot(self, event=None): + """Player shoots a bullet""" + if not self.game_running: + self.start_game() + return + + bullet_speed = self.BULLET_SPEED + if self.powerup_active and self.powerup_type == 'rapid': + bullet_speed *= 1.5 + + self.bullets.append({ + 'x': self.player['x'], + 'y': self.player['y'] - 20, + 'speed': bullet_speed + }) + + # Add muzzle flash particles + for _ in range(5): + self.particles.append({ + 'x': self.player['x'] + random.randint(-10, 10), + 'y': self.player['y'] - 15, + 'vx': random.uniform(-2, 2), + 'vy': random.uniform(-1, 1), + 'size': random.uniform(1, 3), + 'color': random.choice(["#FFEB3B", "#FF9800", "#FF6D00"]), + 'life': 20 + }) + + def start_game(self): + """Start the game""" + self.game_running = True + self.message_label.config(text="") + self.game_loop() + + def toggle_pause(self, event=None): + """Toggle game pause state""" + if self.game_running: + self.game_running = False + self.message_label.config(text="⏸️ Game Paused - Press P to continue") + else: + self.game_running = True + self.message_label.config(text="") + self.game_loop() + + def spawn_enemy(self): + """Spawn a new enemy""" + enemy_types = ['basic', 'fast', 'tank'] + weights = [0.7, 0.2, 0.1] # Probability weights + + enemy_type = random.choices(enemy_types, weights=weights)[0] + + if enemy_type == 'basic': + speed = self.ENEMY_SPEED + self.level * 0.2 + health = 1 + elif enemy_type == 'fast': + speed = self.ENEMY_SPEED * 1.5 + self.level * 0.3 + health = 1 + else: # tank + speed = self.ENEMY_SPEED * 0.7 + self.level * 0.1 + health = 3 + + self.enemies.append({ + 'x': random.randint(50, self.WIDTH - 50), + 'y': random.randint(-100, -40), + 'speed': speed, + 'health': health, + 'type': enemy_type + }) + + def spawn_powerup(self): + """Spawn a powerup with chance""" + if random.random() < 0.02: # 2% chance per frame + powerup_types = ['rapid', 'shield', 'score'] + powerup_type = random.choice(powerup_types) + + self.powerups.append({ + 'x': random.randint(30, self.WIDTH - 30), + 'y': -20, + 'speed': 2, + 'type': powerup_type + }) + + def create_explosion(self, x, y, color="#FF5252"): + """Create explosion particles""" + for _ in range(15): + self.particles.append({ + 'x': x, + 'y': y, + 'vx': random.uniform(-3, 3), + 'vy': random.uniform(-3, 3), + 'size': random.uniform(2, 5), + 'color': color, + 'life': 30 + }) + + def update_particles(self): + """Update and remove old particles""" + new_particles = [] + for particle in self.particles: + particle['x'] += particle['vx'] + particle['y'] += particle['vy'] + particle['life'] -= 1 + + if particle['life'] > 0: + new_particles.append(particle) + self.particles = new_particles + + def update_stars(self): + """Update star positions for parallax effect""" + for star in self.stars: + star['y'] += star['speed'] + if star['y'] > self.HEIGHT: + star['y'] = 0 + star['x'] = random.randint(0, self.WIDTH) + + def game_loop(self): + """Main game loop""" + if not self.game_running: + return + + # Update stars + self.update_stars() + + # Spawn enemies based on level + spawn_chance = 0.03 + (self.level * 0.01) + if random.random() < spawn_chance: + self.spawn_enemy() + + # Spawn powerups + self.spawn_powerup() + + # Update bullets + new_bullets = [] + for bullet in self.bullets: + bullet['y'] -= bullet['speed'] + if bullet['y'] > 0: + new_bullets.append(bullet) + self.bullets = new_bullets + + # Update enemies and check collisions + new_enemies = [] + for enemy in self.enemies: + enemy['y'] += enemy['speed'] + + # Check if enemy hit player + if (abs(enemy['x'] - self.player['x']) < 30 and + abs(enemy['y'] - self.player['y']) < 30): + if not self.powerup_active or self.powerup_type != 'shield': + self.lives -= 1 + self.create_explosion(self.player['x'], self.player['y'], "#4FC3F7") + if self.lives <= 0: + self.game_over() + return + self.create_explosion(enemy['x'], enemy['y']) + continue + + # Check bullet collisions + hit = False + for bullet in self.bullets: + if (abs(bullet['x'] - enemy['x']) < 20 and + abs(bullet['y'] - enemy['y']) < 20): + enemy['health'] -= 1 + self.create_explosion(bullet['x'], bullet['y'], "#FFEB3B") + if enemy['health'] <= 0: + self.score += 10 * self.level + self.create_explosion(enemy['x'], enemy['y']) + hit = True + break + + if not hit and enemy['y'] < self.HEIGHT + 50: + new_enemies.append(enemy) + + self.enemies = new_enemies + + # Update powerups + new_powerups = [] + for powerup in self.powerups: + powerup['y'] += powerup['speed'] + + # Check if player collected powerup + if (abs(powerup['x'] - self.player['x']) < 30 and + abs(powerup['y'] - self.player['y']) < 30): + self.activate_powerup(powerup['type']) + self.create_explosion(powerup['x'], powerup['y'], self.POWERUP_COLOR) + elif powerup['y'] < self.HEIGHT + 20: + new_powerups.append(powerup) + + self.powerups = new_powerups + + # Update powerup timer + if self.powerup_active: + self.powerup_timer -= 1 + if self.powerup_timer <= 0: + self.powerup_active = False + self.powerup_type = None + + # Update particles + self.update_particles() + + # Level up + if self.score >= self.level * 100: + self.level += 1 + self.message_label.config(text=f"🚀 Level {self.level}! Enemies are faster!", fg="#FFD700") + self.root.after(2000, lambda: self.message_label.config(text="")) + + # Update high score + if self.score > self.high_score: + self.high_score = self.score + + self.update_stats() + self.draw_game() + + # Continue game loop + if self.game_running: + self.root.after(16, self.game_loop) # ~60 FPS + + def activate_powerup(self, powerup_type): + """Activate a powerup""" + self.powerup_active = True + self.powerup_type = powerup_type + self.powerup_timer = self.POWERUP_DURATION + + if powerup_type == 'rapid': + self.message_label.config(text="⚡ Rapid Fire Activated!", fg="#FF4081") + elif powerup_type == 'shield': + self.message_label.config(text="🛡️ Shield Activated!", fg="#40C4FF") + else: # score + self.score += 50 + self.message_label.config(text="💎 +50 Points!", fg="#69F0AE") + + self.root.after(1500, lambda: self.message_label.config(text="")) + + def game_over(self): + """Handle game over""" + self.game_running = False + self.message_label.config(text="💥 Game Over! Press R to restart", fg="#FF5252") + self.create_explosion(self.player['x'], self.player['y'], "#4FC3F7") + +if __name__ == "__main__": + root = tk.Tk() + game = SpaceShooter(root) + root.mainloop() \ No newline at end of file diff --git a/src/gamesbyexample/crawler.py b/src/gamesbyexample/crawler.py new file mode 100644 index 0000000..4c82cd2 --- /dev/null +++ b/src/gamesbyexample/crawler.py @@ -0,0 +1,360 @@ +import tkinter as tk +from tkinter import messagebox +import random + +WIDTH = 12 +HEIGHT = 10 +FOW_RADIUS = 3 + +# Emoji tiles +TILE_FLOOR = '·' +TILE_WALL = '🧱' +TILE_PLAYER = '🧙' +TILE_ENEMY = '👹' +TILE_TREASURE = '💰' +TILE_TRAP = '🕳️' +TILE_HEALTH = '❤️' + +DIRECTIONS = {'Up': (-1, 0), 'Down': (1, 0), 'Left': (0, -1), 'Right': (0, 1)} + +class GameApp(tk.Tk): + def __init__(self): + super().__init__() + self.title("🏰 Roguelike Dungeon Crawler 🏰") + self.resizable(False, False) + self.geometry("600x700") + self.configure(bg="#2C2C2C") + + # Style configuration + self.style = { + "bg": "#2C2C2C", + "fg": "white", + "font_title": ("Arial", 18, "bold"), + "font_status": ("Arial", 12), + "font_map": ("Segoe UI Emoji", 20), + "highlight": "#FFD700", + "danger": "#FF6B6B", + "success": "#4ECDC4" + } + + self.game = self.new_game() + + # Header + header_frame = tk.Frame(self, bg=self.style["bg"]) + header_frame.pack(pady=10) + + self.title_label = tk.Label(header_frame, text="🏰 Roguelike Dungeon Crawler 🏰", + font=self.style["font_title"], + bg=self.style["bg"], fg=self.style["highlight"]) + self.title_label.pack() + + # Map display + map_frame = tk.Frame(self, bg=self.style["bg"]) + map_frame.pack(pady=10) + + self.map_text = tk.Text(map_frame, width=WIDTH+2, height=HEIGHT, + font=self.style["font_map"], + bg="black", fg="white", + borderwidth=2, relief="solid", + spacing2=2) + self.map_text.pack() + + # Status display + status_frame = tk.Frame(self, bg=self.style["bg"]) + status_frame.pack(pady=10, fill="x") + + # Health bar + health_frame = tk.Frame(status_frame, bg=self.style["bg"]) + health_frame.pack(fill="x", padx=20) + + self.health_label = tk.Label(health_frame, text="❤️ Health:", + font=self.style["font_status"], + bg=self.style["bg"], fg="white") + self.health_label.pack(side="left") + + self.health_bar = tk.Label(health_frame, text="", + font=self.style["font_status"], + bg=self.style["bg"], fg=self.style["danger"]) + self.health_bar.pack(side="left", padx=(5, 0)) + + # Inventory + inventory_frame = tk.Frame(status_frame, bg=self.style["bg"]) + inventory_frame.pack(fill="x", padx=20, pady=5) + + self.inventory_label = tk.Label(inventory_frame, text="🎒 Inventory:", + font=self.style["font_status"], + bg=self.style["bg"], fg="white") + self.inventory_label.pack(side="left") + + self.inventory_display = tk.Label(inventory_frame, text="", + font=self.style["font_status"], + bg=self.style["bg"], fg=self.style["success"]) + self.inventory_display.pack(side="left", padx=(5, 0)) + + # Message display + message_frame = tk.Frame(self, bg=self.style["bg"], height=60) + message_frame.pack(pady=10, fill="x", padx=20) + message_frame.pack_propagate(False) + + self.message_label = tk.Label(message_frame, text="", + font=self.style["font_status"], + bg="#1A1A1A", fg="white", + wraplength=500, justify="center", + borderwidth=2, relief="solid", padx=10, pady=10) + self.message_label.pack(fill="both", expand=True) + + # Controls help + controls_frame = tk.Frame(self, bg=self.style["bg"]) + controls_frame.pack(pady=10) + + controls_text = "🎮 Controls: Arrow Keys/WASD to move | I for Inventory" + self.controls_label = tk.Label(controls_frame, text=controls_text, + font=("Arial", 10), + bg=self.style["bg"], fg="#AAAAAA") + self.controls_label.pack() + + # Bind keys + self.bind('', self.key_handler) + self.bind('', self.key_handler) + self.bind('', self.key_handler) + self.bind('', self.key_handler) + self.bind('w', self.key_handler) + self.bind('a', self.key_handler) + self.bind('s', self.key_handler) + self.bind('d', self.key_handler) + self.bind('i', self.key_handler) + self.bind('r', self.key_handler) # Restart game + + self.update_ui() + + def new_game(self): + dungeon, rooms = self.make_dungeon() + px, py = random.choice(rooms) + enemies = [] + free_cells = [(i, j) for i in range(HEIGHT) for j in range(WIDTH) + if dungeon[i][j] == TILE_FLOOR and (i, j) != (px, py)] + + # Add enemies, treasures, traps, and health potions + for _ in range(4): + ex, ey = random.choice(free_cells) + free_cells.remove((ex, ey)) + enemies.append({'pos': [ex, ey], 'hp': 5, 'alive': True}) + + return { + 'dungeon': dungeon, + 'player': {'pos': [px, py], 'hp': 15, 'max_hp': 15, 'inventory': []}, + 'enemies': enemies, + 'msg': 'Welcome! Explore the dungeon and collect treasure!', + 'game_over': False + } + + def make_dungeon(self): + dungeon = [[TILE_WALL]*WIDTH for _ in range(HEIGHT)] + rooms = [] + + # Generate rooms + for _ in range(random.randint(4, 6)): + w, h = random.randint(3, 5), random.randint(2, 4) + x, y = random.randint(1, HEIGHT-h-1), random.randint(1, WIDTH-w-1) + for i in range(x, x+h): + for j in range(y, y+w): + dungeon[i][j] = TILE_FLOOR + rooms.append((x+h//2, y+w//2)) + + # Connect rooms with corridors + for i in range(len(rooms)-1): + x1, y1 = rooms[i] + x2, y2 = rooms[i+1] + for i in range(min(x1, x2), max(x1, x2)+1): + dungeon[i][y1] = TILE_FLOOR + for j in range(min(y1, y2), max(y1, y2)+1): + dungeon[x2][j] = TILE_FLOOR + + # Place items + free_cells = [(i, j) for i in range(HEIGHT) for j in range(WIDTH) + if dungeon[i][j] == TILE_FLOOR] + + # Treasures + treasures = random.sample(free_cells, k=3) + for tx, ty in treasures: + dungeon[tx][ty] = 'T' + free_cells.remove((tx, ty)) + + # Traps + traps = random.sample(free_cells, k=3) + for tx, ty in traps: + dungeon[tx][ty] = 'X' + free_cells.remove((tx, ty)) + + # Health potions + healths = random.sample(free_cells, k=2) + for hx, hy in healths: + dungeon[hx][hy] = 'H' + free_cells.remove((hx, hy)) + + return dungeon, rooms + + def update_ui(self): + self.map_text.delete('1.0', tk.END) + px, py = self.game['player']['pos'] + + # Create map with fog of war + for x in range(HEIGHT): + row = '' + for y in range(WIDTH): + # Fog of war - only show tiles within radius + if abs(x - px) + abs(y - py) > FOW_RADIUS: + row += ' ' # Empty space for fog + continue + + tile = self.game['dungeon'][x][y] + + # Player + if (x, y) == (px, py): + row += TILE_PLAYER + ' ' + # Enemies + elif (x, y) in [tuple(e['pos']) for e in self.game['enemies'] if e['alive']]: + row += TILE_ENEMY + ' ' + # Special tiles + elif tile == 'T': + row += TILE_TREASURE + ' ' + elif tile == 'X': + row += TILE_TRAP + ' ' + elif tile == 'H': + row += TILE_HEALTH + ' ' + else: + row += tile + ' ' + + self.map_text.insert(tk.END, row + '\n') + + # Update health bar with visual representation + hp = self.game['player']['hp'] + max_hp = self.game['player']['max_hp'] + health_bar = '❤️' * hp + '♡' * (max_hp - hp) + self.health_bar.config(text=f"{hp}/{max_hp} {health_bar}") + + # Update inventory + inv = self.game['player']['inventory'] + treasure_count = inv.count('treasure') + health_count = inv.count('health_potion') + inventory_text = f"💰×{treasure_count} ❤️×{health_count}" + self.inventory_display.config(text=inventory_text) + + # Update message + self.message_label.config(text=self.game['msg']) + + # Game over check + if self.game['player']['hp'] <= 0 and not self.game['game_over']: + self.game['game_over'] = True + self.game['msg'] = "💀 You died! Game over. Press R to restart." + self.update_ui() + messagebox.showinfo("Game Over", "You have been defeated! Press R to restart.") + + def key_handler(self, event): + if self.game['game_over'] and event.keysym.lower() == 'r': + self.game = self.new_game() + self.update_ui() + return + + if self.game['game_over']: + return + + key = event.keysym.lower() + if key in ['w', 'a', 's', 'd', 'up', 'down', 'left', 'right']: + self.player_move(key) + elif key == 'i': + self.show_inventory() + else: + self.game['msg'] = "Use arrow keys/WASD to move, I for inventory" + self.update_ui() + + def player_move(self, key): + mapping = { + 'w': (-1, 0), 'up': (-1, 0), + 's': (1, 0), 'down': (1, 0), + 'a': (0, -1), 'left': (0, -1), + 'd': (0, 1), 'right': (0, 1) + } + dx, dy = mapping[key] + px, py = self.game['player']['pos'] + nx, ny = px+dx, py+dy + + if 0 <= nx < HEIGHT and 0 <= ny < WIDTH and self.game['dungeon'][nx][ny] != TILE_WALL: + # Check for enemy at destination + enemy_found = None + for e in self.game['enemies']: + if e['alive'] and e['pos'] == [nx, ny]: + enemy_found = e + break + + if enemy_found: + enemy_found['hp'] -= 4 + self.game['msg'] = "⚔️ You hit the enemy for 4 damage!" + if enemy_found['hp'] <= 0: + enemy_found['alive'] = False + self.game['msg'] = "🎯 You defeated the enemy!" + else: + # Move player + self.game['player']['pos'] = [nx, ny] + tile = self.game['dungeon'][nx][ny] + + if tile == 'T': + self.game['player']['inventory'].append('treasure') + self.game['dungeon'][nx][ny] = TILE_FLOOR + self.game['msg'] = "💰 You found treasure!" + elif tile == 'X': + self.game['player']['hp'] -= 3 + self.game['dungeon'][nx][ny] = TILE_FLOOR + self.game['msg'] = "💥 You stepped on a trap! Lost 3 HP!" + elif tile == 'H': + self.game['player']['hp'] = min(self.game['player']['max_hp'], self.game['player']['hp'] + 5) + self.game['player']['inventory'].append('health_potion') + self.game['dungeon'][nx][ny] = TILE_FLOOR + self.game['msg'] = "❤️ You found a health potion! Restored 5 HP!" + else: + self.game['msg'] = "Exploring..." + else: + self.game['msg'] = "🚧 A wall blocks your path." + + self.enemy_turn() + self.update_ui() + + def enemy_turn(self): + if self.game['player']['hp'] <= 0: + return + + px, py = self.game['player']['pos'] + for e in self.game['enemies']: + if not e['alive']: + continue + ex, ey = e['pos'] + dx = max(-1, min(1, px - ex)) + dy = max(-1, min(1, py - ey)) + newpos = [ex+dx, ey+dy] + + # Check if move is valid + if (0 <= newpos[0] < HEIGHT and 0 <= newpos[1] < WIDTH and + self.game['dungeon'][newpos[0]][newpos[1]] != TILE_WALL and + newpos != [px, py] and + not any(ev['alive'] and ev['pos'] == newpos for ev in self.game['enemies'])): + e['pos'] = newpos + + # Attack player if adjacent + if abs(px - e['pos'][0]) + abs(py - e['pos'][1]) == 1: + self.game['player']['hp'] -= 2 + if self.game['player']['hp'] > 0: + self.game['msg'] = "👹 An enemy hit you for 2 damage!" + + def show_inventory(self): + inv = self.game['player']['inventory'] + treasure_count = inv.count('treasure') + health_count = inv.count('health_potion') + + if treasure_count == 0 and health_count == 0: + self.game['msg'] = "🎒 Your inventory is empty." + else: + self.game['msg'] = f"🎒 Inventory: {treasure_count} treasure(s), {health_count} health potion(s)" + self.update_ui() + +if __name__ == '__main__': + GameApp().mainloop() \ No newline at end of file