Python
from time import sleep

configuration_options = ['Create wall', 'Create passageway',
                         'Create start point', 'Create end point', \
                         'Exit to Main Menu']

maze_list = [] #stores the loaded maze or newly-created maze
controls = ['W', 'A', 'S', 'D', 'M'] #keys used for playing the game
movement = ['up', 'left', 'down', 'right', 'middle']
original_positions = [[-1, -1], [-1, -1]] #stores the initial positions of starting and ending characters of maze in the format of [[colA, rowA], [colB, rowB]]
starting_characters = []
current_positions = [0, 0] #stores the positions of starting character as it moves in the format of [colA, rowA]
new_coordinate = [0,0] #stores the coordinates of the element that the player wants to change

start_char = 'K' #starting point of maze
end_char = 'J' #ending point of maze
wall = 'I' #walls of maze
passageway = 'O' #passageways of maze

def print_main_menu():
    
    print ('                                                ⢀⣤⣄                                       ')
    print ('                                    ⠀⠀⠀⠀⠀⠀    ⢰⣿⣿⣿⣿⡆⣠⣶⣿⣶⡀                              ')
    print ('                ⠀⠀⠀                    ⠀⠀⠀    ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿                              ')
    print ('                                    ⠀⠀⠀⠀⠀⠀⠀    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏                              ')
    print ('                ⠀⠀⠀⠀⠀                    ⠀⠀    ⠈⣿⣿⣿⣿⣿⣿⣿⠋                               ')
    print ('                ⠀⠀ ⠀                        ⣾⣿⣿⣧ ⠻⣿⣿⠿⠉                                 ')
    print ('                                        ⣰⣿⣿⣿⣿⣿⣿⣿                                       ')
    print ('                                        ⠸⣿⣿⣿⣿⣿⣿⠏                                       ') 
    print ('                                    ⠀    ⠈⠛⠿⣿⣿⡟                                        ')
    print ()        
    print ('█░█ ▄▀█ █▀█ █▀█ █▄█   █░█ ▄▀█ █░░ █▀▀ █▄░█ ▀█▀ █ █▄░█ █▀▀ ▀ █▀   █▀▄ ▄▀█ █▄█')
    print ('█▀█ █▀█ █▀▀ █▀▀ ░█░   ▀▄▀ █▀█ █▄▄ ██▄ █░▀█ ░█░ █ █░▀█ ██▄ ░ ▄█   █▄▀ █▀█ ░█░')
    print ()
    print ('Welcome Kite! Happy Valentine\'s Day! This is specially made for you by Jo, hope you like it!')

def read_and_load_maze(maze_list):

    lines = ['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII',
             'IOOOOIIIIIOOOOOOOOIIIIIIIOOOOOOOOOOOOOOOOOIIOOOOOI',
             'IOIIOIIIIIOIIIOIIOOIIIIIOOIIOIIIIIIIIIIIIOIIOIIIOI',
             'IOIIOIIIIIOIIIOIIIOOIIIOOIIIOOOOOIIIIIIOOOOOOIIIOI',
             'IOIIOIIIIIOIIIOIIIIOOIOOIIIIOIIIIIIIIIOIIOIIOIIIOI',
             'IOIIOIIIIIOIIIOIIIIIOOOIIIIIOIIIIIIIIOIIIOIIOIIIOI',
             'IOIIOOOOOOOOOOOIIIIIIOIIIIIIOOOOOOIIIOOOOOIIOOOOOI',
             'IKIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJI']

    for line in lines:
        maze_row = list(line) #puts every character as an element in a list in the format of ['X','O','X'...]
        maze_list.append(maze_row) #the lists are then added to the maze_list, creating a nested list
        
    return maze_list

def view_maze(maze_list):
    
    print ('\n{:=<99}\n'.format(''))
    for line in range (len(maze_list)):
        for chars in range (len(maze_list[line])):
            print (maze_list[line][chars], end=' ')
        print('\n')
    print ()

def find_start_and_end_locations(maze_list, original_positions, current_positions, start_char, end_char):

    passageway_counter = 0
    starting_character = []
    
    for rows in range (len(maze_list)): 
        for col in range (len(maze_list[rows])):
            
            #the coordinates of the starting character are stored when the starting character is found
            if (maze_list[rows][col] == start_char):
                original_positions[0][0] = col
                original_positions[0][1] = rows
                current_positions[0] = original_positions[0][0]
                current_positions[1] = original_positions[0][1]
   
                
                starting_character.append(col)
                starting_character.append(rows)
                starting_characters.append(starting_character)
                starting_character = []
                
            #the coordinates of the ending character are stored when the ending character is found
            if (maze_list[rows][col] == end_char):
                original_positions[1][0] = col
                original_positions[1][1] = rows

            #counts the number of passageways
            if (maze_list[rows][col] == passageway):
                passageway_counter += 1

    return current_positions, original_positions, passageway_counter, starting_characters

def print_start_and_end_locations(start_char, end_char, current_positions):

    for coords in range (len(starting_characters)):
        print ('Location of Start ({}) = (Row {}, Column {})'.format(start_char, starting_characters[coords][1], starting_characters[coords][0])) #starting point changes constantly

    print ('Location of End ({}) = (Row {}, Column {})'.format(end_char, original_positions[1][1], original_positions[1][0])) #ending point remain the same
    print ()
    
    return original_positions, current_positions

def select_starting_point(current_positions, starting_characters):

    counter = 0

    try:
        if (len(starting_characters) > 1):
            start_point = input ('Please select the starting point e.g. Row,Column: ')
            start_point = start_point.split(',')
            current_positions[1] = int(start_point[0])
            current_positions[0] = int(start_point[1])

            for coords in range (len(starting_characters)):
                if (current_positions[0] == starting_characters[coords][0]):
                    if (current_positions[1] == starting_characters[coords][1]):
                        break
                    else:
                        print ('Invalid starting point. Please try again!')
                        select_starting_point(current_positions, starting_characters)
            
    except ValueError:
        print ('Please enter a valid coordinate.\n')
        select_starting_point(current_positions, starting_characters)

        
    return current_positions

def ask_to_move(controls, movement, current_positions, maze_list):

    exit_flag = False

    direction = input ('Press \'W\' for UP, \'A\' for LEFT, \'S\' for DOWN, \'D\' for RIGHT: ') 
    direction = direction.upper() #accepts lowercase inputs by converting lowercase to uppercase

    if (direction == controls[4]): #if player chooses to return to main menu
        maze_list[current_positions[1]][current_positions[0]] = passageway #changes the position of the starting character to a passageway
        maze_list[original_positions[0][1]][original_positions[0][0]] = start_char #returns the starting character to its original position

        #changes the coordinates of the starting character, where it stopped, to its original coordinates        
        current_positions[0] = original_positions[0][0] 
        current_positions[1] = original_positions[0][1]

        exit_flag = True #breaks the loop in the play maze option and continues the loop in main program

    return direction

def updated_current_position(direction, controls, start_char, current_positions, maze_list, passageway_counter):

    exit_flag = False
    time_taken = 0
 
    maze_list[current_positions[1]][current_positions[0]] = passageway #changes the previous starting character to a passageway   

    #updates the starting character based on the direction the player moves
    if (direction == controls[0]): #W: UP
        current_positions[1] -= 1 #row -= 1 
    elif (direction == controls[1]): #A: DOWN
        current_positions[0] -= 1 #col -= 1
    elif (direction == controls[2]): #S: LEFT
        current_positions[1] += 1 #row += 1
    elif (direction == controls[3]): #D: RIGHT
        current_positions[0] += 1 #col += 1
    elif (direction == 'E'):
        current_positions[1] -= 1
        current_positions[0] += 1
        
    #when the starting character reaches the ending point, starting character returns to its original position and calculates score and display leaderboard 
    if (maze_list[current_positions[1]][current_positions[0]] == end_char):

        #shows that starting character has reached the ending point
        maze_list[current_positions[1]][current_positions[0]] = start_char 
        view_maze(maze_list)

        maze_list[current_positions[1]][current_positions[0]] = end_char #returns the ending character to its original position

        print ('Congratulations! You have completed the game!\n')
        
        print ('Jo has something to tell you.')
        print ('Look at the maze carefully. Draw the path out!')
        print ('Enter the secret password to read Jo\'s message for you.')
        print ('Type in all capital letters and without space. (Hint: there are 7 letters.)')

        tryagain = True
        password = input ('Enter the password here: ')

        if (password == 'ILOVEJO'):
            tryagain = False

        while (tryagain):
            password = input ('Wrong password! Try again: ')

            if (password == 'ILOVEJO'):
                tryagain = False
            
        print ('Hehe XD I love you too, Kite! Thank you for loving me! I am really thankful to have met you. \n\
               Thank you for letting me know how it is like to be loved and to love someone. \n\
               I will cherish all the time that I have with you and remember all the times that we have spent together. \n\
               MUACKS! Happy Valentine\'s Day, my lover <3')
        print ()

        #changes the coordinates and positions of the starting character to its original coordinates
        current_positions[0] = original_positions[0][0]
        current_positions[1] = original_positions[0][1]
        maze_list[current_positions[1]][current_positions[0]] = start_char

        exit_flag = True #breaks the loop in the play maze option and continues the loop in main program

    #when the starting character hits the wall, start character does not move
    elif (maze_list[current_positions[1]][current_positions[0]] == wall):

        #changes the updated coordinates of the starting character to the previous coordinates based on the direction the player moves
        if (direction == controls[0]): #W: UP
            current_positions[1] += 1 #row += 1 
        elif (direction == controls[1]): #A: DOWN
            current_positions[0] += 1 #col += 1
        elif (direction == controls[2]): #S: LEFT
            current_positions[1] -= 1 #row -= 1
        elif (direction == controls[3]): #D: RIGHT
            current_positions[0] -= 1 #col -= 1
        
        maze_list[current_positions[1]][current_positions[0]] = start_char #updates the starting character in the maze_list

        print ('\nInvalid Movement. Please try again!')
            
    else:
        maze_list[current_positions[1]][current_positions[0]] = start_char #updates the starting character in the maze_list
            
    return current_positions, maze_list, exit_flag

def first_round(maze_list, original_positions, current_positions, \
                start_char, end_char, controls, movement, exit_flag):

    view_maze(maze_list) 
    current_positions, original_positions, passageway_counter, starting_characters = find_start_and_end_locations(maze_list, original_positions, current_positions, \
                                                                                             start_char, end_char) 
    print_start_and_end_locations(start_char, end_char, current_positions)
    
    current_positions = select_starting_point(current_positions, starting_characters)
        
    direction = ask_to_move(controls, movement, current_positions, maze_list) 
    
    if (direction != controls[4]): #if player did not return to main menu, update the position of start character
        current_positions, maze_list, exit_flag = updated_current_position(direction, controls, start_char, \
                                                                                       current_positions, maze_list, passageway_counter)

    return direction, exit_flag, passageway_counter

def next_few_rounds(maze_list, start_char, end_char, current_positions, direction, controls, movement, exit_flag, passageway_counter):
 
    while (maze_list[current_positions[1]][current_positions[0]] != end_char) and (direction != controls[4]):
        
        view_maze(maze_list) 
        print_start_and_end_locations(start_char, end_char, current_positions) 
        direction = ask_to_move(controls, movement, current_positions, maze_list) 
        
        if (direction != controls[4]): #if player did not return to main menu, update the position of start character
            current_positions, maze_list, exit_flag = updated_current_position(direction, controls, start_char, \
                                                                                           current_positions, maze_list, passageway_counter)

        if (exit_flag == True):
            break
        if (direction == controls[0]) or (direction == controls[1]) or (direction == controls[2]) or (direction == controls[3]) or \
           (direction == controls[4]): #checks if other keys are entered
            pass
        elif (direction == controls[4]): #if main menu is selected
            break
        else: #if other keys are selected
            print ('\nInvalid Movement. Please Try again!')

    
    return direction, exit_flag

def fun_element():
    print ('Ready?')
    sleep (2)
    print ('Get Set.')
    sleep (1)
    print ('GO!')

def main_program(maze_list, original_positions, current_positions, start_char, end_char, controls, movement):

    while (True):
        
        exit_flag = False

        print_main_menu()
        print ()
        start = input('Type \'Happy Valentines Day!\' to start!\n')

        if (start == 'Happy Valentines Day!'):
            print ()
            print ('This is a maze game.\nThe starting point is \'K\' and ending point is \'J\'.\nThe walls are \'I\' and the path that you can take is \'O\'.')
            print ()
            howtoplay = input('Type \'I am ready!!!\' to start!\n')
            if (howtoplay == 'I am ready!!!'):
                maze_list = read_and_load_maze(maze_list)                
                view_maze(maze_list)

                fun_element()
                            
                direction, exit_flag, passageway_counter = first_round(maze_list, original_positions, current_positions, \
                                                                       start_char, end_char, controls, movement, exit_flag)
                if (exit_flag == True):
                    break
                if (direction == controls[0]) or (direction == controls[1]) or (direction == controls[2]) or (direction == controls[3]) or \
                   (direction == controls[4]): #checks if other keys are entered
                    pass
                elif (direction == controls[4]): #if main menu is selected
                    break
                else: #prompts again if other keys are selected
                    print ('\nInvalid Movement. Please Try again!')
                    direction, exit_flag, passageway_counter = first_round(maze_list, original_positions, current_positions, \
                                                                                       start_char, end_char, controls, movement, exit_flag)

                next_few_rounds(maze_list, start_char, end_char, current_positions, direction, \
                                controls, movement, exit_flag, passageway_counter)
                               
            else:
                print ()
                print ('You are not ready. Byebye! \nType exactly \'I am ready!!!\' to start!\n')
                break
            
        else:
            print('Type exactly \'Happy Valentines Day!\' to start!')

        print ()


main_program(maze_list, original_positions, current_positions, start_char, end_char, controls, movement)
⢀⣤⣄                                       
                                    ⠀⠀⠀⠀⠀⠀    ⢰⣿⣿⣿⣿⡆⣠⣶⣿⣶⡀                              
                ⠀⠀⠀                    ⠀⠀⠀    ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿                              
                                    ⠀⠀⠀⠀⠀⠀⠀    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏                              
                ⠀⠀⠀⠀⠀                    ⠀⠀    ⠈⣿⣿⣿⣿⣿⣿⣿⠋                               
                ⠀⠀ ⠀                        ⣾⣿⣿⣧ ⠻⣿⣿⠿⠉                                 
                                        ⣰⣿⣿⣿⣿⣿⣿⣿                                       
                                        ⠸⣿⣿⣿⣿⣿⣿⠏                                       
                                    ⠀    ⠈⠛⠿⣿⣿⡟                                        

█░█ ▄▀█ █▀█ █▀█ █▄█   █░█ ▄▀█ █░░ █▀▀ █▄░█ ▀█▀ █ █▄░█ █▀▀ ▀ █▀   █▀▄ ▄▀█ █▄█
█▀█ █▀█ █▀▀ █▀▀ ░█░   ▀▄▀ █▀█ █▄▄ ██▄ █░▀█ ░█░ █ █░▀█ ██▄ ░ ▄█   █▄▀ █▀█ ░█░

Welcome Kite! Happy Valentine's Day! This is specially made for you by Jo, hope you like it!

Type exactly 'Happy Valentines Day!' to start!

                                                ⢀⣤⣄                                       
                                    ⠀⠀⠀⠀⠀⠀    ⢰⣿⣿⣿⣿⡆⣠⣶⣿⣶⡀                              
                ⠀⠀⠀                    ⠀⠀⠀    ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿                              
                                    ⠀⠀⠀⠀⠀⠀⠀    ⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏                              
                ⠀⠀⠀⠀⠀                    ⠀⠀    ⠈⣿⣿⣿⣿⣿⣿⣿⠋                               
                ⠀⠀ ⠀                        ⣾⣿⣿⣧ ⠻⣿⣿⠿⠉                                 
                                        ⣰⣿⣿⣿⣿⣿⣿⣿                                       
                                        ⠸⣿⣿⣿⣿⣿⣿⠏                                       
                                    ⠀    ⠈⠛⠿⣿⣿⡟                                        

█░█ ▄▀█ █▀█ █▀█ █▄█   █░█ ▄▀█ █░░ █▀▀ █▄░█ ▀█▀ █ █▄░█ █▀▀ ▀ █▀   █▀▄ ▄▀█ █▄█
█▀█ █▀█ █▀▀ █▀▀ ░█░   ▀▄▀ █▀█ █▄▄ ██▄ █░▀█ ░█░ █ █░▀█ ██▄ ░ ▄█   █▄▀ █▀█ ░█░

Welcome Kite! Happy Valentine's Day! This is specially made for you by Jo, hope you like it!


This is a maze game.
The starting point is 'K' and ending point is 'J'.
The walls are 'I' and the path that you can take is 'O'.


You are not ready. Byebye! 
Type exactly 'I am ready!!!' to start!