2
\$\begingroup\$

This is a game in which a sequence of 4 characters is displayed to the player, one at a time with a delay between them. Then the player must input that sequence as it was displayed.

Sequences are displayed until input is incorrect.

The characters composing the sequences are chosen at random and they are all lines.

__all__ = []
import random
import time
from colorama import deinit, init
MSG_ASK = 'What was the sequence? '
MSG_CORRECT = '033円[32mCorrect!033円[0m'
MSG_INCORRECT = '033円[31mIncorrect033円[0m'
def main():
 k = 4
 lines = r'|\-/'
 seconds = 1
 init()
 while True:
 s = ''
 sequence = random.choices(lines, k=k)
 sequence = ''.join(sequence)
 for i in range(k):
 if not i:
 s = ''
 elif i == 1:
 s = ' '
 else:
 s = i * ' '
 print(s, sequence[i], end='\r')
 time.sleep(seconds)
 print(f'{s} ')
 if input(MSG_ASK) == sequence:
 print(MSG_CORRECT)
 else:
 print(MSG_INCORRECT)
 break
 deinit()
if __name__ == '__main__':
 main()
AJNeufeld
35.2k5 gold badges41 silver badges103 bronze badges
asked Feb 12, 2021 at 12:14
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Using __all__ = [] is mostly useless in the main program, and should probably be removed.


This is hard to read:

MSG_CORRECT = '033円[32mCorrect!033円[0m'
MSG_INCORRECT = '033円[31mIncorrect033円[0m'

This is much easier:

from colorama import Fore
MSG_CORRECT = Fore.GREEN + 'Correct!' + Fore.RESET
MSG_INCORRECT = Fore.RED + 'Incorrect' + Fore.RESET

Note: Style.RESET_ALL would be an exact translation of 033円[0m. Adjust as desired.


You could pull your loop body out into separate functions:

def generate_random_sequence(length: int, characters: str) -> str:
 """
 Generate a random sequence of characters.
 """
 return ''.join(random.choices(characters, k=length))
def show_sequence(sequence: str, seconds_per_character: float) -> None:
 """
 Display a sequence to the user, one character at a time, on one line,
 using the given delay between characters.
 After the last character has been shown, clear the line.
 """
 for i, ch in enumerate(sequence):
 print(' ' * i, ch, end='\r')
 time.sleep(seconds_per_character)
 print(' ' * len(sequence), ' ')

I've done several things here:

  • type-hints and a """docstring""" have been added
  • sequence is computed in one step
  • removed the s variable, since it can be directly computed as ' ' * i
  • looped directly over the sequence, using enumerate to keep track of the index.
  • speed, length and characters are all arguments to the functions, so the challenge could become programmatically harder (ie, faster or longer)

With the above function, the main loop becomes simpler:

def main():
 k = 4
 lines = r'|\-/'
 seconds = 1
 init()
 while True:
 sequence = generate_random_sequence(k, lines)
 show_sequence(sequence, seconds)
 guess = input(MSG_ASK)
 if guess == sequence:
 print(MSG_CORRECT)
 else:
 print(MSG_INCORRECT)
 break
 deinit()
answered Feb 13, 2021 at 0:04
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.