Red Light, Green Light Game using Python

In this post, we will discuss how to create a python program to replicate the popular Red light Green light game from squid games, for all those who don’t know the rules let me explain them to you

All the players start from one point and have to run to the ending point, sounds simple but there is a big catch at the end lines there is a doll that hides for some time (green light) you have to run towards the doll in that time and when she turns (Red Light) you have to stay still if she detects any motion you are out

Now that you have understood the rules of the game let me give you brief

Code Explanation

First Lets create a Intro Screen that will have a button to start the game

from tkinter import *

root=Tk()
root.geometry("500x600")

b3=Button(root,text="Start Game",command=first_func)
b3.place(x=120,y=10)

root.mainloop()

root is the Tkinter instance variable, we are specifying the geometry (height and width ) using .geometry() class, then we are creating a single button with text as “Start Game” and the function that this button will trigger is first_func, this function will start our game, now lets see what’s inside this function

import threading

def first_func():
    root.destroy()
    t=threading.Thread(target=end_Gui)
    t.start()
    print("first function running")
    detect()

First of all this function will destroy the previous Tkinter GUI by using .destroy() command then we will create Two processes running parallelly the first one is our main game process and the second one is a GUI with a button that the user will press when he/she passes the ending line and the game will be stoped, currently this game is made only for one player but i will keep editing this post to make changes, the first process is running in detect() function and the second process is running in end_Gui() function, let’s see what’s inside detect function

import cv2
import numpy as np
import time
from time import sleep
from tkinter import *
from tkinter import messagebox
import threading
import os


def detect(): 
    delay=20*1   ###for 1 minutes delay 
    close_time=time.time()+delay
    cap = cv2.VideoCapture(0)


    ret, frame1 = cap.read()
    ret, frame2 = cap.read()

    while cap.isOpened():
        diff = cv2.absdiff(frame1, frame2)
        gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
        blur = cv2.GaussianBlur(gray, (5,5), 0)
        _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY)
        dilated = cv2.dilate(thresh, None, iterations=3)
        contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            if cv2.contourArea(contour) < 900:
                print("in frame")
                continue
            messagebox.showinfo("showinfo", "You are caught")
            os._exit(1)           
        cv2.imshow("feed", frame1)
        frame1 = frame2
        ret, frame2 = cap.read()

        if time.time()>close_time:
            break

    cv2.destroyAllWindows()
    cap.release()
    main_loop_func()

firstly let’s import all the packages that we want to use in our program most of them comes preinstalled with python but a couple of them needs installation, you can install them by writing pip install package name in the command prompt

after we have installed and imported the packages lets first define a few variables

  • delay : time you want red light or motion detetction to work (measured in seconds)
  • close_time : time we want our motion detection to stop and let the players move again
  • cap : we are taking input from our webcam and the raw data is stored in cap variable
  • frame1,frame2 : these are the two reference frames , lets understand it this way we take a still image of a room and name it frame1 , then we take another still frame after 1 sec and name it frame2 if there is a difference in frame1 and frame2 we will conclude that indeed there was a motion

after we got the input from the webcam we will create an infinite loop that will run as long as our webcam is sending us the video,after we have a few more variables that are performing some tasks let’s discuss them

  • diff : this variable will store the value of whether there is any differnce between frame1 and frame2 we will do this using .absdiff() class from opencv (parameters are two still frames)
  • gray : after we got the difference we will convert it to grayscale soo that the feature detection is easier we will use .cvtColor() class from opencv and the parameters are (first the image you want convert into grayscale and second is cv2.COLOR_BGR2GRAY method)
  • blur : After doing grayscale we need to apply some blur this is basically done to remove noise we are using gaussian blue and these are the parameters
    • image that we want to apply blur to
    • size of the blur kernel (kernal is basically a mattrix that user has to define and kernal depends on type of blur we are performing )
    • value of sigmax
  • thresh : this variable will store whether the movement has crossed the threshhold value or not we will do this using the cv2.threshold() , this class will have the following parameters
    • image we want to find threshhold in
    • minimum threshhold value
    • maximum threshhold value
    • type of algorith we will use for deciding threshhold ,here we are using cv2.THRESH_BINARY
  • dilated : after defining the threshhold we need to prepare our image to find better contours we will do this by dilating the image using .dilate() class from opencv, arguments in dilate method are
    • image you want perform dilation
    • kernal for dilation
    • number of iterations
  • contours : then we will find contours on our dilated image by using .findContours() method of opencv it has the following arguments
    • dilated image on which you want to find the contours
    • mode of finding the contours
    • method of finding the contours

After we found contours we need to create a for loop for each contour and check if they are above a certain limit then we will raise the message that “you are caught “, os._exit(1) is a terminal command that will kill the entire program as the game is over

and if there is no movement we will display output to the user using .imshow() method of OpenCV, we will assign new values to frame1 and frame2 variables to continue the process once again

then we will add exit condition to which is true when the delay time is over (or red light time is over ) and we want the motion detection to turn off soo that the players can run to the finishing line at the end we will call main_loop_func() it will restart the motion detection after a certain time

def main_loop_func():
    while True:
        sleep(20)
        detect()

we will create an infinite loop that will run motion detection as many times as you want but before restarting the function it will add a 20-second delay which is our green light for players to run, soo this was about the motion detection and what will happen if you are caught but what about the win, how can a player declare their win it’s pretty simple, remember in the first_func() we have created a separate thread which was triggering end_Gui function yeah its there for players to declare their win, let’s see how it works

def end_Gui():
    root1=Tk()
    root1.geometry("500x600")

    b3=Button(root1,text="Finish Game",command=finsh_game)
    b3.place(x=120,y=10)

    root1.mainloop()

It’s pretty simple we will create a new Tkinter Gui and it will have a single button that the user has to press to declare that he/she won, and this wraps up this program if you have any questions comment down,if you want to see the whole code all together you can visit my Github page or copy-paste from below

import cv2
import numpy as np
import time
from time import sleep
from tkinter import *
from tkinter import messagebox
import threading
import os


def detect(): 
    delay=20*1   ###for 1 minutes delay 
    close_time=time.time()+delay
    cap = cv2.VideoCapture(0)


    ret, frame1 = cap.read()
    ret, frame2 = cap.read()

    while cap.isOpened():
        diff = cv2.absdiff(frame1, frame2)
        gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
        blur = cv2.GaussianBlur(gray, (5,5), 0)
        _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY)
        dilated = cv2.dilate(thresh, None, iterations=3)
        contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            if cv2.contourArea(contour) < 900:
                print("in frame")
                continue
            messagebox.showinfo("showinfo", "You are Dead")
            os._exit(1)           
        cv2.imshow("feed", frame1)
        frame1 = frame2
        ret, frame2 = cap.read()

        if time.time()>close_time:
            break

        key=cv2.waitKey(1)
        if key==ord('q'):
          break

    cv2.destroyAllWindows()
    cap.release()
    main_loop_func()


def finsh_game():
    messagebox.showinfo("showinfo", "You Won")
    os._exit(1)

def end_Gui():
    root1=Tk()
    root1.geometry("500x600")

    b3=Button(root1,text="open file",command=finsh_game)
    b3.place(x=120,y=10)

    root1.mainloop()


def main_loop_func():
    while True:
        sleep(20)
        detect()


def first_func():
    root.destroy()
    t=threading.Thread(target=end_Gui)
    t.start()
    print("first function running")
    detect()
    

root=Tk()
root.geometry("500x600")

b3=Button(root,text="open file",command=first_func)
b3.place(x=120,y=10)

root.mainloop()

About the author

Harshit

Hey, I'am Harshit Roy, a programmer with an obsession of learning new things, this blog is dedicated to helping people to learn programming fun way by creating projects

View all posts