🎯 Mission: D-Day B-Day

✍️ Coded line by line by Mr.Nahm 💛 · See full profile and all works →

← All projects

📖 What is this project?

Mission: D-Day B-Day คือเกมผจญภัยแบบเลือกทางเดิน (Text Adventure) แนวสายลับ — เปิดเรื่องด้วยการที่เราถูกว่าจ้างให้ทำ "ภารกิจลับ" แล้วต้องตัดสินใจว่าจะ ACCEPT (รับงาน) REFUSE (ปฏิเสธ) หรือ LEARN MORE (ขอฟังรายละเอียดก่อน) — แต่ละทางพาไปคนละเส้นเรื่องจริง ๆ ไม่ใช่แค่ข้อความต่างกัน

สิ่งที่ทำให้เกมนี้น่าสนใจคือจังหวะการเล่าเรื่อง — Mr.Nahm เขียนฟังก์ชัน sprint() ที่พิมพ์ทีละตัวอักษรด้วย time.sleep(0.07) ทำให้ข้อความค่อย ๆ ไหลออกมาเหมือนหนังสายลับ และ sinput() ที่ตรวจคำตอบให้อัตโนมัติ ถ้าพิมพ์ผิดจะขึ้น INVALID! แล้วถามใหม่จนกว่าจะตอบถูก ไม่มีทางที่เกมจะพังเพราะผู้เล่นพิมพ์มั่ว

อีกจุดที่เป็นเทคนิคระดับสูงคือการแยกเนื้อเรื่องออกเป็นคนละไฟล์main.py เป็นฉากเปิด แล้วเรียก Accept.py หรือ Refuse.py ต่อด้วย subprocess.run() พร้อมส่ง stdout/stderr ต่อให้ ทำให้แต่ละเส้นเรื่องแยกกันเขียนได้อิสระ และยังมีระบบเสี่ยงดวงตอนถูกยิง (สุ่ม 1 ใน 3) กับระบบเก็บของ ที่จำได้ว่าเราเลือกอาวุธอะไรไว้ตั้งแต่ต้นเกม

🧠 What they used from the Python course:
แยกเนื้อเรื่องเป็นหลายไฟล์ (main / Accept / Refuse) subprocess.run() — เรียกไฟล์ Python อีกไฟล์ให้ทำงานต่อ from main import — เอาฟังก์ชันจากไฟล์อื่นมาใช้ซ้ำ ฟังก์ชันพิมพ์ทีละตัวอักษรด้วย time.sleep() ตรวจคำตอบผู้เล่นวนซ้ำจนกว่าจะถูก (while + in) ANSI escape codes — ใส่สีข้อความในเทอร์มินัล 10 สี random.randint() — ระบบเสี่ยงดวงตอนถูกยิง if / elif / else ซ้อนหลายชั้น ทำหลายตอนจบ list — ระบบกระเป๋าเก็บของ (inventory)

🕹️ Try the real thing!

This is the real program, converted to run on the web with every rule kept exactly the same — type your answer and press Enter, just like running it in Python.

👨‍💻 The original Python source code (with the comments they wrote themselves)

This project is split into 3 files — tap a heading to open each one.

main.py (76 lines)
import random
import subprocess
import sys
import time
import os
colors = {
    "black": '\033[30m',
    "red": '\033[31m',
    "green": '\033[92m',
    "yellow": '\033[33m',
    "blue": '\033[34m',
    "magenta": '\033[35m',
    "cyan": '\033[36m',
    "white": '\033[37m',
    "gray": '\033[90m',
    "reset": '\033[0m'
    }
def sprint(txt, color='reset'):
 for l in txt:
   print(colors[color]+l+colors['reset'],flush=True,end='')
   time.sleep(0.07)
 print()
 time.sleep(1)
def sinput(txt,color='reset'):
 for l in txt:
   print(colors[color]+l+colors['reset'],end='',flush=True)
   time.sleep(0.07)
 ans = input(' >> ').lower()
 options = txt.lower().split(' | ')
 while ans not in options:
  sprint('INVALID!','red')
  for l in txt:
    print(colors[color]+l+colors['reset'],end='',flush=True)
    time.sleep(0.07)
  ans = input(' >> ')
 return ans
def msprint(txt, color='reset'):
 for l in txt:
   print(colors[color]+l+colors['reset'],flush=True,end='')
   time.sleep(0.07)

def main():
  msprint('SCENE I --- ')
  sprint('THE OFFER', 'yellow')
  sprint('MISSION: D-DAY B-DAY')
  sprint('SKIP STORY')
  skip_story = sinput('YES | NO', 'red')
  if skip_story == 'no':
    sprint('MISSION D-DAY B-DAY IS A MISSION YOU HAVE BEEN HIRED TO CARRY OUT')
    sprint('YOU ARE ALLOWED TO ACCEPT OR REFUSE:')
    sprint('IF YOU ACCEPT AND FAIL: YOU WILL BE SILENCED')
    sprint('IF YOU REFUSE, YOU WILL BE ADMINISTERED A HIGH CLASS SEDATIVE THAT ALLOWS YOU FORGET THIS OFFER')
    sprint('DO YOU CHOOSE TO ACCEPT OR REFUSE')
    sprint('CHOOSE WISELY')
  start_game = sinput('ACCEPT | REFUSE | LEARN MORE', 'red')
  if start_game == 'learn more':
    sprint('THE MISSION IS SIMPLE: YOU ARE TASKED WITH RUINING A PARTY, A BIRTHDAY PARTY')
    sprint('THE PLAN: YOU SNEAK INTO THE HOSTING LOCATION AND BRING THE PARTY DOWN...')
    sprint('BY ALL MEANS NECESSARY')
    sprint("NOW I'LL ASK YOU AGAIN:")
    start_game = sinput('ACCEPT | REFUSE','red').lower()
  elif start_game == 'refuse':
    subprocess.run(
      ["python", "Refuse.py"],
      stdout=sys.stdout,
      stderr=sys.stderr,
    )
  elif start_game == 'accept':
    subprocess.run(
      ["python", "Accept.py"],
      stdout=sys.stdout,
      stderr=sys.stderr,
    )
if __name__ == '__main__':
  main()
  
Accept.py (108 lines)
from main import sprint, sinput, msprint
import random
invent = []
def accept():
    sprint('SO YOU HAVE ACCEPTED')
    sprint('YOU WILL BE GIVEN A CHOICE BETWEEN 3 BASIC STARTER WEAPONS')
    msprint('THE GUN: ','magenta')
    sprint('A SIMPLE YET EFFECTIVE CHOICE','gray')
    msprint('THE MACHETE: ','magenta')
    sprint('A VERSATILE TOOL NOT SO USEFUL IN COMBAT','gray')
    msprint('THE HAT: ','magenta')
    sprint('LOOKS EPIC','gray')
    starter = sinput('GUN | MACHETE | HAT','red').upper()
    invent.append(starter.lower())
    msprint('YOU CHOSE THE ')
    msprint(starter, 'magenta')
    sprint('! GREAT CHOICE... HOPE YOU DONT REGRET IT')
    msprint('SCENE II[A] --- ')
    sprint('THE APPROACH','yellow')
    sprint('THE LIGHTS IN THE ROOM STARTS TO DIM')
    sprint("YOU HEAR A SLOW METALLIC GRINDING AND A GENERATOR'S WHIR", 'gray')
    sprint('SUDDENLY A BURST OF LIGHT BURSTS INTO THE ROOM REVEALING THE CITYSCAPE OUTSIDE','yellow')
    sprint('YOUR EYES START TO ADJUST TO THE LIGHT')
    sprint('YOU SLOWLY RISE FROM YOUR CHAIR')
    choice = sinput('LEAVE THE BUILDING | EXPLORE THE BUILDING')
    if choice == 'explore the building':
      sprint('YOU CHOSE TO EXPLORE THE BUILDING')
      sprint('THE BUILDING YOU ARE IN SEEMS TO BE A LARGE WAREHOUSE')
      sprint('AS YOU WALK AROUND A PERSONNEL ASKS YOU TO LEAVE THE BUILDING')
      choice = sinput('LEAVE THE BUILDING | PUNCH THE PERSONNEL')
      if choice == 'punch the personnel':
        sprint('ARE YOU SURE?')
        choice = sinput('YES | NO')
        if choice == 'yes':
          sprint('YOU PUNCHED THE PERSONNEL')
          msprint('THE PERSONNEL PULLS OUT A ')
          sprint('.50 DESSERT EAGLE','yellow')
          sprint('HE AIMS...')
          sprint('PULLS THE TRIGGER')
          bullet_hit = random.randint(1,3)
        else:
          sprint('YOU DECIDED AGAINST PUNCHING THE PERSONNEL AND THEREFORE MUST LEAVE')
          sprint('AS YOU WALK TOWARDS THE EXIT YOU HEAR A SIREN AND THE SCREECHING OF TIRES')
          sprint('YOU ASSUME ITS AN ONGOING CAR CHASE BUT YOU PAY NO MIND')
          sprint('AS YOU EXIT THE BUILDING THE SIREN SOUND SEEMS TO BE MOVING CLOSER')
          sprint('SUDDENLY A BRIGHT LIGHT FLASHES FROM YOUR SIDE')
          sprint('YOU TURN TO LOOK:')
          sprint('BUT IT WAS ALREADY TOO LATE')
          sprint("'DEER CAUGHT IN THE HEADLIGHTS'",'red')     
        if bullet_hit == 1:
            sprint('DEATH BY VIOLENCE', 'red')
        else:
          msprint('THE BULLET WOOSHES PAST YOUR HEAD ')
          sprint('TAKING OUT YOUR EARLOBE', 'red')
          sprint("Personnel: *scoffs* Seems like I've missed. You're a lucky one. C'mere, let me show you around")
          msprint('AS THE PERSONNEL SHOWS YOU ABOUT THE FACILITY YOU SPOT AN ')
          msprint('AIR CANNON ', 'blue')
          sprint('LAYING ON THE TABLE')
          choice = sinput('TAKE THE CANNON | LEAVE THE CANNON').lower()
          if choice == 'leave the cannon':
            sprint('THE PERSONNEL NOTICES YOU STOPPING AND LOOKING AT THE CANNON')
            sprint('HE GIVES IT TO YOU')
            invent.append('air cannon')
          else:
            choice = sinput('STEAL IT | ASK FOR IT')
            if choice == 'steal it':
              sprint('THE CANNON WAS HEAVIER THAN YOU EXPECTED')
              sprint('THE CANNON FALLS ON YOUR FOOT AND YOU STUMBLE BACKWARDS INTO A GUARD')
              sprint('THE GUARD GETS OFFENDED')
              msprint('THE GUARD PULLS OUT AN ')
              sprint('AK-47','yellow')
              sprint('HE AIMS...')
              sprint('PULLS THE TRIGGER')
              sprint("SHOULD'VE LEARNT MANNERS", 'red')
              choice = 0
            else:
              sprint('YOU ASK THE PERSONNEL NICELY FOR THE CANNON')
              sprint('HE SCOFFS')
              sprint('Hmm... Good question.')
              sprint('No.')
          if choice:
            sprint('YOU WALK AROUND THE BUILDING EXPLORING A FEW MORE ROOMS UNTIL YOUR TOUR ENDS')
            sprint("YOU'VE BECOME FRIENDS WITH THE PERSONNEL")
              

      else:
          sprint('AS YOU WALK TOWARDS THE EXIT YOU HEAR A SIREN AND THE SCREECHING OF TIRES')
          sprint('YOU ASSUME ITS AN ONGOING CAR CHASE BUT YOU PAY NO MIND')
          sprint('AS YOU EXIT THE BUILDING THE SIREN SOUND SEEMS TO BE MOVING CLOSER')
          sprint('SUDDENLY A BRIGHT LIGHT FLASHES FROM YOUR SIDE')
          sprint('YOU TURN TO LOOK:')
          sprint('BUT IT WAS ALREADY TOO LATE')
          sprint("'DEER CAUGHT IN THE HEADLIGHTS'",'red')     
    else:
      sprint('AS YOU WALK TOWARDS THE EXIT YOU HEAR A SIREN AND THE SCREECHING OF TIRES')
      sprint('YOU ASSUME ITS AN ONGOING CAR CHASE BUT YOU PAY NO MIND')
      sprint('AS YOU EXIT THE BUILDING THE SIREN SOUND SEEMS TO BE MOVING CLOSER')
      sprint('SUDDENLY A BRIGHT LIGHT FLASHES FROM YOUR SIDE')
      sprint('YOU TURN TO LOOK:')
      sprint('BUT IT WAS ALREADY TOO LATE')
      sprint("'DEER CAUGHT IN THE HEADLIGHTS'",'red')      
      




if __name__ == '__main__':
  accept()
Refuse.py (17 lines)
from main import sprint, sinput
def refuse():
    sprint('SO YOU REFUSED')
    sprint('VERY WELL')
    sprint('YOU WILL REMEMBER NONE OF THIS MATTER')
    sprint('-------------------------------------')
    sprint('*you wake up an hour later on the side of the street, confused of how you got there*')
    sprint("*you feel dizzy but it's not severe*")
    sprint('*your phone rings*')
    sprint("*your mom is calling you*")
    sprint('*you pick up your phone*')
    sprint('"---- WHERE ARE YOU"')


if __name__ == '__main__':
  refuse()
Share on LINE
Want your child to build games like this?

Our Python course is taught live, one-on-one, and every child builds a real project of their own just like these.