diff --git a/README.md b/README.md index 47d0b41d4..46269a0ba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@
# Project Name +ThrillTyper [![Report Issue on Jira](https://img.shields.io/badge/Report%20Issues-Jira-0052CC?style=flat&logo=jira-software)](https://temple-cis-projects-in-cs.atlassian.net/jira/software/c/projects/DT/issues) [![Deploy Docs](https://github.com/ApplebaumIan/tu-cis-4398-docs-template/actions/workflows/deploy.yml/badge.svg)](https://github.com/ApplebaumIan/tu-cis-4398-docs-template/actions/workflows/deploy.yml) [![Documentation Website Link](https://img.shields.io/badge/-Documentation%20Website-brightgreen)](https://applebaumian.github.io/tu-cis-4398-docs-template/) @@ -11,27 +12,46 @@ ## Keywords -Section #, as well as any words that quickly give your peers insights into the application like programming language, development platform, type of application, etc. +Section 4 +Python +React +Type Racing +Web Application ## Project Abstract -This document proposes a novel application of a text message (SMS or Email) read-out and hands-free call interacted between an Android Smartphone and an infotainment platform (headunit) in a car environment. When a phone receives an SMS or Email, the text message is transferred from the phone to the headunit through a Bluetooth connection. On the headunit, user can control which and when the received SMS or E-mail to be read out through the in-vehicle audio system. The user may press one button on the headunit to activate the hands-free feature to call back the SMS sender. +Welcome to the exciting world of ThrillTyper – a cutting-edge typing racer game that's here to make typing fun and competitive. This game is an online web application that offers various single player modes including a robot opponent mode, custom mode, and dynamic race mode, private online multiplayer, and public online multiplayer. In multiplayer each race is composed of up to ten racers, and in online multiplayer the host of the game shall have the option between two to ten competitors. Metrics for each race shall be logged to each user’s account including words-per-minute (wpm), time, and accuracy, however, if the player has no account they shall be playing as a guest with no saved data. Participants shall be able to register accounts, join typing races, and compete in real-time against each other. The game shall feature a user-friendly interface built with JavaScript, a backend powered by Flask, and WebSocket technology for seamless real-time communication. The game shall include user authentication, race creation, and a dynamic leaderboard to showcase the fastest typists. ## High Level Requirement -Describe the requirements – i.e., what the product does and how it does it from a user point of view – at a high level. +ThrillTyper is the ultimate typing challenge, offering players an array of modes to engage with. In robot opponent mode, users will see the robot’s progress typing against them and their own metrics. Custom mode will allows users to input texts, select genres, and select between words and sentences. Dynamic race mode will analyze the user’s last few sentences typed and their metrics to generate a few new lines based on that data and what AI deems best to generate. While online multiplayer provides the thrill of real-time competition with two to ten players hosted by a game master. Key metrics, such as words-per-minute (wpm), time, and accuracy, shall be shown in game and meticulously logged for each user, creating a personalized experience. Whether you're a registered user tracking your progress or a guest enjoying the rush, ThrillTyper ensures an exciting typing adventure for everyone. ## Conceptual Design -Describe the initial design concept: Hardware/software architecture, programming language, operating system, etc. +The initial design concept envisions a software architecture where the frontend, developed using JavaScript, provides a user-friendly interface for interaction. The backend is powered by Flask, a framework written in Python, serving as a robust foundation for text generation, multiplayer connection handling and user data handling. Real-time communication is facilitated through WebSocket technology, ensuring dynamic multiplayer experience. The software stack is designed for compatibility with standard web browsers, making it accessible across various operating systems. The development process adheres to industry best practices, utilizing Git for version control and collaborative development. ## Background -The background will contain a more detailed description of the product and a comparison to existing similar projects/products. A literature search should be conducted and the results listed. Proper citation of sources is required. If there are similar open-source products, you should state whether existing source will be used and to what extent. If there are similar closed-source/proprietary products, you should state how the proposed product will be similar and different. +ThrillTyper seeks to distinguish itself through the incorporation of real-time multiplayer capabilities, a dynamic leaderboard, and an emphasis on performance metrics tracking. Proprietary products like "TypeRacer" and "Nitro Type" were also scrutinized for their user engagement features and various capabilities. In crafting ThrillTyper, the aim is not only to offer a unique and thrilling game experience but also to strategically position the product by leveraging successful elements observed in existing projects while introducing innovative differentiators like Robot Opponent Mode and Dynamic Text Generation that cater to a broader user base. ## Required Resources -Discuss what you need to develop this project. This includes background information you will need to acquire, hardware resources, and software resources. If these are not part of the standard Computer Science Department lab resources, these must be identified early and discussed with the instructor. +This is a software-dominant project with zero outside hardware requirements. The Visual Studio Code IDE shall be the biggest requirement to program in JavaScript and Python. Experience with Python Flask and JavaScript shall be helpful. A computer or server provider shall be needed to act as a server to host the application. + +## Implemented Features + +Single Player - basic timed gameplay +Robot Opponent Mode - competing against a simulated opponent with difficulties of either easy, medium, or hard +Custom Mode - allows user to choose genre for words to type or input a blurb of their own to type +User Systems - accounts, logging in, dashboard, and leaderboard +Dynamic Mode - generates an easy blurb for the user to type initially and based on the WPM the users has for that it generates a new blurb, and this goes on until time runs out + +## Known Bugs + +### Release 1.0 + +1. Dynamic Text Generation does not allow the user to advance if they type two spaces in a row after finishing their last blurb +2. Multiplayer does not synchronize gameplay so that the match ends when one player has finished the race ## Collaborators @@ -87,6 +107,13 @@ Discuss what you need to develop this project. This includes background informat Allen Abraham + + + tuk04440 +
+ Allen Abraham +
+ diff --git a/test.py b/test.py index 4f8abe54d..311b07be1 100644 --- a/test.py +++ b/test.py @@ -61,7 +61,7 @@ def test_valid_login(client): response = client.post( "/authentication", data={"username": username, "password": password}) print(response.status_code) - assert "/" == response.location + assert "/#/menu" == response.location def test_continue_as_guest(client): @@ -141,10 +141,10 @@ def test_generate_text_word_list(client): def test_generate_dynamic(client): """ - Test: That dynamic text generation endpoint can take in WPM and accuracy and generate words using that data + Test: That text generation endpoint can take in WPM and generate words using that data Result: True if the endpoint responds with successful status code and responds with enough words to fill two lines """ - response = client.get("/generate_dynamic/?wpm=53&accuracy=70") + response = client.get("/generate_text/?wpm=53") assert response.status_code==200 word_lst = response.data.decode('utf-8').split(" ") assert len(word_lst)>=10 @@ -543,7 +543,7 @@ def test_generate_text(self): Test: Ensure that text is generate successfully given valid input Result: True when: if given valid input, the invalid argument message is not returned, or if invalid input is given, then the invalid argument message is returned """ - assert "Invalid arguments or missing arguments." not in Text_Generator.generate_text( + assert "An error occurred, check the file name and the parameters." not in Text_Generator.generate_text( "hard", "words", 20) - assert "Invalid arguments or missing arguments." in Text_Generator.generate_text( + assert "An error occurred, check the file name and the parameters." in Text_Generator.generate_text( "what", "no way buddy", 3) diff --git a/text_generator.py b/text_generator.py index 7e8c186bb..f2aa02e35 100644 --- a/text_generator.py +++ b/text_generator.py @@ -1,18 +1,17 @@ from random import randint LEN_OF_LONGEST_WORD = 22 - +LEFT_SIDE = "qwert|asdfg|zxcv" +LEFT_ROW2_START = LEFT_SIDE.find('|') +LEFT_ROW3_START = LEFT_SIDE.find('|', LEFT_ROW2_START+1) +RIGHT_SIDE = "poiuy|lkjh|mnb" +RIGHT_ROW2_START = RIGHT_SIDE.find('|') +RIGHT_ROW3_START = RIGHT_SIDE.find('|', RIGHT_ROW2_START+1) +PINKIE_CHARS = "qaz" class Text_Generator: """ Responsible for generating text for a game to use and also separating words into different difficulties (the latter is done outside of run time) """ - LEFT_SIDE = "qwert|asdfg|zxcv" - LEFT_ROW2_START = LEFT_SIDE.find('|') - LEFT_ROW3_START = LEFT_SIDE.find('|', LEFT_ROW2_START+1) - RIGHT_SIDE = "poiuy|lkjh|mnb" - RIGHT_ROW2_START = RIGHT_SIDE.find('|') - RIGHT_ROW3_START = RIGHT_SIDE.find('|', RIGHT_ROW2_START+1) - PINKIE_CHARS = "qaz" def get_txt_list(file) -> list[str]: """ @@ -41,17 +40,17 @@ def score_word_typing_difficulty(self, word) -> int: while i < len(word): has_next_char = i+1 < len(word) # checking edge chars - if word[i] in self.PINKIE_CHARS: + if word[i] in PINKIE_CHARS: score += 0.25 if has_next_char and word[i+1] == word[i]: i += 1 # checking direct verticals and consecutive side switches has_next_char = i+1 < len(word) if has_next_char: - curr_word_left_ind = self.LEFT_SIDE.find(word[i]) - next_word_left_ind = self.LEFT_SIDE.find(word[i+1]) - curr_word_right_ind = self.RIGHT_SIDE.find(word[i]) - next_word_right_ind = self.RIGHT_SIDE.find(word[i+1]) + curr_word_left_ind = LEFT_SIDE.find(word[i]) + next_word_left_ind = LEFT_SIDE.find(word[i+1]) + curr_word_right_ind = RIGHT_SIDE.find(word[i]) + next_word_right_ind = RIGHT_SIDE.find(word[i+1]) if (curr_word_left_ind == -1 and next_word_left_ind != -1) or (curr_word_left_ind != -1 and next_word_left_ind == -1): side_switches += 1 else: @@ -79,11 +78,11 @@ def is_direct_vertical(self, curr_char_keyboard_pos, nxt_char_keyboard_pos, is_l """ if (curr_char_keyboard_pos != -1 and nxt_char_keyboard_pos != -1): # standardize the rows - row2_start = self.RIGHT_ROW2_START - row3_start = self.RIGHT_ROW3_START + row2_start = RIGHT_ROW2_START + row3_start = RIGHT_ROW3_START if is_left: - row2_start = self.LEFT_ROW2_START - row3_start = self.LEFT_ROW3_START + row2_start = LEFT_ROW2_START + row3_start = LEFT_ROW3_START if curr_char_keyboard_pos > row3_start: curr_char_keyboard_pos -= row3_start elif curr_char_keyboard_pos > row2_start: @@ -162,8 +161,3 @@ def generate_text(difficulty: str, form: str, amount: int, genre: str = None): except Exception as e: print(f"Error: {e}") return "An error occurred, check the file name and the parameters." - - -if __name__ == "__main__": - tg = Text_Generator() - tg.sort_words_by_difficulty(tg.get_txt_list("words.txt"))