"""Games for the BBS. Shares `scores`, `sp_games` and `matches` with the web site, so a telnet user and a WAP user can play each other in the same match.""" import json import random import time from bbsdb import q, q1, ex, ago QUESTIONS = [ ("What does WAP stand for?", ["Wireless Application Protocol", "Web Access Point", "Wide Area Paging", "Wireless Audio Player"], 0), ("WML is based on which language?", ["HTML", "XML", "SGML", "JSON"], 1), ("Which company made the Nokia 7110?", ["Ericsson", "Motorola", "Nokia", "Siemens"], 2), ("A WML file is made up of one or more...", ["Pages", "Cards", "Frames", "Slides"], 1), ("What year was WAP 1.1 published?", ["1996", "1999", "2002", "2005"], 1), ("GPRS stands for General Packet Radio...?", ["System", "Service", "Standard", "Stream"], 1), ] def games_menu(t, con, me): while True: t.header("GAMES") t.line(" [1] Guess the Number (single player)") t.line(" [2] Quick Quiz (single player)") t.line(" [3] Noughts & Crosses (multiplayer)") t.line(" [4] Nim - 21 sticks (multiplayer)") t.line(" [5] Mastermind (single player)") t.line(" [6] Hangman (single player)") t.line(" [7] High scores") t.line(" [Q] Back to main") c = t.ask("\ngames> ").lower() if c == "1": guess(t, con, me) elif c == "2": quiz(t, con, me) elif c == "3": ttt(t, con, me) elif c == "4": nim(t, con, me) elif c == "5": mastermind(t, con, me) elif c == "6": hangman(t, con, me) elif c == "7": scores(t, con) elif c.startswith("q") or c == "": return def add_score(con, game, uid, score, detail=""): ex(con, "INSERT INTO scores (game,user_id,score,detail,created_at)" " VALUES (?,?,?,?,?)", (game, uid, score, detail, int(time.time()))) # ------------------------------------------------------------------ mastermind def mastermind(t, con, me): # Mastermind: 4 pegs, 6 colors, 10 tries colors = ['1', '2', '3', '4', '5', '6'] # represent colors as digits secret = [random.choice(colors) for _ in range(4)] tries = 0 max_tries = 10 t.header("MASTERMIND") t.line(" I have selected a sequence of 4 colors from 1-6.") t.line(" You have 10 tries to guess the sequence.") t.line(" Feedback: Black = correct color and position, White = correct color only.") t.line(" Enter your guess as 4 digits (e.g. 1234) or Q to quit.") while tries < max_tries: s = t.ask("\n guess> ", maxlen=10) if s.lower().startswith("q"): t.line(" The code was %s." % ''.join(secret)) return if len(s) != 4 or not all(c in colors for c in s): t.line(" Enter exactly 4 digits from 1-6.") continue guess = list(s) tries += 1 # Calculate black and white pegs black = sum(1 for i in range(4) if guess[i] == secret[i]) # Count occurrences of each color in secret and guess for white pegs secret_counts = {c: secret.count(c) for c in set(secret)} guess_counts = {c: guess.count(c) for c in set(guess)} white = sum(min(secret_counts.get(c, 0), guess_counts.get(c, 0)) for c in set(secret)) - black if black == 4: score = max(1, 100 - 10 * tries) add_score(con, "mastermind", me["id"], score, "%d tries" % tries) t.line(" Correct! %d in %d tries. Score %d." % (''.join(secret), tries, score)) return else: t.line(" Feedback: %d Black, %d White. (tries: %d)" % (black, white, tries)) t.line(" You ran out of tries. The code was %s." % ''.join(secret)) def hangman(t, con, me): # Hangman: word guessing game, 6 lives import string WORDS = ["python", "bbs", "telnet", "wml", "matrix", "linux", "mastermind", "screens", "forum", "games"] word = random.choice(WORDS) word_letters = set(word) alphabet = set(string.ascii_lowercase) used_letters = set() lives = 6 t.header("HANGMAN") t.line("I am thinking of a word. It has %d letters." % len(word)) t.line("You have %d lives." % lives) while len(word_letters) > 0 and lives > 0: # What current word is (with dashes for unguessed letters) word_list = [letter if letter in used_letters else "-" for letter in word] t.line("Current word: " + " ".join(word_list)) t.line("Lives left: %d" % lives) t.line("Used letters: " + " ".join(sorted(used_letters))) # User input t.line("Guess a letter:") s = t.ask("> ").lower() if len(s) != 1 or s not in alphabet: t.line("Please enter a single letter from a-z.") continue # If user has already guessed this letter if s in used_letters: t.line("You have already used that letter. Please try again.") continue # Add letter to used used_letters.add(s) # Check if letter is in word if s in word_letters: word_letters.discard(s) t.line("Good! %s is in the word." % s) else: lives -= 1 t.line("%s is not in the word." % s) # Game over if lives == 0: t.line("You died! The word was %s." % word) else: t.line("Yay! You guessed the word %s!" % word) score = max(1, 50 - (6 - lives) * 5) add_score(con, "hangman", me["id"], score, "%d lives remaining" % lives) def scores(t, con): names = {"guess": "Guess the Number", "quiz": "Quick Quiz", "ttt": "Noughts & Crosses", "nim": "Nim", "mastermind": "Mastermind", "hangman": "Hangman"}