From bf6cddf30a2a550031b91d7e8b6cf126851a92ad Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Thu, 30 Sep 2021 13:19:44 +0800 Subject: [PATCH 001/272] Set theme jekyll-theme-hacker --- docs/_config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/_config.yml diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000000..fc24e7a62d --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-hacker \ No newline at end of file From 7b71ae0604965c9e5b98360de9e0a3ba1eef31ad Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 3 Oct 2021 14:26:48 +0800 Subject: [PATCH 002/272] Add Lim Jia Jing details in AboutUs.md. Remove fifth row in AboutUs.md. --- docs/AboutUs.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..de0ed93cb7 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,8 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 8f70bab74a590b6fccc7f2b5544a44c66c0279dc Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Tue, 5 Oct 2021 21:44:43 +0800 Subject: [PATCH 003/272] update about us Updated my section in AboutUs.md. Created my md page in docs --- build.gradle | 1 + docs/AboutUs.md | 2 +- docs/team/lusicheng.md | 0 src/main/java/seedu/duke/Duke.java | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 docs/team/lusicheng.md diff --git a/build.gradle b/build.gradle index b0c5528fb5..5e2d6e2c45 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'application' id 'checkstyle' + //check coding style and format id 'com.github.johnrengelman.shadow' version '5.1.0' } diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..d93e3c056a 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) diff --git a/docs/team/lusicheng.md b/docs/team/lusicheng.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..da6156c498 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,6 +1,6 @@ package seedu.duke; -import java.util.Scanner; +import java.util.*; public class Duke { /** From 86003c4f82dbfac50c62462d902714700fe2ddcf Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Tue, 5 Oct 2021 21:46:40 +0800 Subject: [PATCH 004/272] Initialise Personal page --- docs/team/lusicheng.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/team/lusicheng.md b/docs/team/lusicheng.md index e69de29bb2..83b10f9210 100644 --- a/docs/team/lusicheng.md +++ b/docs/team/lusicheng.md @@ -0,0 +1,6 @@ +# Lu Sicheng - Project Portfolio Page + +## Overview + + +### Summary of Contributions From 323bc6a1e6c9454693a54b89eb5e922e9feb5a9d Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Tue, 5 Oct 2021 21:48:12 +0800 Subject: [PATCH 005/272] Update profile image --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index d93e3c056a..d8d325b1ce 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) +![image](https://user-images.githubusercontent.com/69776265/136035789-60431999-0190-4967-948f-e936065e8275.png) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From bac86b5817765ec55d73877e85cb2904b6a21f71 Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Tue, 5 Oct 2021 21:49:35 +0800 Subject: [PATCH 006/272] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index d8d325b1ce..6fe98b6157 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![image](https://user-images.githubusercontent.com/69776265/136035789-60431999-0190-4967-948f-e936065e8275.png) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) +![image](https://user-images.githubusercontent.com/69776265/136035789-60431999-0190-4967-948f-e936065e8275.png=50x20) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 85b2c4af46282372fb31926d9e147e89c15dedfe Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Tue, 5 Oct 2021 21:50:00 +0800 Subject: [PATCH 007/272] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 6fe98b6157..ec3dbd4898 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![image](https://user-images.githubusercontent.com/69776265/136035789-60431999-0190-4967-948f-e936065e8275.png=50x20) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) +![image](https://user-images.githubusercontent.com/69776265/136035789-60431999-0190-4967-948f-e936065e8275.png =100x100) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 87d0061a2806247511a8235cb0812e5f9d86b0d9 Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Tue, 5 Oct 2021 21:52:55 +0800 Subject: [PATCH 008/272] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index ec3dbd4898..88eb0bf162 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![image](https://user-images.githubusercontent.com/69776265/136035789-60431999-0190-4967-948f-e936065e8275.png =100x100) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) + | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From cf9717b8f54c91f68e7e8319603c050d579fbfc0 Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Wed, 6 Oct 2021 10:21:05 +0800 Subject: [PATCH 009/272] Update Duke.java --- src/main/java/seedu/duke/Duke.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index da6156c498..5c74e68d59 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,6 +1,6 @@ package seedu.duke; -import java.util.*; +import java.util.Scanner; public class Duke { /** From f5a84406c462b7dbd88833a78551485b26ada00a Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Wed, 6 Oct 2021 10:21:40 +0800 Subject: [PATCH 010/272] Update build.gradle --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5e2d6e2c45..b0c5528fb5 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,6 @@ plugins { id 'java' id 'application' id 'checkstyle' - //check coding style and format id 'com.github.johnrengelman.shadow' version '5.1.0' } From 29ab203069c6863624e0e9458a42532a04b46b6c Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Wed, 6 Oct 2021 12:21:19 +0800 Subject: [PATCH 011/272] About Zhansen --- docs/AboutUs.md | 3 +-- docs/team/shizhansen.md | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 docs/team/shizhansen.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 2a604c59d0..8385471bf9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -4,6 +4,5 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/johndoe.md) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +| Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](docs/team/shizhansen.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) diff --git a/docs/team/shizhansen.md b/docs/team/shizhansen.md new file mode 100644 index 0000000000..0d2004b781 --- /dev/null +++ b/docs/team/shizhansen.md @@ -0,0 +1,6 @@ +# Shi Zhansen - Project Portfolio Page + +## Overview + + +### Summary of Contributions From 3be87d52675906fcab5af65a1697183b4228fe8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 7 Oct 2021 12:34:13 +0800 Subject: [PATCH 012/272] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8385471bf9..d598659f0b 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -5,4 +5,4 @@ Display | Name | Github Profile | Portfolio ![](https://via.placeholder.com/100.png?text=Photo) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/johndoe.md) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) | Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](docs/team/shizhansen.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://avatars.githubusercontent.com/u/58932649?v=4) | William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](docs/team/williamwahyudi.md) From a53aa6288c33c2294d7eb2a584f9f496a701a9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 7 Oct 2021 12:35:21 +0800 Subject: [PATCH 013/272] Create AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index d598659f0b..9d40eefe9d 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -5,4 +5,4 @@ Display | Name | Github Profile | Portfolio ![](https://via.placeholder.com/100.png?text=Photo) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/johndoe.md) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) | Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](docs/team/shizhansen.md) -![](https://avatars.githubusercontent.com/u/58932649?v=4) | William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](docs/team/williamwahyudi.md) +| William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](docs/team/williamwahyudi.md) From b74078a17cc218ea370fb69975a717bfef4a2118 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 8 Oct 2021 21:52:46 +0800 Subject: [PATCH 014/272] project skeleton --- TypingGame.txt | 0 .../{duke/Duke.java => TypingGame/Main.java} | 4 +- .../seedu/TypingGame/commands/NewGame.java | 7 + .../seedu/TypingGame/common/Messages.java | 18 ++ .../java/seedu/TypingGame/common/Utils.java | 13 ++ .../java/seedu/TypingGame/data/GamerInfo.java | 14 ++ .../exception/FaultyInputException.java | 4 + .../exception/InvalidCommandException.java | 4 + .../java/seedu/TypingGame/parser/Parser.java | 9 + .../seedu/TypingGame/storage/StorageFile.java | 8 + src/main/java/seedu/TypingGame/ui/TextUi.java | 174 ++++++++++++++++++ src/test/java/seedu/{duke => }/DukeTest.java | 2 +- 12 files changed, 254 insertions(+), 3 deletions(-) create mode 100644 TypingGame.txt rename src/main/java/seedu/{duke/Duke.java => TypingGame/Main.java} (92%) create mode 100644 src/main/java/seedu/TypingGame/commands/NewGame.java create mode 100644 src/main/java/seedu/TypingGame/common/Messages.java create mode 100644 src/main/java/seedu/TypingGame/common/Utils.java create mode 100644 src/main/java/seedu/TypingGame/data/GamerInfo.java create mode 100644 src/main/java/seedu/TypingGame/exception/FaultyInputException.java create mode 100644 src/main/java/seedu/TypingGame/exception/InvalidCommandException.java create mode 100644 src/main/java/seedu/TypingGame/parser/Parser.java create mode 100644 src/main/java/seedu/TypingGame/storage/StorageFile.java create mode 100644 src/main/java/seedu/TypingGame/ui/TextUi.java rename src/test/java/seedu/{duke => }/DukeTest.java (90%) diff --git a/TypingGame.txt b/TypingGame.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/TypingGame/Main.java similarity index 92% rename from src/main/java/seedu/duke/Duke.java rename to src/main/java/seedu/TypingGame/Main.java index 5c74e68d59..db24c4b7bf 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/TypingGame/Main.java @@ -1,8 +1,8 @@ -package seedu.duke; +package seedu.TypingGame; import java.util.Scanner; -public class Duke { +public class Main { /** * Main entry-point for the java.duke.Duke application. */ diff --git a/src/main/java/seedu/TypingGame/commands/NewGame.java b/src/main/java/seedu/TypingGame/commands/NewGame.java new file mode 100644 index 0000000000..15fa5fb383 --- /dev/null +++ b/src/main/java/seedu/TypingGame/commands/NewGame.java @@ -0,0 +1,7 @@ +package seedu.TypingGame.commands; + +/* + * commands to initiate a new game. + */ +public class NewGame { +} diff --git a/src/main/java/seedu/TypingGame/common/Messages.java b/src/main/java/seedu/TypingGame/common/Messages.java new file mode 100644 index 0000000000..5ef1e39744 --- /dev/null +++ b/src/main/java/seedu/TypingGame/common/Messages.java @@ -0,0 +1,18 @@ +package seedu.TypingGame.common; + +/** + * Container for user visible messages. + */ +public class Messages { + + public static final String MESSAGE_GOODBYE = "Good bye!"; + public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; + public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; + public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; + public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; + public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " + + "java seedu.TypingGame.Main [STORAGE_FILE_PATH]"; + public static final String MESSAGE_WELCOME = "Welcome to Typing Game!"; + public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; +} diff --git a/src/main/java/seedu/TypingGame/common/Utils.java b/src/main/java/seedu/TypingGame/common/Utils.java new file mode 100644 index 0000000000..339c6c75ab --- /dev/null +++ b/src/main/java/seedu/TypingGame/common/Utils.java @@ -0,0 +1,13 @@ +package seedu.TypingGame.common; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * Utility methods + */ +public class Utils { + + +} diff --git a/src/main/java/seedu/TypingGame/data/GamerInfo.java b/src/main/java/seedu/TypingGame/data/GamerInfo.java new file mode 100644 index 0000000000..c34cef1d51 --- /dev/null +++ b/src/main/java/seedu/TypingGame/data/GamerInfo.java @@ -0,0 +1,14 @@ +package seedu.TypingGame.data; + +import seedu.TypingGame.data.person.Person; +import seedu.TypingGame.data.person.ReadOnlyPerson; +import seedu.TypingGame.data.person.UniquePersonList; +import seedu.TypingGame.data.person.UniquePersonList.DuplicatePersonException; +import seedu.TypingGame.data.person.UniquePersonList.PersonNotFoundException; + +/** + * Contains the data of the entire game. + */ +public class GamerInfo { + +} diff --git a/src/main/java/seedu/TypingGame/exception/FaultyInputException.java b/src/main/java/seedu/TypingGame/exception/FaultyInputException.java new file mode 100644 index 0000000000..ec1f822d58 --- /dev/null +++ b/src/main/java/seedu/TypingGame/exception/FaultyInputException.java @@ -0,0 +1,4 @@ +package seedu.TypingGame.exception; + +public class FaultyInputException { +} diff --git a/src/main/java/seedu/TypingGame/exception/InvalidCommandException.java b/src/main/java/seedu/TypingGame/exception/InvalidCommandException.java new file mode 100644 index 0000000000..b996d5e5d2 --- /dev/null +++ b/src/main/java/seedu/TypingGame/exception/InvalidCommandException.java @@ -0,0 +1,4 @@ +package seedu.TypingGame.exception; + +public class InvalidCommandException { +} diff --git a/src/main/java/seedu/TypingGame/parser/Parser.java b/src/main/java/seedu/TypingGame/parser/Parser.java new file mode 100644 index 0000000000..3c40af9be4 --- /dev/null +++ b/src/main/java/seedu/TypingGame/parser/Parser.java @@ -0,0 +1,9 @@ +package seedu.TypingGame.parser; + + +/** + * Parses user input. + */ +public class Parser { + +} diff --git a/src/main/java/seedu/TypingGame/storage/StorageFile.java b/src/main/java/seedu/TypingGame/storage/StorageFile.java new file mode 100644 index 0000000000..01facb3bb5 --- /dev/null +++ b/src/main/java/seedu/TypingGame/storage/StorageFile.java @@ -0,0 +1,8 @@ +package seedu.TypingGame.storage; + +/** + * Represents the file used to store Typing data. + */ +public class StorageFile { + +} diff --git a/src/main/java/seedu/TypingGame/ui/TextUi.java b/src/main/java/seedu/TypingGame/ui/TextUi.java new file mode 100644 index 0000000000..3b0c09f193 --- /dev/null +++ b/src/main/java/seedu/TypingGame/ui/TextUi.java @@ -0,0 +1,174 @@ +package seedu.TypingGame.ui; + +import static seedu.TypingGame.common.Messages.MESSAGE_GOODBYE; +import static seedu.TypingGame.common.Messages.MESSAGE_INIT_FAILED; +import static seedu.TypingGame.common.Messages.MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE; +import static seedu.TypingGame.common.Messages.MESSAGE_USING_STORAGE_FILE; +import static seedu.TypingGame.common.Messages.MESSAGE_WELCOME; + +import java.io.InputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Scanner; + +import seedu.TypingGame.data.person.ReadOnlyPerson; + +/** + * Text UI of the application. + */ +public class TextUi { + + /** Offset required to convert between 1-indexing and 0-indexing. */ + public static final int DISPLAYED_INDEX_OFFSET = 1; + + /** A decorative prefix added to the beginning of lines printed by GamerInfo */ + private static final String LINE_PREFIX = "|| "; + + /** A platform independent line separator. */ + private static final String LS = System.lineSeparator(); + + private static final String DIVIDER = "==================================================="; + + /** Format of indexed list item */ + private static final String MESSAGE_INDEXED_LIST_ITEM = "\t%1$d. %2$s"; + + /** Format of a comment input line. Comment lines are silently consumed when reading user input. */ + private static final String COMMENT_LINE_FORMAT_REGEX = "#.*"; + + private final Scanner in; + private final PrintStream out; + + public TextUi() { + this(System.in, System.out); + } + + public TextUi(InputStream in, PrintStream out) { + this.in = new Scanner(in); + this.out = out; + } + + /** + * Returns true if the user input line should be ignored. + * Input should be ignored if it is parsed as a comment, is only whitespace, or is empty. + * + * @param rawInputLine full raw user input line. + * @return true if the entire user input line should be ignored. + */ + private boolean shouldIgnore(String rawInputLine) { + return rawInputLine.trim().isEmpty() || isCommentLine(rawInputLine); + } + + /** + * Returns true if the user input line is a comment line. + * + * @param rawInputLine full raw user input line. + * @return true if input line is a comment. + */ + private boolean isCommentLine(String rawInputLine) { + return rawInputLine.trim().matches(COMMENT_LINE_FORMAT_REGEX); + } + + /** + * Prompts for the command and reads the text entered by the user. + * Ignores empty, pure whitespace, and comment lines. + * Echos the command back to the user. + * @return command (full line) entered by the user + */ + public String getUserCommand() { + out.print(LINE_PREFIX + "Enter command: "); + String fullInputLine = in.nextLine(); + + // silently consume all ignored lines + while (shouldIgnore(fullInputLine)) { + fullInputLine = in.nextLine(); + } + + showToUser("[Command entered:" + fullInputLine + "]"); + return fullInputLine; + } + + /** + * Generates and prints the welcome message upon the start of the application. + * @param version current version of the application. + * @param storageFilePath path to the storage file being used. + */ + public void showWelcomeMessage(String version, String storageFilePath) { + String storageFileInfo = String.format(MESSAGE_USING_STORAGE_FILE, storageFilePath); + showToUser( + DIVIDER, + DIVIDER, + MESSAGE_WELCOME, + version, + MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE, + storageFileInfo, + DIVIDER); + } + + public void showGoodbyeMessage() { + showToUser(MESSAGE_GOODBYE, DIVIDER, DIVIDER); + } + + + public void showInitFailedMessage() { + showToUser(MESSAGE_INIT_FAILED, DIVIDER, DIVIDER); + } + + /** Shows message(s) to the user */ + public void showToUser(String... message) { + for (String m : message) { + out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); + } + } + + /** + * Shows the result of a command execution to the user. Includes additional formatting to demarcate different + * command execution segments. + */ + public void showResultToUser(CommandResult result) { + final Optional> resultPersons = result.getRelevantPersons(); + if (resultPersons.isPresent()) { + showPersonListView(resultPersons.get()); + } + showToUser(result.feedbackToUser, DIVIDER); + } + + /** + * Shows a list of persons to the user, formatted as an indexed list. + * Private contact details are hidden. + */ + private void showPersonListView(List persons) { + final List formattedPersons = new ArrayList<>(); + for (ReadOnlyPerson person : persons) { + formattedPersons.add(person.getAsTextHidePrivate()); + } + showToUserAsIndexedList(formattedPersons); + } + + /** Shows a list of strings to the user, formatted as an indexed list. */ + private void showToUserAsIndexedList(List list) { + showToUser(getIndexedListForViewing(list)); + } + + /** Formats a list of strings as a viewable indexed list. */ + private static String getIndexedListForViewing(List listItems) { + final StringBuilder formatted = new StringBuilder(); + int displayIndex = 0 + DISPLAYED_INDEX_OFFSET; + for (String listItem : listItems) { + formatted.append(getIndexedListItem(displayIndex, listItem)).append("\n"); + displayIndex++; + } + return formatted.toString(); + } + + /** + * Formats a string as a viewable indexed list item. + * + * @param visibleIndex visible index for this listing + */ + private static String getIndexedListItem(int visibleIndex, String listItem) { + return String.format(MESSAGE_INDEXED_LIST_ITEM, visibleIndex, listItem); + } + +} diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/DukeTest.java similarity index 90% rename from src/test/java/seedu/duke/DukeTest.java rename to src/test/java/seedu/DukeTest.java index 2dda5fd651..e70c96f072 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/DukeTest.java @@ -1,4 +1,4 @@ -package seedu.duke; +package seedu; import static org.junit.jupiter.api.Assertions.assertTrue; From f2475cb975faf8673da0c4ca50ad5537ab74c847 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 8 Oct 2021 22:20:55 +0800 Subject: [PATCH 015/272] improve skeleton To pass CI test --- .../java/seedu/TypingGame/data/GamerInfo.java | 5 - src/main/java/seedu/TypingGame/ui/TextUi.java | 165 ------------------ 2 files changed, 170 deletions(-) diff --git a/src/main/java/seedu/TypingGame/data/GamerInfo.java b/src/main/java/seedu/TypingGame/data/GamerInfo.java index c34cef1d51..4de8c56148 100644 --- a/src/main/java/seedu/TypingGame/data/GamerInfo.java +++ b/src/main/java/seedu/TypingGame/data/GamerInfo.java @@ -1,10 +1,5 @@ package seedu.TypingGame.data; -import seedu.TypingGame.data.person.Person; -import seedu.TypingGame.data.person.ReadOnlyPerson; -import seedu.TypingGame.data.person.UniquePersonList; -import seedu.TypingGame.data.person.UniquePersonList.DuplicatePersonException; -import seedu.TypingGame.data.person.UniquePersonList.PersonNotFoundException; /** * Contains the data of the entire game. diff --git a/src/main/java/seedu/TypingGame/ui/TextUi.java b/src/main/java/seedu/TypingGame/ui/TextUi.java index 3b0c09f193..feec68b7f4 100644 --- a/src/main/java/seedu/TypingGame/ui/TextUi.java +++ b/src/main/java/seedu/TypingGame/ui/TextUi.java @@ -1,174 +1,9 @@ package seedu.TypingGame.ui; -import static seedu.TypingGame.common.Messages.MESSAGE_GOODBYE; -import static seedu.TypingGame.common.Messages.MESSAGE_INIT_FAILED; -import static seedu.TypingGame.common.Messages.MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE; -import static seedu.TypingGame.common.Messages.MESSAGE_USING_STORAGE_FILE; -import static seedu.TypingGame.common.Messages.MESSAGE_WELCOME; - -import java.io.InputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Scanner; - -import seedu.TypingGame.data.person.ReadOnlyPerson; /** * Text UI of the application. */ public class TextUi { - /** Offset required to convert between 1-indexing and 0-indexing. */ - public static final int DISPLAYED_INDEX_OFFSET = 1; - - /** A decorative prefix added to the beginning of lines printed by GamerInfo */ - private static final String LINE_PREFIX = "|| "; - - /** A platform independent line separator. */ - private static final String LS = System.lineSeparator(); - - private static final String DIVIDER = "==================================================="; - - /** Format of indexed list item */ - private static final String MESSAGE_INDEXED_LIST_ITEM = "\t%1$d. %2$s"; - - /** Format of a comment input line. Comment lines are silently consumed when reading user input. */ - private static final String COMMENT_LINE_FORMAT_REGEX = "#.*"; - - private final Scanner in; - private final PrintStream out; - - public TextUi() { - this(System.in, System.out); - } - - public TextUi(InputStream in, PrintStream out) { - this.in = new Scanner(in); - this.out = out; - } - - /** - * Returns true if the user input line should be ignored. - * Input should be ignored if it is parsed as a comment, is only whitespace, or is empty. - * - * @param rawInputLine full raw user input line. - * @return true if the entire user input line should be ignored. - */ - private boolean shouldIgnore(String rawInputLine) { - return rawInputLine.trim().isEmpty() || isCommentLine(rawInputLine); - } - - /** - * Returns true if the user input line is a comment line. - * - * @param rawInputLine full raw user input line. - * @return true if input line is a comment. - */ - private boolean isCommentLine(String rawInputLine) { - return rawInputLine.trim().matches(COMMENT_LINE_FORMAT_REGEX); - } - - /** - * Prompts for the command and reads the text entered by the user. - * Ignores empty, pure whitespace, and comment lines. - * Echos the command back to the user. - * @return command (full line) entered by the user - */ - public String getUserCommand() { - out.print(LINE_PREFIX + "Enter command: "); - String fullInputLine = in.nextLine(); - - // silently consume all ignored lines - while (shouldIgnore(fullInputLine)) { - fullInputLine = in.nextLine(); - } - - showToUser("[Command entered:" + fullInputLine + "]"); - return fullInputLine; - } - - /** - * Generates and prints the welcome message upon the start of the application. - * @param version current version of the application. - * @param storageFilePath path to the storage file being used. - */ - public void showWelcomeMessage(String version, String storageFilePath) { - String storageFileInfo = String.format(MESSAGE_USING_STORAGE_FILE, storageFilePath); - showToUser( - DIVIDER, - DIVIDER, - MESSAGE_WELCOME, - version, - MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE, - storageFileInfo, - DIVIDER); - } - - public void showGoodbyeMessage() { - showToUser(MESSAGE_GOODBYE, DIVIDER, DIVIDER); - } - - - public void showInitFailedMessage() { - showToUser(MESSAGE_INIT_FAILED, DIVIDER, DIVIDER); - } - - /** Shows message(s) to the user */ - public void showToUser(String... message) { - for (String m : message) { - out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); - } - } - - /** - * Shows the result of a command execution to the user. Includes additional formatting to demarcate different - * command execution segments. - */ - public void showResultToUser(CommandResult result) { - final Optional> resultPersons = result.getRelevantPersons(); - if (resultPersons.isPresent()) { - showPersonListView(resultPersons.get()); - } - showToUser(result.feedbackToUser, DIVIDER); - } - - /** - * Shows a list of persons to the user, formatted as an indexed list. - * Private contact details are hidden. - */ - private void showPersonListView(List persons) { - final List formattedPersons = new ArrayList<>(); - for (ReadOnlyPerson person : persons) { - formattedPersons.add(person.getAsTextHidePrivate()); - } - showToUserAsIndexedList(formattedPersons); - } - - /** Shows a list of strings to the user, formatted as an indexed list. */ - private void showToUserAsIndexedList(List list) { - showToUser(getIndexedListForViewing(list)); - } - - /** Formats a list of strings as a viewable indexed list. */ - private static String getIndexedListForViewing(List listItems) { - final StringBuilder formatted = new StringBuilder(); - int displayIndex = 0 + DISPLAYED_INDEX_OFFSET; - for (String listItem : listItems) { - formatted.append(getIndexedListItem(displayIndex, listItem)).append("\n"); - displayIndex++; - } - return formatted.toString(); - } - - /** - * Formats a string as a viewable indexed list item. - * - * @param visibleIndex visible index for this listing - */ - private static String getIndexedListItem(int visibleIndex, String listItem) { - return String.format(MESSAGE_INDEXED_LIST_ITEM, visibleIndex, listItem); - } - } From 3057445c8fbb4babf635f64d868bb404b8fbec18 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 8 Oct 2021 22:23:54 +0800 Subject: [PATCH 016/272] improve skeleton To pass CI test, improved code quality --- src/main/java/seedu/{TypingGame => typists}/Main.java | 2 +- .../java/seedu/{TypingGame => typists}/commands/NewGame.java | 2 +- .../java/seedu/{TypingGame => typists}/common/Messages.java | 4 ++-- src/main/java/seedu/{TypingGame => typists}/common/Utils.java | 2 +- .../java/seedu/{TypingGame => typists}/data/GamerInfo.java | 2 +- .../exception/FaultyInputException.java | 2 +- .../exception/InvalidCommandException.java | 2 +- .../java/seedu/{TypingGame => typists}/parser/Parser.java | 2 +- .../seedu/{TypingGame => typists}/storage/StorageFile.java | 2 +- src/main/java/seedu/{TypingGame => typists}/ui/TextUi.java | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) rename src/main/java/seedu/{TypingGame => typists}/Main.java (95%) rename src/main/java/seedu/{TypingGame => typists}/commands/NewGame.java (66%) rename src/main/java/seedu/{TypingGame => typists}/common/Messages.java (90%) rename src/main/java/seedu/{TypingGame => typists}/common/Utils.java (79%) rename src/main/java/seedu/{TypingGame => typists}/data/GamerInfo.java (71%) rename src/main/java/seedu/{TypingGame => typists}/exception/FaultyInputException.java (52%) rename src/main/java/seedu/{TypingGame => typists}/exception/InvalidCommandException.java (53%) rename src/main/java/seedu/{TypingGame => typists}/parser/Parser.java (63%) rename src/main/java/seedu/{TypingGame => typists}/storage/StorageFile.java (72%) rename src/main/java/seedu/{TypingGame => typists}/ui/TextUi.java (69%) diff --git a/src/main/java/seedu/TypingGame/Main.java b/src/main/java/seedu/typists/Main.java similarity index 95% rename from src/main/java/seedu/TypingGame/Main.java rename to src/main/java/seedu/typists/Main.java index db24c4b7bf..3ac04bab27 100644 --- a/src/main/java/seedu/TypingGame/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,4 +1,4 @@ -package seedu.TypingGame; +package seedu.typists; import java.util.Scanner; diff --git a/src/main/java/seedu/TypingGame/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java similarity index 66% rename from src/main/java/seedu/TypingGame/commands/NewGame.java rename to src/main/java/seedu/typists/commands/NewGame.java index 15fa5fb383..80c97028e7 100644 --- a/src/main/java/seedu/TypingGame/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.commands; +package seedu.typists.commands; /* * commands to initiate a new game. diff --git a/src/main/java/seedu/TypingGame/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java similarity index 90% rename from src/main/java/seedu/TypingGame/common/Messages.java rename to src/main/java/seedu/typists/common/Messages.java index 5ef1e39744..b728059879 100644 --- a/src/main/java/seedu/TypingGame/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.common; +package seedu.typists.common; /** * Container for user visible messages. @@ -12,7 +12,7 @@ public class Messages { public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " - + "java seedu.TypingGame.Main [STORAGE_FILE_PATH]"; + + "java seedu.typists.Main [STORAGE_FILE_PATH]"; public static final String MESSAGE_WELCOME = "Welcome to Typing Game!"; public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; } diff --git a/src/main/java/seedu/TypingGame/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java similarity index 79% rename from src/main/java/seedu/TypingGame/common/Utils.java rename to src/main/java/seedu/typists/common/Utils.java index 339c6c75ab..361d4c5baa 100644 --- a/src/main/java/seedu/TypingGame/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.common; +package seedu.typists.common; import java.util.Collection; import java.util.HashSet; diff --git a/src/main/java/seedu/TypingGame/data/GamerInfo.java b/src/main/java/seedu/typists/data/GamerInfo.java similarity index 71% rename from src/main/java/seedu/TypingGame/data/GamerInfo.java rename to src/main/java/seedu/typists/data/GamerInfo.java index 4de8c56148..e653a8e3c3 100644 --- a/src/main/java/seedu/TypingGame/data/GamerInfo.java +++ b/src/main/java/seedu/typists/data/GamerInfo.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.data; +package seedu.typists.data; /** diff --git a/src/main/java/seedu/TypingGame/exception/FaultyInputException.java b/src/main/java/seedu/typists/exception/FaultyInputException.java similarity index 52% rename from src/main/java/seedu/TypingGame/exception/FaultyInputException.java rename to src/main/java/seedu/typists/exception/FaultyInputException.java index ec1f822d58..3648a67940 100644 --- a/src/main/java/seedu/TypingGame/exception/FaultyInputException.java +++ b/src/main/java/seedu/typists/exception/FaultyInputException.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.exception; +package seedu.typists.exception; public class FaultyInputException { } diff --git a/src/main/java/seedu/TypingGame/exception/InvalidCommandException.java b/src/main/java/seedu/typists/exception/InvalidCommandException.java similarity index 53% rename from src/main/java/seedu/TypingGame/exception/InvalidCommandException.java rename to src/main/java/seedu/typists/exception/InvalidCommandException.java index b996d5e5d2..375db1d263 100644 --- a/src/main/java/seedu/TypingGame/exception/InvalidCommandException.java +++ b/src/main/java/seedu/typists/exception/InvalidCommandException.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.exception; +package seedu.typists.exception; public class InvalidCommandException { } diff --git a/src/main/java/seedu/TypingGame/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java similarity index 63% rename from src/main/java/seedu/TypingGame/parser/Parser.java rename to src/main/java/seedu/typists/parser/Parser.java index 3c40af9be4..09b6de7b3a 100644 --- a/src/main/java/seedu/TypingGame/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.parser; +package seedu.typists.parser; /** diff --git a/src/main/java/seedu/TypingGame/storage/StorageFile.java b/src/main/java/seedu/typists/storage/StorageFile.java similarity index 72% rename from src/main/java/seedu/TypingGame/storage/StorageFile.java rename to src/main/java/seedu/typists/storage/StorageFile.java index 01facb3bb5..18162de3fd 100644 --- a/src/main/java/seedu/TypingGame/storage/StorageFile.java +++ b/src/main/java/seedu/typists/storage/StorageFile.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.storage; +package seedu.typists.storage; /** * Represents the file used to store Typing data. diff --git a/src/main/java/seedu/TypingGame/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java similarity index 69% rename from src/main/java/seedu/TypingGame/ui/TextUi.java rename to src/main/java/seedu/typists/ui/TextUi.java index feec68b7f4..962aff8084 100644 --- a/src/main/java/seedu/TypingGame/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,4 +1,4 @@ -package seedu.TypingGame.ui; +package seedu.typists.ui; /** From ca714a4c078831befc8eaf87689819d8c07f5858 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 8 Oct 2021 22:30:14 +0800 Subject: [PATCH 017/272] Update Utils.java --- src/main/java/seedu/typists/common/Utils.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 361d4c5baa..4f05b3ecae 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -1,11 +1,7 @@ package seedu.typists.common; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - /** - * Utility methods + * Utility methods. */ public class Utils { From ac2dd7d2fef97dbdf7e90ae0745b067f16ca6a42 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 8 Oct 2021 22:32:08 +0800 Subject: [PATCH 018/272] Update input.txt --- text-ui-test/input.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..e69de29bb2 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +0,0 @@ -James Gosling \ No newline at end of file From 3c41984a9f24a6921d82bc442de0a7228442903d Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 8 Oct 2021 22:40:40 +0800 Subject: [PATCH 019/272] update input --- build.gradle | 4 ++-- text-ui-test/input.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index b0c5528fb5..02b3025347 100644 --- a/build.gradle +++ b/build.gradle @@ -29,11 +29,11 @@ test { } application { - mainClassName = "seedu.duke.Duke" + mainClassName = "seedu.typists.Main" } shadowJar { - archiveBaseName = "duke" + archiveBaseName = "typists" archiveClassifier = null } diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb2..f6ec2e9f95 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1 @@ +James Gosling \ No newline at end of file From 6ceb4165b36d1166c8972e01bf41069dd4545bea Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 8 Oct 2021 23:35:05 +0800 Subject: [PATCH 020/272] Created StringParser class with a JUnit test To test out the dashboard tag detecting function --- src/main/java/seedu/typists/Main.java | 18 +++++++++ .../InvalidStringInputException.java | 8 ++++ .../seedu/typists/parser/StringParser.java | 27 ++++++++++++++ src/test/java/seedu/StringParserTest.java | 37 +++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 src/main/java/seedu/typists/exception/InvalidStringInputException.java create mode 100644 src/main/java/seedu/typists/parser/StringParser.java create mode 100644 src/test/java/seedu/StringParserTest.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 3ac04bab27..7ad4275147 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,5 +1,9 @@ package seedu.typists; +import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.parser.StringParser; + +import java.util.List; import java.util.Scanner; public class Main { @@ -17,5 +21,19 @@ public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Hello " + in.nextLine()); + + /** + * The following code test on the JUnit test on StringParser + */ + StringParser sp = new StringParser(); + String str = "Hello|World|How are|you all"; + List stringParts = null; + try { + stringParts = sp.splitString(str, "\\|"); + } catch (InvalidStringInputException e) { + e.printStackTrace(); + } } + + } diff --git a/src/main/java/seedu/typists/exception/InvalidStringInputException.java b/src/main/java/seedu/typists/exception/InvalidStringInputException.java new file mode 100644 index 0000000000..cb3a2b2f56 --- /dev/null +++ b/src/main/java/seedu/typists/exception/InvalidStringInputException.java @@ -0,0 +1,8 @@ +package seedu.typists.exception; + +public class InvalidStringInputException extends Throwable { + @Override + public String getMessage() { + return "Invalid input given" + super.getMessage(); + } +} diff --git a/src/main/java/seedu/typists/parser/StringParser.java b/src/main/java/seedu/typists/parser/StringParser.java new file mode 100644 index 0000000000..0dfcca5f2a --- /dev/null +++ b/src/main/java/seedu/typists/parser/StringParser.java @@ -0,0 +1,27 @@ +package seedu.typists.parser; + +import java.util.ArrayList; +import java.util.Arrays; + +import seedu.typists.exception.InvalidStringInputException; + +public class StringParser { + + /** + * Splits the string based on the separator provided as parameter. + * + * @param stringToSplit the string to be split + * @param separator a string representing the separator that you want to split the string on + * @return ArrayList of strings + */ + public ArrayList splitString(String stringToSplit, String separator) throws InvalidStringInputException { + + if(stringToSplit == null){ + throw new InvalidStringInputException(); + } + ArrayList stringParts = new ArrayList<>(); + stringParts.addAll(Arrays.asList(stringToSplit.split(separator))); + + return stringParts; + } +} \ No newline at end of file diff --git a/src/test/java/seedu/StringParserTest.java b/src/test/java/seedu/StringParserTest.java new file mode 100644 index 0000000000..bd1bf84222 --- /dev/null +++ b/src/test/java/seedu/StringParserTest.java @@ -0,0 +1,37 @@ +package seedu; + +import org.junit.jupiter.api.Test; +import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.parser.StringParser; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class StringParserTest { + + // methodBeingTested_inputGiven_expectedOutcome + // Input, one separator, 2 parts -- Happy path + @Test + void splitString_oneSeparator_expectTwoParts() throws InvalidStringInputException { + String inputString = "Hello|world"; + StringParser sp = new StringParser(); + String separator = "\\|"; + ArrayList stringParts = sp.splitString(inputString,separator); + assertEquals(2,stringParts.size()); + } + + //test failure case + // method being tested, NullInput, expect exception + @Test + void splitString_nullInput_expectException() { + String inputString = null; + StringParser sp = new StringParser(); + String separator = "\\|"; + //ArrayList stringParts = sp.splitString(inputString,separator); + assertThrows(InvalidStringInputException.class, + ()->sp.splitString(inputString,separator)); + //assertEquals(0,stringParts.size()); + } +} From 4e67ef8e92af8205f5e9efa9b5b62cb709607b09 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 8 Oct 2021 23:41:01 +0800 Subject: [PATCH 021/272] checkstyle Debug --- src/main/java/seedu/typists/parser/StringParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/parser/StringParser.java b/src/main/java/seedu/typists/parser/StringParser.java index 0dfcca5f2a..17bf380ab1 100644 --- a/src/main/java/seedu/typists/parser/StringParser.java +++ b/src/main/java/seedu/typists/parser/StringParser.java @@ -16,7 +16,7 @@ public class StringParser { */ public ArrayList splitString(String stringToSplit, String separator) throws InvalidStringInputException { - if(stringToSplit == null){ + if (stringToSplit == null) { throw new InvalidStringInputException(); } ArrayList stringParts = new ArrayList<>(); From 81a609fbfd0e8210d71ca7c7c37394ae81646af7 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 8 Oct 2021 23:43:42 +0800 Subject: [PATCH 022/272] checkstyle debug 2 --- src/test/java/seedu/StringParserTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/StringParserTest.java b/src/test/java/seedu/StringParserTest.java index bd1bf84222..45b0114fc7 100644 --- a/src/test/java/seedu/StringParserTest.java +++ b/src/test/java/seedu/StringParserTest.java @@ -31,7 +31,7 @@ void splitString_nullInput_expectException() { String separator = "\\|"; //ArrayList stringParts = sp.splitString(inputString,separator); assertThrows(InvalidStringInputException.class, - ()->sp.splitString(inputString,separator)); + () -> sp.splitString(inputString,separator)); //assertEquals(0,stringParts.size()); } } From 2bd9a22730b21c905eab2842060d04254af0a835 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 8 Oct 2021 23:49:07 +0800 Subject: [PATCH 023/272] checkstyle debug 3 --- src/test/java/seedu/StringParserTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/seedu/StringParserTest.java b/src/test/java/seedu/StringParserTest.java index 45b0114fc7..58e2493986 100644 --- a/src/test/java/seedu/StringParserTest.java +++ b/src/test/java/seedu/StringParserTest.java @@ -30,8 +30,7 @@ void splitString_nullInput_expectException() { StringParser sp = new StringParser(); String separator = "\\|"; //ArrayList stringParts = sp.splitString(inputString,separator); - assertThrows(InvalidStringInputException.class, - () -> sp.splitString(inputString,separator)); + assertThrows(InvalidStringInputException.class, () -> sp.splitString(inputString,separator)); //assertEquals(0,stringParts.size()); } } From 82983567674b82c24718835dee82c247e82d022a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 11 Oct 2021 15:57:56 +0800 Subject: [PATCH 024/272] Create start page Create landing page for typist. --- src/main/java/seedu/typists/Main.java | 34 ++++++++++------ .../java/seedu/typists/common/Messages.java | 31 ++++++++++----- src/main/java/seedu/typists/ui/TextUi.java | 39 +++++++++++++++++++ src/test/java/seedu/DukeTest.java | 1 + 4 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 3ac04bab27..6025464f91 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,21 +1,33 @@ package seedu.typists; -import java.util.Scanner; +import seedu.typists.parser.Parser; +import seedu.typists.ui.TextUi; + +//solution below adapted from https://github.com/se-edu/addressbook-level2/ public class Main { + /** Version info of the program. */ + public static final String VERSION = "Typist - Version 1.0"; + TextUi UiBot; + Parser ParseBot; + + public void start() { + this.UiBot = new TextUi(); + this.ParseBot = new Parser(); + UiBot.showWelcomeMessage(VERSION); + } + + /** Runs the program until termination. */ + public void run() { + start(); +// runCommandLoopUntilExitCommand(); +// exit(); + } + /** * Main entry-point for the java.duke.Duke application. */ public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); + new Main().run(); } } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index b728059879..3129dc6beb 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -5,14 +5,25 @@ */ public class Messages { - public static final String MESSAGE_GOODBYE = "Good bye!"; - public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; - public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; - public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; - public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; - public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " - + "java seedu.typists.Main [STORAGE_FILE_PATH]"; - public static final String MESSAGE_WELCOME = "Welcome to Typing Game!"; - public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; + public static final String LOGO = + " ______ _ __ \n" + + " /_ __/_ ______ (_)____/ /_\n" + + " / / / / / / __ \\/ / ___/ __/\n" + + " / / / /_/ / /_/ / (__ ) /_ \n" + + "/_/ \\__, / .___/_/____/\\__/ \n" + + " /____/_/ "; + + public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; + public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; + +// public static final String MESSAGE_GOODBYE = "Good bye!"; +// public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; +// public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; +// public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; +// public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; +// public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; +// public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " +// + "java seedu.typists.Main [STORAGE_FILE_PATH]"; +// +// public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 962aff8084..3b569c9186 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,9 +1,48 @@ package seedu.typists.ui; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; + +import static java.lang.System.lineSeparator; +import static java.lang.System.out; +import static seedu.typists.common.Messages.LOGO; +import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; +import static seedu.typists.common.Messages.MESSAGE_WELCOME; + /** * Text UI of the application. */ public class TextUi { + private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + private final String DIVIDER = "****************************************************************"; + private final String LINE_PREFIX = " | "; + private final String LS = lineSeparator(); + + public String getTimeStamp() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + return timeFormatter.format(timestamp); + } + + //solution below adapted from https://github.com/se-edu/addressbook-level2/ + public void showWelcomeMessage(String version) { + getTimeStamp(); + printScreen( + version, + getTimeStamp(), + DIVIDER, + LOGO, + MESSAGE_WELCOME, + MESSAGE_ACKNOWLEDGE, + DIVIDER + ); + } + + public void printScreen(String... message) { + for (String m: message) { + out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); + } + } } diff --git a/src/test/java/seedu/DukeTest.java b/src/test/java/seedu/DukeTest.java index e70c96f072..c222fff234 100644 --- a/src/test/java/seedu/DukeTest.java +++ b/src/test/java/seedu/DukeTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; class DukeTest { + @Test public void sampleTest() { assertTrue(true); From 693e16d71de5c1524862cfb11f40b82388af120b Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 11 Oct 2021 16:38:29 +0800 Subject: [PATCH 025/272] Update code with Checkstyle modify code to fix Checkstyle bugs --- src/main/java/seedu/typists/Main.java | 22 +++++++++----- .../java/seedu/typists/common/Messages.java | 30 +++++++++---------- src/main/java/seedu/typists/ui/TextUi.java | 6 ++-- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 6025464f91..696dc740e9 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -8,20 +8,28 @@ public class Main { /** Version info of the program. */ public static final String VERSION = "Typist - Version 1.0"; - TextUi UiBot; - Parser ParseBot; + TextUi uiBot; + Parser parseBot; public void start() { - this.UiBot = new TextUi(); - this.ParseBot = new Parser(); - UiBot.showWelcomeMessage(VERSION); + this.uiBot = new TextUi(); + this.parseBot = new Parser(); + uiBot.showWelcomeMessage(VERSION); + } + + public void runCommandLoopUntilExitCommand() { + + } + + public void exit() { + } /** Runs the program until termination. */ public void run() { start(); -// runCommandLoopUntilExitCommand(); -// exit(); + runCommandLoopUntilExitCommand(); + exit(); } /** diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 3129dc6beb..c7ec14dfbb 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -6,24 +6,22 @@ public class Messages { public static final String LOGO = - " ______ _ __ \n" + - " /_ __/_ ______ (_)____/ /_\n" + - " / / / / / / __ \\/ / ___/ __/\n" + - " / / / /_/ / /_/ / (__ ) /_ \n" + - "/_/ \\__, / .___/_/____/\\__/ \n" + - " /____/_/ "; + " ______ _ __ \n" + + " /_ __/_ ______ (_)____/ /_\n" + + " / / / / / / __ \\/ / ___/ __/\n" + + " / / / /_/ / /_/ / (__ ) /_ \n" + + "/_/ \\__, / .___/_/____/\\__/ \n" + + " /____/_/ "; public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; -// public static final String MESSAGE_GOODBYE = "Good bye!"; -// public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; -// public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; -// public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; -// public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; -// public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; -// public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " -// + "java seedu.typists.Main [STORAGE_FILE_PATH]"; -// -// public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; + //public static final String MESSAGE_GOODBYE = "Good bye!"; + //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; + //public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; + //public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; + //public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; + //public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + //public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " + // + "java seedu.typists.Main [STORAGE_FILE_PATH]"; } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 3b569c9186..c0c5af17af 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -17,9 +17,9 @@ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private final String DIVIDER = "****************************************************************"; - private final String LINE_PREFIX = " | "; - private final String LS = lineSeparator(); + private static final String DIVIDER = "****************************************************************"; + private static final String LINE_PREFIX = " | "; + private static final String LS = lineSeparator(); public String getTimeStamp() { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); From 55c4d572dd45d3af59137bd1be4c1e211c9033c9 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 11 Oct 2021 21:36:36 +0800 Subject: [PATCH 026/272] timer mode tryout --- src/main/java/seedu/typists/Main.java | 39 +++++++++++ .../java/seedu/typists/common/Messages.java | 24 +++++++ src/main/java/seedu/typists/game/Game.java | 5 ++ .../java/seedu/typists/game/TimeModeGame.java | 64 +++++++++++++++++ src/main/java/seedu/typists/ui/TextUi.java | 68 +++++++++++++++++++ 5 files changed, 200 insertions(+) create mode 100644 src/main/java/seedu/typists/game/Game.java create mode 100644 src/main/java/seedu/typists/game/TimeModeGame.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 3ac04bab27..7a798c9ec3 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,8 +1,47 @@ package seedu.typists; +<<<<<<< Updated upstream import java.util.Scanner; public class Main { +======= +import seedu.typists.game.Game; +import seedu.typists.game.TimeModeGame; +import seedu.typists.parser.Parser; +import seedu.typists.ui.TextUi; + +import static seedu.typists.common.Messages.SAMPLE_TEXT; + + +//solution below adapted from https://github.com/se-edu/addressbook-level2/ +public class Main { + /** Version info of the program. */ + public static final String VERSION = "Typist - Version 1.0"; + + public void start() { + TextUi uiBot = new TextUi(); + Parser parseBot = new Parser(); + TimeModeGame gameBot = new TimeModeGame(); + uiBot.showWelcomeMessage(VERSION); + gameBot.startGame(SAMPLE_TEXT, 5); + } + + public void runCommandLoopUntilExitCommand() { + + } + + public void exit() { + + } + + /** Runs the program until termination. */ + public void run() { + start(); + runCommandLoopUntilExitCommand(); + exit(); + } + +>>>>>>> Stashed changes /** * Main entry-point for the java.duke.Duke application. */ diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index b728059879..c9ef05439e 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -5,6 +5,7 @@ */ public class Messages { +<<<<<<< Updated upstream public static final String MESSAGE_GOODBYE = "Good bye!"; public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; @@ -15,4 +16,27 @@ public class Messages { + "java seedu.typists.Main [STORAGE_FILE_PATH]"; public static final String MESSAGE_WELCOME = "Welcome to Typing Game!"; public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; +======= + public static final String LOGO = + " ______ _ __ \n" + + " /_ __/_ ______ (_)____/ /_\n" + + " / / / / / / __ \\/ / ___/ __/\n" + + " / / / /_/ / /_/ / (__ ) /_ \n" + + "/_/ \\__, / .___/_/____/\\__/ \n" + + " /____/_/ "; + + public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; + public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; + //This sample text is gotten from https://www.lipsum.com/ + public static final String SAMPLE_TEXT = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; + + //public static final String MESSAGE_GOODBYE = "Good bye!"; + //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; + //public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; + //public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; + //public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; + //public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + //public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " + // + "java seedu.typists.Main [STORAGE_FILE_PATH]"; +>>>>>>> Stashed changes } diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java new file mode 100644 index 0000000000..5a353218d0 --- /dev/null +++ b/src/main/java/seedu/typists/game/Game.java @@ -0,0 +1,5 @@ +package seedu.typists.game; + +public abstract class Game { + +} diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java new file mode 100644 index 0000000000..1013f17d6c --- /dev/null +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -0,0 +1,64 @@ +package seedu.typists.game; + +import seedu.typists.ui.TextUi; + +import java.time.LocalDateTime; +import java.util.Scanner; +import java.util.Timer; +import java.util.TimerTask; + +import static seedu.typists.common.Messages.SAMPLE_TEXT; + +public class TimeModeGame extends Game { + private final TextUi uiBot; + + public TimeModeGame() { + this.uiBot = new TextUi(); + } + + /** Currently still a dummy */ + public String getTargetWordSet() { + return SAMPLE_TEXT; + } + + public void startGame(String targetWordSet, int timeLimitSeconds) { + uiBot.showTargetWordSet(targetWordSet); + /* + TimerTask game = new TimerTask() { + @Override + public void run() { + System.out.println("Timer ends"); + } + }; + + Timer timer = new Timer(){ + @Override + public void cancel() { + super.cancel(); + System.out.println("Timer abort."); + } + }; + timer.schedule(game, timeLimitSeconds*1000 ); + System.out.println("counting " + timeLimitSeconds + " starting now:" ); + //task to do within timeLimit + timer.cancel(); + */ + + //method 1 trying + LocalDateTime currentTime = LocalDateTime.now(); + System.out.println(currentTime); + + //method 2 trying + Scanner reader = new Scanner(System.in); + System.out.println("Enter a number: "); + long limit = 5000L; + long startTime = System.currentTimeMillis(); + Long l = reader.nextLong(); + if ((startTime + limit) < System.currentTimeMillis()) + System.out.println("Sorry, your answer is too late"); + else + System.out.println("Your answer is on time"); + + } + +} diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 962aff8084..7008aa4785 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,9 +1,77 @@ package seedu.typists.ui; +<<<<<<< Updated upstream +======= +import java.sql.Array; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; + +import static java.lang.System.lineSeparator; +import static java.lang.System.out; +import static seedu.typists.common.Messages.LOGO; +import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; +import static seedu.typists.common.Messages.MESSAGE_WELCOME; + +>>>>>>> Stashed changes /** * Text UI of the application. */ public class TextUi { +<<<<<<< Updated upstream +======= + private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + private static final String DIVIDER = "****************************************************************"; + private static final String LINE_PREFIX = " | "; + private static final String LS = lineSeparator(); + + public String getTimeStamp() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + return timeFormatter.format(timestamp); + } + + //solution below adapted from https://github.com/se-edu/addressbook-level2/ + public void showWelcomeMessage(String version) { + getTimeStamp(); + printScreen( + version, + getTimeStamp(), + DIVIDER, + LOGO, + MESSAGE_WELCOME, + MESSAGE_ACKNOWLEDGE, + DIVIDER + ); + } + + public void printScreen(String... message) { + for (String m: message) { + out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); + } + } + + public ArrayList splitLineIntoWordList(String line) { + ArrayList wordList = new ArrayList <>(); + wordList.addAll(Arrays.asList(line.split(" "))); + return wordList; + } + + /** Print to screen the target words, each line 10 words */ + public void showTargetWordSet(String TargetWordSet) { + ArrayList wordList = splitLineIntoWordList(TargetWordSet); + int i = 1; + for (String w : wordList) { + out.print(w + " "); + if (i % 10 == 0) { + out.print("\n"); + } + i++; + } + out.print("\n"); + } +>>>>>>> Stashed changes } From 5484e8d2eae71794958416ce4a228c74ee1967da Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 11 Oct 2021 21:56:04 +0800 Subject: [PATCH 027/272] modify code to pass runTest --- .../java/seedu/typists/common/Messages.java | 8 ++++---- src/main/java/seedu/typists/ui/TextUi.java | 4 +++- text-ui-test/EXPECTED.TXT | 20 ++++++++++--------- text-ui-test/input.txt | 1 - 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index c7ec14dfbb..6ff7edf496 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -6,12 +6,12 @@ public class Messages { public static final String LOGO = - " ______ _ __ \n" + " ______ _ __\n" + " /_ __/_ ______ (_)____/ /_\n" + " / / / / / / __ \\/ / ___/ __/\n" - + " / / / /_/ / /_/ / (__ ) /_ \n" - + "/_/ \\__, / .___/_/____/\\__/ \n" - + " /____/_/ "; + + " / / / /_/ / /_/ / (__ ) /_\n" + + "/_/ \\__, / .___/_/____/\\__/\n" + + " /____/_/"; public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index c0c5af17af..bfc9e93524 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -21,6 +21,8 @@ public class TextUi { private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); + //get current timestamp + //unused because it interferes with the EXPECTED.TXT in runtest public String getTimeStamp() { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); return timeFormatter.format(timestamp); @@ -31,7 +33,7 @@ public void showWelcomeMessage(String version) { getTimeStamp(); printScreen( version, - getTimeStamp(), + //getTimeStamp(), DIVIDER, LOGO, MESSAGE_WELCOME, diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..086638cfa2 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1,11 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - -What is your name? -Hello James Gosling + | Typist - Version 1.0 + | **************************************************************** + | ______ _ __ + | /_ __/_ ______ (_)____/ /_ + | / / / / / / __ \/ / ___/ __/ + | / / / /_/ / /_/ / (__ ) /_ + | /_/ \__, / .___/_/____/\__/ + | /____/_/ + | Welcome to Typist -- the ultimate cli typing game. + | Brought to you by -- AY2122S1-CS2113-T13-4. + | **************************************************************** diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..e69de29bb2 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +0,0 @@ -James Gosling \ No newline at end of file From 8bc0b6b4c2ed3ef138ea77e56d5d87e9d50b1d91 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 16:28:33 +0800 Subject: [PATCH 028/272] Content and random string generator --- src/main/java/seedu/typists/Main.java | 1 + .../java/seedu/typists/content/Content.java | 16 ++++++++++++ .../typists/content/RandomGenerator.java | 25 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/main/java/seedu/typists/content/Content.java create mode 100644 src/main/java/seedu/typists/content/RandomGenerator.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 7ad4275147..8cfa337677 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,5 +1,6 @@ package seedu.typists; +import seedu.typists.content.RandomGenerator; import seedu.typists.exception.InvalidStringInputException; import seedu.typists.parser.StringParser; diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java new file mode 100644 index 0000000000..dc731845a8 --- /dev/null +++ b/src/main/java/seedu/typists/content/Content.java @@ -0,0 +1,16 @@ +package seedu.typists.content; + +/** + * Content object + */ +public class Content { + private String content; + + public void setContent(String content) { + this.content = content; + } + + public String getContent() { + return content; + } +} diff --git a/src/main/java/seedu/typists/content/RandomGenerator.java b/src/main/java/seedu/typists/content/RandomGenerator.java new file mode 100644 index 0000000000..b74ef5a558 --- /dev/null +++ b/src/main/java/seedu/typists/content/RandomGenerator.java @@ -0,0 +1,25 @@ +package seedu.typists.content; + +import java.util.Random; + +/** + * Generate random string of custom length + */ +public class RandomGenerator { + public String randomString(int length) { + Random isCaps = new Random(); + Random rand = new Random(); + StringBuilder s = new StringBuilder(); + for (int i = 0; i < length; i++) { + int random = 0; + if (isCaps.nextBoolean()) { + random = rand.nextInt(26) + 65; + } + else { + random = rand.nextInt(26) + 97; + } + s.append((char) random); + } + return s.toString(); + } +} From 5410fa9fc69bdf91ebc4c5dc5086ce5fd4e7d579 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 16:42:32 +0800 Subject: [PATCH 029/272] Content and random string generator --- src/main/java/seedu/typists/content/Content.java | 2 +- src/main/java/seedu/typists/content/RandomGenerator.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index dc731845a8..220be56cb5 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -1,7 +1,7 @@ package seedu.typists.content; /** - * Content object + * Content object. */ public class Content { private String content; diff --git a/src/main/java/seedu/typists/content/RandomGenerator.java b/src/main/java/seedu/typists/content/RandomGenerator.java index b74ef5a558..3010490a59 100644 --- a/src/main/java/seedu/typists/content/RandomGenerator.java +++ b/src/main/java/seedu/typists/content/RandomGenerator.java @@ -3,7 +3,7 @@ import java.util.Random; /** - * Generate random string of custom length + * Generate random string of custom length. */ public class RandomGenerator { public String randomString(int length) { @@ -14,8 +14,7 @@ public String randomString(int length) { int random = 0; if (isCaps.nextBoolean()) { random = rand.nextInt(26) + 65; - } - else { + } else { random = rand.nextInt(26) + 97; } s.append((char) random); From b8a2990896b8b0cee5c1244298272cdb4d5399eb Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:33:48 +0800 Subject: [PATCH 030/272] Wiki import --- build.gradle | 1 + src/main/java/seedu/typists/Main.java | 12 ++++++------ src/main/java/seedu/typists/content/WikiImport.java | 13 +++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 src/main/java/seedu/typists/content/WikiImport.java diff --git a/build.gradle b/build.gradle index 02b3025347..096c5c405c 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ repositories { } dependencies { + implementation 'org.fastily:jwiki:1.8.0' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' } diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 8cfa337677..3474424c35 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,6 +1,6 @@ package seedu.typists; -import seedu.typists.content.RandomGenerator; +import seedu.typists.content.WikiImport; import seedu.typists.exception.InvalidStringInputException; import seedu.typists.parser.StringParser; @@ -23,9 +23,7 @@ public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Hello " + in.nextLine()); - /** - * The following code test on the JUnit test on StringParser - */ + // The following code test on the JUnit test on StringParser. StringParser sp = new StringParser(); String str = "Hello|World|How are|you all"; List stringParts = null; @@ -34,7 +32,9 @@ public static void main(String[] args) { } catch (InvalidStringInputException e) { e.printStackTrace(); } - } - + // Test for WikiImport. + WikiImport wiki = new WikiImport(); + System.out.println(wiki.getArticle("GitHub")); + } } diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java new file mode 100644 index 0000000000..5468c64e77 --- /dev/null +++ b/src/main/java/seedu/typists/content/WikiImport.java @@ -0,0 +1,13 @@ +package seedu.typists.content; + +import org.fastily.jwiki.core.Wiki; + +/** + * Imports the first paragraph of a text from Wikipedia. + */ +public class WikiImport { + public String getArticle(String article) { + Wiki wiki = new Wiki.Builder().build(); + return wiki.getTextExtract(article); + } +} From 169f62afc9b332a624553159f50cd526b030d763 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:47:20 +0800 Subject: [PATCH 031/272] Wiki import and test --- src/main/java/seedu/typists/Main.java | 7 +++- .../seedu/typists/content/WikiImport.java | 6 +++- .../exception/InvalidArticleException.java | 8 +++++ src/test/java/seedu/WikiImportTest.java | 34 +++++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/typists/exception/InvalidArticleException.java create mode 100644 src/test/java/seedu/WikiImportTest.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 3474424c35..27f4735181 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,6 +1,7 @@ package seedu.typists; import seedu.typists.content.WikiImport; +import seedu.typists.exception.InvalidArticleException; import seedu.typists.exception.InvalidStringInputException; import seedu.typists.parser.StringParser; @@ -35,6 +36,10 @@ public static void main(String[] args) { // Test for WikiImport. WikiImport wiki = new WikiImport(); - System.out.println(wiki.getArticle("GitHub")); + try { + String article = wiki.getArticle("GitHub"); + } catch (InvalidArticleException e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java index 5468c64e77..1c464c7fb0 100644 --- a/src/main/java/seedu/typists/content/WikiImport.java +++ b/src/main/java/seedu/typists/content/WikiImport.java @@ -1,13 +1,17 @@ package seedu.typists.content; import org.fastily.jwiki.core.Wiki; +import seedu.typists.exception.InvalidArticleException; /** * Imports the first paragraph of a text from Wikipedia. */ public class WikiImport { - public String getArticle(String article) { + public String getArticle(String article) throws InvalidArticleException { Wiki wiki = new Wiki.Builder().build(); + if (!wiki.exists(article)) { + throw new InvalidArticleException(); + } return wiki.getTextExtract(article); } } diff --git a/src/main/java/seedu/typists/exception/InvalidArticleException.java b/src/main/java/seedu/typists/exception/InvalidArticleException.java new file mode 100644 index 0000000000..734b6ca5fb --- /dev/null +++ b/src/main/java/seedu/typists/exception/InvalidArticleException.java @@ -0,0 +1,8 @@ +package seedu.typists.exception; + +public class InvalidArticleException extends Throwable { + @Override + public String getMessage() { + return "Invalid article given" + super.getMessage(); + } +} diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java new file mode 100644 index 0000000000..0da211fa4a --- /dev/null +++ b/src/test/java/seedu/WikiImportTest.java @@ -0,0 +1,34 @@ +package seedu; + +import org.junit.jupiter.api.Test; +import seedu.typists.content.WikiImport; +import seedu.typists.exception.InvalidArticleException; +import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.parser.StringParser; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class WikiImportTest { + + // methodBeingTested_inputGiven_expectedOutcome + // Input, Github, relevant article + @Test + void getArticle_Github_expectArticle() throws InvalidArticleException { + String article = "Github"; + WikiImport wiki = new WikiImport(); + String content = wiki.getArticle(article); + assertEquals("GitHub, Inc. is a provider of Internet hosting for software development and version control using Git. It offers the distributed version control and source code management (SCM) functionality of Git, plus its own features. It provides access control and several collaboration features such as bug tracking, feature requests, task management, continuous integration and wikis for every project.[4] Headquartered in California, it has been a subsidiary of Microsoft since 2018.", content); + } + + // test failure case + // method being tested, Githob, expect exception + @Test + void getArticle_Githob_expectException() { + String article = "Githob"; + WikiImport wiki = new WikiImport(); + assertThrows(InvalidArticleException.class, () -> wiki.getArticle(article)); + } +} From 84bfb8f5dac0f2bc846a579da575cbd4dfdc0709 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:53:05 +0800 Subject: [PATCH 032/272] Wiki import and test --- src/main/java/seedu/typists/Main.java | 2 ++ src/test/java/seedu/WikiImportTest.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 27f4735181..e517056e01 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -38,6 +38,8 @@ public static void main(String[] args) { WikiImport wiki = new WikiImport(); try { String article = wiki.getArticle("GitHub"); + System.out.println(article.length()); + System.out.println(article); } catch (InvalidArticleException e) { e.printStackTrace(); } diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java index 0da211fa4a..11a0890b0b 100644 --- a/src/test/java/seedu/WikiImportTest.java +++ b/src/test/java/seedu/WikiImportTest.java @@ -14,13 +14,13 @@ public class WikiImportTest { // methodBeingTested_inputGiven_expectedOutcome - // Input, Github, relevant article + // Input, Github, relevant article (731 characters) @Test void getArticle_Github_expectArticle() throws InvalidArticleException { String article = "Github"; WikiImport wiki = new WikiImport(); String content = wiki.getArticle(article); - assertEquals("GitHub, Inc. is a provider of Internet hosting for software development and version control using Git. It offers the distributed version control and source code management (SCM) functionality of Git, plus its own features. It provides access control and several collaboration features such as bug tracking, feature requests, task management, continuous integration and wikis for every project.[4] Headquartered in California, it has been a subsidiary of Microsoft since 2018.", content); + assertEquals(731, content.length()); } // test failure case From fe3e2d29402aec43640a3b8ab0b8ef8ede91c245 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 17:59:26 +0800 Subject: [PATCH 033/272] Wiki import and test --- src/test/java/seedu/WikiImportTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java index 11a0890b0b..51556a5b70 100644 --- a/src/test/java/seedu/WikiImportTest.java +++ b/src/test/java/seedu/WikiImportTest.java @@ -17,7 +17,7 @@ public class WikiImportTest { // Input, Github, relevant article (731 characters) @Test void getArticle_Github_expectArticle() throws InvalidArticleException { - String article = "Github"; + String article = "GitHub"; WikiImport wiki = new WikiImport(); String content = wiki.getArticle(article); assertEquals(731, content.length()); From 9e3d8a5f7fa7e1b5c8b8a64cde3dcabad544be6f Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 18:00:29 +0800 Subject: [PATCH 034/272] Wiki import and test --- src/test/java/seedu/WikiImportTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java index 51556a5b70..4aba12037d 100644 --- a/src/test/java/seedu/WikiImportTest.java +++ b/src/test/java/seedu/WikiImportTest.java @@ -14,9 +14,9 @@ public class WikiImportTest { // methodBeingTested_inputGiven_expectedOutcome - // Input, Github, relevant article (731 characters) + // Input, GitHub, relevant article (731 characters) @Test - void getArticle_Github_expectArticle() throws InvalidArticleException { + void getArticle_GitHub_expectArticle() throws InvalidArticleException { String article = "GitHub"; WikiImport wiki = new WikiImport(); String content = wiki.getArticle(article); From 3e56416390cba8c750f788ade9236b1c613005f9 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 12 Oct 2021 18:03:04 +0800 Subject: [PATCH 035/272] Wiki import and test --- src/main/java/seedu/typists/Main.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index e517056e01..27f4735181 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -38,8 +38,6 @@ public static void main(String[] args) { WikiImport wiki = new WikiImport(); try { String article = wiki.getArticle("GitHub"); - System.out.println(article.length()); - System.out.println(article); } catch (InvalidArticleException e) { e.printStackTrace(); } From bfaa79a4c707c07964df38f0de79aedc2c695e22 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 13:39:21 +0800 Subject: [PATCH 036/272] Reverting importing Wiki part --- build.gradle | 2 +- src/main/java/seedu/typists/Main.java | 3 ++ .../seedu/typists/content/WikiImport.java | 17 ---------- src/test/java/seedu/WikiImportTest.java | 34 ------------------- 4 files changed, 4 insertions(+), 52 deletions(-) delete mode 100644 src/main/java/seedu/typists/content/WikiImport.java delete mode 100644 src/test/java/seedu/WikiImportTest.java diff --git a/build.gradle b/build.gradle index 096c5c405c..f9118b05a8 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,6 @@ repositories { } dependencies { - implementation 'org.fastily:jwiki:1.8.0' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' } @@ -44,4 +43,5 @@ checkstyle { run{ standardInput = System.in + enableAssertions = true } diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 696dc740e9..13bde35d68 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -36,6 +36,9 @@ public void run() { * Main entry-point for the java.duke.Duke application. */ public static void main(String[] args) { + assert true; new Main().run(); } + + } diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java deleted file mode 100644 index 1c464c7fb0..0000000000 --- a/src/main/java/seedu/typists/content/WikiImport.java +++ /dev/null @@ -1,17 +0,0 @@ -package seedu.typists.content; - -import org.fastily.jwiki.core.Wiki; -import seedu.typists.exception.InvalidArticleException; - -/** - * Imports the first paragraph of a text from Wikipedia. - */ -public class WikiImport { - public String getArticle(String article) throws InvalidArticleException { - Wiki wiki = new Wiki.Builder().build(); - if (!wiki.exists(article)) { - throw new InvalidArticleException(); - } - return wiki.getTextExtract(article); - } -} diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java deleted file mode 100644 index 4aba12037d..0000000000 --- a/src/test/java/seedu/WikiImportTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package seedu; - -import org.junit.jupiter.api.Test; -import seedu.typists.content.WikiImport; -import seedu.typists.exception.InvalidArticleException; -import seedu.typists.exception.InvalidStringInputException; -import seedu.typists.parser.StringParser; - -import java.util.ArrayList; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class WikiImportTest { - - // methodBeingTested_inputGiven_expectedOutcome - // Input, GitHub, relevant article (731 characters) - @Test - void getArticle_GitHub_expectArticle() throws InvalidArticleException { - String article = "GitHub"; - WikiImport wiki = new WikiImport(); - String content = wiki.getArticle(article); - assertEquals(731, content.length()); - } - - // test failure case - // method being tested, Githob, expect exception - @Test - void getArticle_Githob_expectException() { - String article = "Githob"; - WikiImport wiki = new WikiImport(); - assertThrows(InvalidArticleException.class, () -> wiki.getArticle(article)); - } -} From 2a7cecc58f1b1cf1f972c8d03cdcafb4cd716835 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 14 Oct 2021 14:28:01 +0800 Subject: [PATCH 037/272] create timermode game --- src/main/java/seedu/typists/Main.java | 38 +++--- .../java/seedu/typists/common/Messages.java | 17 +-- .../java/seedu/typists/game/TimeModeGame.java | 109 ++++++++++++------ src/main/java/seedu/typists/ui/TextUi.java | 29 +++-- 4 files changed, 107 insertions(+), 86 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 7a798c9ec3..dfa9a99b52 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,29 +1,25 @@ package seedu.typists; -<<<<<<< Updated upstream -import java.util.Scanner; -public class Main { -======= -import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; import seedu.typists.parser.Parser; import seedu.typists.ui.TextUi; import static seedu.typists.common.Messages.SAMPLE_TEXT; - //solution below adapted from https://github.com/se-edu/addressbook-level2/ public class Main { /** Version info of the program. */ public static final String VERSION = "Typist - Version 1.0"; - - public void start() { - TextUi uiBot = new TextUi(); - Parser parseBot = new Parser(); - TimeModeGame gameBot = new TimeModeGame(); - uiBot.showWelcomeMessage(VERSION); - gameBot.startGame(SAMPLE_TEXT, 5); + public static final int LINE_LENGTH = 10; + TextUi uiBot; + Parser parseBot; + TimeModeGame gameBot; + + public Main() { + this.uiBot = new TextUi(); + this.parseBot = new Parser(); + this.gameBot = new TimeModeGame(); } public void runCommandLoopUntilExitCommand() { @@ -34,6 +30,10 @@ public void exit() { } + public void start() { + uiBot.showWelcomeMessage(VERSION); + gameBot.startGame(SAMPLE_TEXT,10, LINE_LENGTH); + } /** Runs the program until termination. */ public void run() { start(); @@ -41,20 +41,10 @@ public void run() { exit(); } ->>>>>>> Stashed changes /** * Main entry-point for the java.duke.Duke application. */ public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); + new Main().run(); } } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index c9ef05439e..0db0b5780e 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -4,19 +4,6 @@ * Container for user visible messages. */ public class Messages { - -<<<<<<< Updated upstream - public static final String MESSAGE_GOODBYE = "Good bye!"; - public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; - public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; - public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in address book"; - public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; - public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " - + "java seedu.typists.Main [STORAGE_FILE_PATH]"; - public static final String MESSAGE_WELCOME = "Welcome to Typing Game!"; - public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; -======= public static final String LOGO = " ______ _ __ \n" + " /_ __/_ ______ (_)____/ /_\n" @@ -28,7 +15,8 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; //This sample text is gotten from https://www.lipsum.com/ - public static final String SAMPLE_TEXT = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; + public static final String SAMPLE_TEXT = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." + + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; //public static final String MESSAGE_GOODBYE = "Good bye!"; //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; @@ -38,5 +26,4 @@ public class Messages { //public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; //public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " // + "java seedu.typists.Main [STORAGE_FILE_PATH]"; ->>>>>>> Stashed changes } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 1013f17d6c..a9976d541d 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,8 +1,10 @@ package seedu.typists.game; +import org.w3c.dom.Text; import seedu.typists.ui.TextUi; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Scanner; import java.util.Timer; import java.util.TimerTask; @@ -10,10 +12,16 @@ import static seedu.typists.common.Messages.SAMPLE_TEXT; public class TimeModeGame extends Game { - private final TextUi uiBot; + ArrayList displayLines; + ArrayList inputLines; + boolean is_gameEnd; + TextUi uiBot; public TimeModeGame() { this.uiBot = new TextUi(); + this.is_gameEnd = false; + displayLines = new ArrayList <>(); + inputLines = new ArrayList <>(); } /** Currently still a dummy */ @@ -21,44 +29,75 @@ public String getTargetWordSet() { return SAMPLE_TEXT; } - public void startGame(String targetWordSet, int timeLimitSeconds) { - uiBot.showTargetWordSet(targetWordSet); - /* - TimerTask game = new TimerTask() { - @Override - public void run() { - System.out.println("Timer ends"); - } - }; + public boolean readyToStartTimer () { + Scanner in = new Scanner(System.in); + String command = ""; + while(!command.equals("yes")) { + System.out.println("Do you want to start now?"); + command = in.nextLine(); - Timer timer = new Timer(){ - @Override - public void cancel() { - super.cancel(); - System.out.println("Timer abort."); - } - }; - timer.schedule(game, timeLimitSeconds*1000 ); - System.out.println("counting " + timeLimitSeconds + " starting now:" ); - //task to do within timeLimit - timer.cancel(); - */ + } + return true; + } - //method 1 trying - LocalDateTime currentTime = LocalDateTime.now(); - System.out.println(currentTime); + public void startGame(String targetWordSet, int timeLimitSeconds, int wordsPerLine) { + Scanner in = new Scanner(System.in); + //refacter out this line later, pass in the arraylist to statGame + displayLines = uiBot.getDisplayWordLine(targetWordSet, wordsPerLine); - //method 2 trying - Scanner reader = new Scanner(System.in); - System.out.println("Enter a number: "); - long limit = 5000L; - long startTime = System.currentTimeMillis(); - Long l = reader.nextLong(); - if ((startTime + limit) < System.currentTimeMillis()) - System.out.println("Sorry, your answer is too late"); - else - System.out.println("Your answer is on time"); + if (readyToStartTimer()) { + int i = 0; + long beginTime = System.currentTimeMillis(); + //System.out.println("Timer starts now: " + beginTime); + boolean timeOver = false; + long currTime = 0; + inputLines = new ArrayList <>(); + while (!timeOver) { + currTime = System.currentTimeMillis() - beginTime; + //10000millisecond = 10 second + if (currTime >= timeLimitSeconds * 1000L) { + timeOver = true; + } else { + System.out.println(displayLines.get(i)); + String userInput = in.nextLine(); + inputLines.add(userInput); + i++; + } + } + int displayTime = (int)currTime/1000; + System.out.println("Game Finished. Total time taken: " + displayTime + "seconds. "); + compareData(displayLines, inputLines); +// this.gameTimer = new Timer(); +// gameTimer.schedule(endGame, timeLimitSeconds * 1000L); + } +// +// while(!is_gameEnd) { +// String userInput = in.next(); +// System.out.println(userInput); +// } +// System.out.println("ends."); + } + public void compareData(ArrayList checker, ArrayList answer){ + int totalErrorCount = 0; + for (int i = 0; i < answer.size(); i++) { + totalErrorCount += compareOneLine(checker.get(i), answer.get(i)); + } + System.out.println("Total number of wrong keystrokes: " + totalErrorCount); + } + + public int compareOneLine(String checker, String answer) { + int errorCount = 0; + for (int i = 0; i < checker.length(); i++) { + try { + if (checker.charAt(i) != answer.charAt(i)) { + errorCount++; + } + } catch (StringIndexOutOfBoundsException e) { + errorCount++; + } + } + return errorCount; } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 7008aa4785..a6234381d7 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,9 +1,5 @@ package seedu.typists.ui; - -<<<<<<< Updated upstream -======= -import java.sql.Array; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -15,14 +11,10 @@ import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; import static seedu.typists.common.Messages.MESSAGE_WELCOME; ->>>>>>> Stashed changes /** * Text UI of the application. */ public class TextUi { - -<<<<<<< Updated upstream -======= private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static final String DIVIDER = "****************************************************************"; @@ -55,9 +47,7 @@ public void printScreen(String... message) { } public ArrayList splitLineIntoWordList(String line) { - ArrayList wordList = new ArrayList <>(); - wordList.addAll(Arrays.asList(line.split(" "))); - return wordList; + return new ArrayList <>(Arrays.asList(line.split(" "))); } /** Print to screen the target words, each line 10 words */ @@ -73,5 +63,20 @@ public void showTargetWordSet(String TargetWordSet) { } out.print("\n"); } ->>>>>>> Stashed changes + + public ArrayList getDisplayWordLine(String TargetWordSet, int lineLength) { + ArrayList wordList = splitLineIntoWordList(TargetWordSet); + ArrayList wordLines = new ArrayList <>(); + int i = 1; + StringBuilder sb = new StringBuilder(); + for (String w : wordList) { + sb.append(w).append(" "); + if (i % lineLength == 0) { + wordLines.add(sb.toString().trim()); + sb = new StringBuilder(); + } + i++; + } + return wordLines; + } } From f408969b4b32ccf932a0b93b8b126c4968444117 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 14 Oct 2021 14:34:55 +0800 Subject: [PATCH 038/272] minor cleanups --- .../java/seedu/typists/game/TimeModeGame.java | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index a9976d541d..cb865ff5d6 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -12,14 +12,13 @@ import static seedu.typists.common.Messages.SAMPLE_TEXT; public class TimeModeGame extends Game { - ArrayList displayLines; - ArrayList inputLines; - boolean is_gameEnd; - TextUi uiBot; + private ArrayList displayLines; + private ArrayList inputLines; + private final TextUi uiBot; public TimeModeGame() { this.uiBot = new TextUi(); - this.is_gameEnd = false; + boolean is_gameEnd = false; displayLines = new ArrayList <>(); inputLines = new ArrayList <>(); } @@ -48,13 +47,11 @@ public void startGame(String targetWordSet, int timeLimitSeconds, int wordsPerLi if (readyToStartTimer()) { int i = 0; long beginTime = System.currentTimeMillis(); - //System.out.println("Timer starts now: " + beginTime); boolean timeOver = false; long currTime = 0; inputLines = new ArrayList <>(); while (!timeOver) { currTime = System.currentTimeMillis() - beginTime; - //10000millisecond = 10 second if (currTime >= timeLimitSeconds * 1000L) { timeOver = true; } else { @@ -64,20 +61,14 @@ public void startGame(String targetWordSet, int timeLimitSeconds, int wordsPerLi i++; } } - int displayTime = (int)currTime/1000; + int displayTime = (int) currTime / 1000; System.out.println("Game Finished. Total time taken: " + displayTime + "seconds. "); compareData(displayLines, inputLines); -// this.gameTimer = new Timer(); -// gameTimer.schedule(endGame, timeLimitSeconds * 1000L); - } -// -// while(!is_gameEnd) { -// String userInput = in.next(); -// System.out.println(userInput); -// } -// System.out.println("ends."); } + } + + public void compareData(ArrayList checker, ArrayList answer){ int totalErrorCount = 0; for (int i = 0; i < answer.size(); i++) { From be51740390b36654437f259b777ea8fa982ad794 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 14 Oct 2021 14:36:04 +0800 Subject: [PATCH 039/272] Error --- src/main/java/seedu/typists/Main.java | 3 --- .../java/seedu/typists/commands/NewGame.java | 1 + src/main/java/seedu/typists/common/Error.java | 20 +++++++++++++++++++ .../java/seedu/typists/common/Messages.java | 2 -- src/main/java/seedu/typists/common/Utils.java | 1 - src/main/java/seedu/typists/ui/TextUi.java | 4 +--- 6 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 src/main/java/seedu/typists/common/Error.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 13bde35d68..696dc740e9 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -36,9 +36,6 @@ public void run() { * Main entry-point for the java.duke.Duke application. */ public static void main(String[] args) { - assert true; new Main().run(); } - - } diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java index 80c97028e7..44a8321259 100644 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -4,4 +4,5 @@ * commands to initiate a new game. */ public class NewGame { + } diff --git a/src/main/java/seedu/typists/common/Error.java b/src/main/java/seedu/typists/common/Error.java new file mode 100644 index 0000000000..3f17681e87 --- /dev/null +++ b/src/main/java/seedu/typists/common/Error.java @@ -0,0 +1,20 @@ +package seedu.typists.common; + +import static java.lang.Math.min; + +/** + * Error rate calculator. + */ +public class Error { + public int lengthDifference(String content, String typed) { + return Math.abs(content.length() - typed.length()); + } + + public int characterDifference(String content, String typed) { + int charDiff = 0; + for (int i = 0; i < min(content.length(), typed.length()); i++) { + charDiff += (content.charAt(i) != typed.charAt(i) ? 1 : 0); + } + return charDiff + lengthDifference(content, typed); + } +} diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 6ff7edf496..932872e655 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -4,7 +4,6 @@ * Container for user visible messages. */ public class Messages { - public static final String LOGO = " ______ _ __\n" + " /_ __/_ ______ (_)____/ /_\n" @@ -12,7 +11,6 @@ public class Messages { + " / / / /_/ / /_/ / (__ ) /_\n" + "/_/ \\__, / .___/_/____/\\__/\n" + " /____/_/"; - public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 4f05b3ecae..ab5027eb46 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -5,5 +5,4 @@ */ public class Utils { - } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index bfc9e93524..87ddd8c094 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -14,9 +14,7 @@ * Text UI of the application. */ public class TextUi { - private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "****************************************************************"; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); @@ -44,7 +42,7 @@ public void showWelcomeMessage(String version) { public void printScreen(String... message) { for (String m: message) { - out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); + System.out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); } } } From 3baec0c43cdf6506aca7ba7d57f4a685dc004fbd Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 14 Oct 2021 17:34:11 +0800 Subject: [PATCH 040/272] Error + some books --- src/main/java/seedu/typists/common/Error.java | 4 ++ .../java/seedu/typists/content/Books.java | 61 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/main/java/seedu/typists/content/Books.java diff --git a/src/main/java/seedu/typists/common/Error.java b/src/main/java/seedu/typists/common/Error.java index 3f17681e87..3fe25b2299 100644 --- a/src/main/java/seedu/typists/common/Error.java +++ b/src/main/java/seedu/typists/common/Error.java @@ -17,4 +17,8 @@ public int characterDifference(String content, String typed) { } return charDiff + lengthDifference(content, typed); } + + public double errorRate(String content, String typed) { + return (double) characterDifference(content, typed) / content.length(); + } } diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java new file mode 100644 index 0000000000..145867a6f1 --- /dev/null +++ b/src/main/java/seedu/typists/content/Books.java @@ -0,0 +1,61 @@ +package seedu.typists.content; + +public class Books { + String para1 = "A green hunting cap squeezed the top of the fleshy " + + "balloon of a head. The green earflaps, " + + "full of large ears and uncut hair and the fine " + + "bristles that grew in the ears themselves, " + + "stuck out on either side like turn signals " + + "indicating two directions at once. " + + "Full, pursed lips protruded beneath the bushy black " + + "moustache and, at their corners, sank into little folds " + + "filled with disapproval and potato chip crumbs. " + + "In the shadow under the green visor of the cap Ignatius J. " + + "Reilly’s supercilious blue and yellow eyes looked down " + + "upon the other people waiting under the clock at the D.H. " + + "Holmes department store, studying the crowd of " + + "people for signs of bad taste in dress. " + + "Several of the outfits, Ignatius noticed, " + + "were new enough and expensive enough to be properly " + + "considered offenses against taste and decency. " + + "Possession of anything new or expensive only reflected a " + + "person’s lack of theology and geometry; it could even cast doubts upon one’s soul. "; + + String para2 = "Call me Ishmael. " + + "Some years ago — never mind how long precisely — " + + "having little or no money in my purse, " + + "and nothing particular to interest me on shore, " + + "I thought I would sail about " + + "a little and see the watery part of the world. It is a way " + + "I have of driving off the spleen, " + + "and regulating the circulation. " + + "Whenever I find myself growing grim about the mouth; " + + "whenever it is a damp, drizzly November in my soul; " + + "whenever I find myself involuntarily pausing before coffin " + + "warehouses, and bringing up the rear of every funeral I meet; " + + "and especially whenever my hypos get such an upper hand of me, " + + "that it requires a strong moral principle to prevent me from " + + "deliberately stepping into the street, " + + "and methodically knocking people’s hats off — then, " + + "I account it high time to get to sea as soon as I can. " + + "This is my substitute for pistol and ball. " + + "With a philosophical flourish Cato throws himself " + + "upon his sword; I quietly take to the ship. " + + "There is nothing surprising in this. If they but knew it, " + + "almost all men in their degree, some time or other, " + + "cherish very nearly the same feelings towards the ocean with me. "; + + String para3 = "In the late summer of that year we lived in " + + "a house in a village that looked across the river " + + "and the plain to the mountains. " + + "In the bed of the river there were pebbles and boulders, " + + "dry and white in the sun, and the water was clear and swiftly " + + "moving and blue in the channels. " + + "Troops went by the house and down the road and " + + "the dust they raised powdered the leaves of the trees. " + + "The trunks of the trees too were dusty and the leaves fell " + + "early that year and we saw the troops marching along the " + + "road and the dust rising and leaves, stirred by the breeze, " + + "falling and the soldiers marching and " + + "afterward the road bare and white except for the leaves."; +} From 695a8c87fd5e28050d927d8ee2b327e1a10778bc Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 17:46:00 +0800 Subject: [PATCH 041/272] Added a simple typing game --- src/main/java/seedu/typists/Main.java | 51 +++++++++++++++++-- .../java/seedu/typists/commands/NewGame.java | 48 +++++++++++++++-- .../java/seedu/typists/content/Content.java | 15 ++++-- .../exception/FaultyInputException.java | 5 +- .../exception/InvalidArticleException.java | 2 +- .../exception/InvalidCommandException.java | 2 +- .../InvalidStringInputException.java | 2 +- .../java/seedu/typists/parser/Parser.java | 45 ++++++++++++++++ .../seedu/typists/parser/StringParser.java | 8 +-- .../java/seedu/typists/parser/TextParser.java | 20 ++++++++ src/main/java/seedu/typists/ui/TextUi.java | 35 +++++++++++++ 11 files changed, 214 insertions(+), 19 deletions(-) create mode 100644 src/main/java/seedu/typists/parser/TextParser.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 13bde35d68..b39acaf4ff 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,28 +1,71 @@ package seedu.typists; +import seedu.typists.commands.NewGame; +import seedu.typists.exception.FaultyInputException; +import seedu.typists.exception.InvalidStringInputException; import seedu.typists.parser.Parser; +import seedu.typists.storage.StorageFile; import seedu.typists.ui.TextUi; +import java.io.IOException; + //solution below adapted from https://github.com/se-edu/addressbook-level2/ public class Main { /** Version info of the program. */ public static final String VERSION = "Typist - Version 1.0"; TextUi uiBot; - Parser parseBot; + NewGame game; + StorageFile storage; public void start() { this.uiBot = new TextUi(); - this.parseBot = new Parser(); + this.game = new NewGame(); + this.storage = new StorageFile(); uiBot.showWelcomeMessage(VERSION); } - public void runCommandLoopUntilExitCommand() { + public static void executeCommand(Parser c, NewGame game, StorageFile storage) throws InvalidStringInputException { + switch (c.getCommand()) { + case "bye": + break; + case "new": + game.beginNewGame(); + break; + default: + break; + } + //storage.writeToFile(tasks); + } + public void runCommandLoopUntilExitCommand() { + boolean isExit = false; + while (!isExit) { + try { + String fullCommand = uiBot.readCommand(); + uiBot.showLine(); // show the divider line ("_______") + Parser c = new Parser(fullCommand); + c.parse(); + executeCommand(c,game,storage); + isExit = c.getIsExit(); + } catch (StringIndexOutOfBoundsException e) { + uiBot.showText("OOPS!!! The description after this command word cannot be empty."); + } catch (IndexOutOfBoundsException e) { + uiBot.showText("OOPS!!! It's out of range."); + } catch (NumberFormatException e) { + uiBot.showText("OOPS!!! Input after done/delete must be a number."); + } catch (FaultyInputException e) { + uiBot.showText(e.getMessage()); + } catch (InvalidStringInputException e) { + e.printStackTrace(); + } finally { + uiBot.showLine(); + } + } } public void exit() { - + uiBot.showBye(); } /** Runs the program until termination. */ diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java index 80c97028e7..a7080bba4b 100644 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -1,7 +1,49 @@ package seedu.typists.commands; -/* - * commands to initiate a new game. - */ +import seedu.typists.exception.FaultyInputException; +import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.parser.Parser; +import seedu.typists.parser.TextParser; +import seedu.typists.ui.TextUi; + +import java.util.ArrayList; + +import static seedu.typists.parser.StringParser.splitString; + public class NewGame { + private ArrayList game1; + private static int game_index; + TextUi uiGame; + + public NewGame() { + this.game1 = new ArrayList<>(100); + this.game_index = 0; + this.uiGame = new TextUi(); + } + + public int getTotalSentence() { + return game1.size(); + } + + public void beginNewGame() throws InvalidStringInputException { + String content1 = "The greatest glory in living lies not in never falling."; + game1 = splitString(content1," "); + boolean isExit = false; + while (!isExit) { + uiGame.showText(game1.get(game_index)); + String fullCommand = uiGame.readCommand(); + TextParser c = new TextParser(fullCommand, game1.get(game_index)); + isExit = c.getIsExit(); + game_index += 1; + uiGame.printProgress(); + uiGame.showNumber(game_index); + uiGame.showText("out of"); + uiGame.showNumber(getTotalSentence()); + if (game_index == getTotalSentence()) { + uiGame.printSuccess(); + break; + } + } + } + } diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 220be56cb5..0532a137a4 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -1,16 +1,23 @@ package seedu.typists.content; +import java.util.ArrayList; + /** * Content object. */ public class Content { - private String content; + private ArrayList content; public void setContent(String content) { - this.content = content; + this.content = new ArrayList<>(100); + String content1 = "The greatest glory in living lies not in never falling, but in rising every time we fall."; + String content2 = "The way to get started is to quit talking and begin doing."; + this.content.set(0,content1); + this.content.set(1,content2); } - public String getContent() { - return content; + + public String getContent(int index) { + return content.get(index); } } diff --git a/src/main/java/seedu/typists/exception/FaultyInputException.java b/src/main/java/seedu/typists/exception/FaultyInputException.java index 3648a67940..d7c4e303b7 100644 --- a/src/main/java/seedu/typists/exception/FaultyInputException.java +++ b/src/main/java/seedu/typists/exception/FaultyInputException.java @@ -1,4 +1,7 @@ package seedu.typists.exception; -public class FaultyInputException { +public class FaultyInputException extends Exception { + public FaultyInputException(String errorMessage) { + super(errorMessage); + } } diff --git a/src/main/java/seedu/typists/exception/InvalidArticleException.java b/src/main/java/seedu/typists/exception/InvalidArticleException.java index 734b6ca5fb..a6db81f253 100644 --- a/src/main/java/seedu/typists/exception/InvalidArticleException.java +++ b/src/main/java/seedu/typists/exception/InvalidArticleException.java @@ -1,6 +1,6 @@ package seedu.typists.exception; -public class InvalidArticleException extends Throwable { +public class InvalidArticleException extends Exception { @Override public String getMessage() { return "Invalid article given" + super.getMessage(); diff --git a/src/main/java/seedu/typists/exception/InvalidCommandException.java b/src/main/java/seedu/typists/exception/InvalidCommandException.java index 375db1d263..762c54b2e1 100644 --- a/src/main/java/seedu/typists/exception/InvalidCommandException.java +++ b/src/main/java/seedu/typists/exception/InvalidCommandException.java @@ -1,4 +1,4 @@ package seedu.typists.exception; -public class InvalidCommandException { +public class InvalidCommandException extends Exception{ } diff --git a/src/main/java/seedu/typists/exception/InvalidStringInputException.java b/src/main/java/seedu/typists/exception/InvalidStringInputException.java index cb3a2b2f56..4e183fecd9 100644 --- a/src/main/java/seedu/typists/exception/InvalidStringInputException.java +++ b/src/main/java/seedu/typists/exception/InvalidStringInputException.java @@ -1,6 +1,6 @@ package seedu.typists.exception; -public class InvalidStringInputException extends Throwable { +public class InvalidStringInputException extends Exception { @Override public String getMessage() { return "Invalid input given" + super.getMessage(); diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index 09b6de7b3a..f7e2cdb62a 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -1,9 +1,54 @@ package seedu.typists.parser; +import seedu.typists.exception.FaultyInputException; + /** * Parses user input. */ public class Parser { + protected String input; + protected String command; + protected String description; + protected Boolean isExit; + + /** + * Parser with input and a boolean. + * command by default = "default" + * @param input takes user input + */ + public Parser(String input) { + this.input = input; + this.isExit = false; + this.command = "default"; + } + + /** + *Get exit. + * @return obtain the Exit status + */ + public Boolean getIsExit() { + return isExit; + } + + + public void parse() throws FaultyInputException { + if (input.equals("bye")) { + isExit = true; + command = "bye"; + } else if (input.equals("new")) { + command = "new"; + } + } + + public String getCommand() { + return command; + } + public String getDescription() throws FaultyInputException { + if (description.isEmpty()) { + throw new FaultyInputException("OOPS!!! The description cannot be empty."); + } + return description; + } } diff --git a/src/main/java/seedu/typists/parser/StringParser.java b/src/main/java/seedu/typists/parser/StringParser.java index 17bf380ab1..3743df093d 100644 --- a/src/main/java/seedu/typists/parser/StringParser.java +++ b/src/main/java/seedu/typists/parser/StringParser.java @@ -10,17 +10,17 @@ public class StringParser { /** * Splits the string based on the separator provided as parameter. * - * @param stringToSplit the string to be split + * @param s the string to be split * @param separator a string representing the separator that you want to split the string on * @return ArrayList of strings */ - public ArrayList splitString(String stringToSplit, String separator) throws InvalidStringInputException { + public static ArrayList splitString(String s, String separator) throws InvalidStringInputException { - if (stringToSplit == null) { + if (s == null) { throw new InvalidStringInputException(); } ArrayList stringParts = new ArrayList<>(); - stringParts.addAll(Arrays.asList(stringToSplit.split(separator))); + stringParts.addAll(Arrays.asList(s.split(separator))); return stringParts; } diff --git a/src/main/java/seedu/typists/parser/TextParser.java b/src/main/java/seedu/typists/parser/TextParser.java new file mode 100644 index 0000000000..676bead072 --- /dev/null +++ b/src/main/java/seedu/typists/parser/TextParser.java @@ -0,0 +1,20 @@ +package seedu.typists.parser; + +public class TextParser { + protected String input; + protected Boolean isExit; + + + public TextParser(String input, String text) { + this.input = input; + this.isExit = !input.equals(text); + } + + /** + * Get exit. + * @return obtain the Exit status + */ + public Boolean getIsExit() { + return isExit; + } +} diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index bfc9e93524..717fba5b40 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -3,6 +3,7 @@ import java.sql.Timestamp; import java.text.SimpleDateFormat; +import java.util.Scanner; import static java.lang.System.lineSeparator; import static java.lang.System.out; @@ -47,4 +48,38 @@ public void printScreen(String... message) { out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); } } + + public static String readCommand() { + Scanner sc = new Scanner(System.in); + return sc.nextLine(); + } + + public static void showLine() { + System.out.println(DIVIDER); + } + + /** + * Print error message. + * @param meg obtained from DukeException message + */ + public static void showText(String meg) { + System.out.println(meg); + } + + public static void showNumber(int i) { + System.out.println(String.valueOf(i)); + } + + public static void showBye() { + System.out.println("Bye. Hope to see you again soon!"); + } + + public static void printProgress() { + System.out.println("So far so good."); + } + + public static void printSuccess() { + System.out.println("Finished!"); + } + } From dd3e1d1728f62db46ba9534e4a72d52778b578ed Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 17:54:42 +0800 Subject: [PATCH 042/272] Fix bug missing NoSuchElementException --- src/main/java/seedu/typists/Main.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b39acaf4ff..ecadc5bafa 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -8,6 +8,7 @@ import seedu.typists.ui.TextUi; import java.io.IOException; +import java.util.NoSuchElementException; //solution below adapted from https://github.com/se-edu/addressbook-level2/ @@ -58,6 +59,8 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText(e.getMessage()); } catch (InvalidStringInputException e) { e.printStackTrace(); + } catch (NoSuchElementException e) { + e.printStackTrace(); } finally { uiBot.showLine(); } From 48f2feed9014c16b3f4ef652726ec9df59f9a440 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 14 Oct 2021 17:57:28 +0800 Subject: [PATCH 043/272] Some more books --- .../java/seedu/typists/content/Books.java | 147 +++++++++++++++++- 1 file changed, 142 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java index 145867a6f1..eb4590970f 100644 --- a/src/main/java/seedu/typists/content/Books.java +++ b/src/main/java/seedu/typists/content/Books.java @@ -1,7 +1,8 @@ package seedu.typists.content; public class Books { - String para1 = "A green hunting cap squeezed the top of the fleshy " + String aconfederacyofdunces = "A green hunting " + + "cap squeezed the top of the fleshy " + "balloon of a head. The green earflaps, " + "full of large ears and uncut hair and the fine " + "bristles that grew in the ears themselves, " @@ -19,9 +20,10 @@ public class Books { + "were new enough and expensive enough to be properly " + "considered offenses against taste and decency. " + "Possession of anything new or expensive only reflected a " - + "person’s lack of theology and geometry; it could even cast doubts upon one’s soul. "; + + "person’s lack of theology and geometry;" + + "it could even cast doubts upon one’s soul. "; - String para2 = "Call me Ishmael. " + String mobydick = "Call me Ishmael. " + "Some years ago — never mind how long precisely — " + "having little or no money in my purse, " + "and nothing particular to interest me on shore, " @@ -43,9 +45,10 @@ public class Books { + "upon his sword; I quietly take to the ship. " + "There is nothing surprising in this. If they but knew it, " + "almost all men in their degree, some time or other, " - + "cherish very nearly the same feelings towards the ocean with me. "; + + "cherish very nearly the same " + + "feelings towards the ocean with me."; - String para3 = "In the late summer of that year we lived in " + String afarewelltoarms = "In the late summer of that year we lived in " + "a house in a village that looked across the river " + "and the plain to the mountains. " + "In the bed of the river there were pebbles and boulders, " @@ -58,4 +61,138 @@ public class Books { + "road and the dust rising and leaves, stirred by the breeze, " + "falling and the soldiers marching and " + "afterward the road bare and white except for the leaves."; + + String ataleoftwocities = "It was the best of times, " + + "it was the worst of times, " + + "it was the age of wisdom, it was the age of foolishness, " + + "it was the epoch of belief, it was the epoch of incredulity, " + + "it was the season of Light, it was the season of Darkness, " + + "it was the spring of hope, it was the winter of despair, " + + "we had everything before us, we had nothing before us, " + + "we were all going direct to Heaven, " + + "we were all going direct the other way — " + + "in short, the period was so far like the present period, " + + "that some of its noisiest authorities insisted on its being " + + "received, for good or for evil, " + + "in the superlative degree of comparison only. "; + + String ontheroad = "I first met Dean not long " + + "after my wife and I split up. " + + "I had just gotten over a serious illness that " + + "I won’t bother to talk about, except that " + + "it had something to do with the miserably weary " + + "split-up and my feeling that everything was dead. " + + "With the coming of Dean Moriarty began the part " + + "of my life you could call my life on the road. " + + "Before that I’d often dreamed of going West to see the " + + "country, always vaguely planning and never taking off. " + + "Dean is the perfect guy for the road because he " + + "actually was born on the road, " + + "when his parents were passing through Salt Lake City in 1926, " + + "in a jalopy, on their way to Los Angeles. " + + "First reports of him came to me through Chad King, " + + "who’d shown me a few letters from him written in a " + + "New Mexico reform school. I was tremendously interested " + + "in the letters because they so naively and sweetly asked " + + "Chad to teach him all about Nietzsche and all the wonderful " + + "intellectual things that Chad knew. At one point Carlo and " + + "I talked about the letters and wondered if we would ever meet " + + "the strange Dean Moriarty. This is all far back, " + + "when Dean was not the way he is today, when he was a " + + "young jailkid shrouded in mystery. Then news came that Dean " + + "was out of reform school and was coming to New York for the " + + "first time; also there was talk that he had just " + + "married a girl called Marylou. "; + + String prideandprejudice = "It is a truth universally acknowledged, " + + "that a single man in possession of a good fortune must be in " + + "want of a wife. However little known the feelings or " + + "views of such a man may be on his first entering a " + + "neighbourhood, this truth is so well fixed in the minds of the " + + "surrounding families, that he is considered as the rightful " + + "property of some one or other of their daughters."; + + String whitefang = "Dark spruce forest frowned on either side of the " + + "frozen waterway. The trees had been stripped by a " + + "recent wind of their white covering of frost, " + + "and they seemed to lean toward each other, " + + "black and ominous, in the fading light. " + + "A vast silence reigned over the land. " + + "The land itself was a desolation, lifeless, " + + "without movement, so lone and cold that the spirit of " + + "it was not even that of sadness. " + + "There was a hint in it of laughter, " + + "but of a laughter more terrible than any sadness — " + + "a laughter that was mirthless as the smile of the Sphinx, " + + "a laughter cold as the frost and partaking of the " + + "grimness of infallibility. " + + "It was the masterful and incommunicable " + + "wisdom of eternity laughing at the futility " + + "of life and the effort of life. " + + "It was the Wild, the savage, frozen-hearted Northland Wild."; + + String americanpsycho = "ABANDON ALL HOPE YE WHO ENTER HERE is " + + "scrawled in blood red lettering on " + + "the side of the Chemical Bank near the corner of " + + "Eleventh and First and is in print large enough to be seen " + + "from the backseat of the cab as it lurches forward in " + + "the traffic leaving Wall Street and just as Timothy " + + "Price notices the words a bus pulls up, " + + "the advertisement for Les Miserables on its side blocking " + + "his view, but Price who is with Pierce & Pierce " + + "and twenty-six doesn't seem to care because he " + + "tells the driver he will give him five dollars to turn " + + "up the radio, \"Be My Baby\" on WYNN, " + + "and the driver, black, not American, does so."; + + String notesfromunderground = "I am a sick man. ... " + + "I am a spiteful man. I am an unattractive man. " + + "I believe my liver is diseased. However, " + + "I know nothing at all about my disease, " + + "and do not know for certain what ails me. " + + "I don't consult a doctor for it, and never have, " + + "though I have a respect for medicine and doctors. " + + "Besides, I am extremely superstitious, " + + "sufficiently so to respect medicine, anyway " + + "(I am well-educated enough not to be superstitious, " + + "but I am superstitious). No, " + + "I refuse to consult a doctor from spite. " + + "That you probably will not understand. " + + "Well, I understand it, though. Of course, " + + "I can't explain who it is precisely that " + + "I am mortifying in this case by my spite: " + + "I am perfectly well aware that I cannot \"pay " + + "out\" the doctors by not consulting them; " + + "I know better than anyone that by all this " + + "I am only injuring myself and no one else. " + + "But still, if I don't consult a doctor it is from spite. " + + "My liver is bad, well then let it hurt even worse!"; + + String metamorphosis = "As Gregor Samsa awoke one " + + "morning from uneasy dreams he found himself transformed " + + "in his bed into a gigantic insect. " + + "He was lying on his hard, as it were armor-plated, " + + "back and when he lifted his head a little he " + + "could see his dome-like brown belly divided into " + + "stiff arched segments on top of which the " + + "bed quilt could hardly keep in position and " + + "was about to slide off completely. " + + "His numerous legs, which were pitifully thin " + + "compared to the rest of his bulk, " + + "waved helplessly before his eyes."; + + String theadventuresofhuckleberryfinn = "You don't know " + + "about me without you have read a book by the " + + "name of The Adventures of Tom Sawyer; " + + "but that ain't no matter. That book was made " + + "by Mr. Mark Twain, and he told the truth, mainly. " + + "There was things which he stretched, " + + "but mainly he told the truth. " + + "That is nothing. I never seen anybody " + + "but lied one time or another, without " + + "it was Aunt Polly, or the widow, or " + + "maybe Mary. Aunt Polly - Tom's Aunt Polly, " + + "she is - and Mary, and the Widow Douglas is " + + "all told about in that book, which is mostly a " + + "true book, with some stretchers, as I said before."; } From c385a6a277812b753ecc472fa080701d3dd602d6 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 18:09:22 +0800 Subject: [PATCH 044/272] Ui improve for printProgress() --- src/main/java/seedu/typists/commands/NewGame.java | 6 ++---- src/main/java/seedu/typists/ui/TextUi.java | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java index a7080bba4b..5c9e54c810 100644 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -28,6 +28,7 @@ public int getTotalSentence() { public void beginNewGame() throws InvalidStringInputException { String content1 = "The greatest glory in living lies not in never falling."; game1 = splitString(content1," "); + uiGame.showText(content1); boolean isExit = false; while (!isExit) { uiGame.showText(game1.get(game_index)); @@ -35,10 +36,7 @@ public void beginNewGame() throws InvalidStringInputException { TextParser c = new TextParser(fullCommand, game1.get(game_index)); isExit = c.getIsExit(); game_index += 1; - uiGame.printProgress(); - uiGame.showNumber(game_index); - uiGame.showText("out of"); - uiGame.showNumber(getTotalSentence()); + uiGame.printGameMode1Progress(game_index,getTotalSentence()); if (game_index == getTotalSentence()) { uiGame.printSuccess(); break; diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 717fba5b40..8607408f99 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -74,8 +74,8 @@ public static void showBye() { System.out.println("Bye. Hope to see you again soon!"); } - public static void printProgress() { - System.out.println("So far so good."); + public static void printGameMode1Progress(int a, int b) { + System.out.println("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } public static void printSuccess() { From e689fb82f1208f5b0eb0cd835e58bb200163f2d4 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 18:15:11 +0800 Subject: [PATCH 045/272] Added some input and output --- text-ui-test/EXPECTED.TXT | 12 ++++++++++++ text-ui-test/input.txt | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 086638cfa2..bf603d78ca 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -9,3 +9,15 @@ | Welcome to Typist -- the ultimate cli typing game. | Brought to you by -- AY2122S1-CS2113-T13-4. | **************************************************************** +**************************************************************** +The greatest glory in living lies not in never falling. +The +Your progress:1/10 +greatest +Your progress:2/10 +glory +Your progress:4/10 +**************************************************************** +**************************************************************** +**************************************************************** +Bye. Hope to see you again soon! \ No newline at end of file diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb2..45db62e734 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,6 @@ +new +The +greatest +glory +.. +bye \ No newline at end of file From c4dfb4d50f71dcf65882f9187f7f5f5d229334e8 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 14 Oct 2021 18:19:20 +0800 Subject: [PATCH 046/272] Some more books --- .../java/seedu/typists/content/Books.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java index eb4590970f..409960c46e 100644 --- a/src/main/java/seedu/typists/content/Books.java +++ b/src/main/java/seedu/typists/content/Books.java @@ -104,6 +104,44 @@ public class Books { + "first time; also there was talk that he had just " + "married a girl called Marylou. "; + String brightonrock = "Hale knew, before he had been in Brighton " + + "three hours, that they meant to murder him. " + + "With his inky fingers and his bitten nails, " + + "his manner cynical and nervous, " + + "anybody could tell he didn’t belong – " + + "belong to the early summer sun, the cool " + + "Whitsun wind off the sea, the holiday crowd. " + + "They came in by train from Victoria every five minutes, " + + "rocked down Queen’s Road standing on the " + + "tops of the little local trams, stepped off " + + "in bewildered multitudes into fresh and " + + "glittering air: the new silver paint sparkled on the piers, " + + "the cream houses ran away into the west like a " + + "pale Victorian water-colour; a race in miniature motors, " + + "a band playing, flower gardens in bloom below the " + + "front, an aeroplane advertising something for " + + "the health in pale vanishing clouds across the sky."; + + String pickup = "It must have been around a quarter to eleven. " + + "A sailor came in and ordered a chile dog and coffee. " + + "I sliced a bun, jerked a frank out of the boiling water, " + + "nested it, poured a half-dipper of chile over the frank " + + "and sprinkled it liberally with chopped onions. " + + "I scribbled a check and put it by his plate. " + + "I wouldn’t have recommended the unpalatable mess " + + "to a starving animal. The sailor was the only customer, " + + "and after he ate his dog he left. " + + "That was the exact moment she entered. " + + "A small woman, hardly more than five feet. " + + "She had the figure of a teenage girl. " + + "Her suit was a blue tweed, smartly cut, " + + "and over her thin shoulders she wore a fur jacket, " + + "bolero length. Tiny gold circular earrings " + + "clung to her small pierced ears. " + + "Her hands and feet were small, " + + "and when she seated herself at " + + "the counter I noticed she wasn’t wearing any rings."; + String prideandprejudice = "It is a truth universally acknowledged, " + "that a single man in possession of a good fortune must be in " + "want of a wife. However little known the feelings or " @@ -168,6 +206,17 @@ public class Books { + "But still, if I don't consult a doctor it is from spite. " + "My liver is bad, well then let it hurt even worse!"; + String thehauntingofhillhouse = "No live organism can continue " + + "for long to exist sanely under conditions of absolute " + + "reality; even larks and katydids are supposed, by some, " + + "to dream. Hill House, not sane, stood by itself against " + + "its hills, holding darkness within; it had stood so for " + + "eighty years and might stand for eighty more. " + + "Within, walls continued upright, bricks met neatly, " + + "floors were firm, and doors were sensibly shut; " + + "silence lay steadily against the wood and " + + "stone of Hill House, and whatever walked there, walked alone…"; + String metamorphosis = "As Gregor Samsa awoke one " + "morning from uneasy dreams he found himself transformed " + "in his bed into a gigantic insect. " @@ -181,6 +230,19 @@ public class Books { + "compared to the rest of his bulk, " + "waved helplessly before his eyes."; + String invisibleman = "I am an invisible man. " + + "No, I am not a spook like those who haunted Edgar Allan Poe; " + + "nor am I one of your Hollywood-movie ectoplasms. " + + "I am a man of substance, of flesh and bone, fiber " + + "and liquids—and I might even be said to possess a mind. " + + "I am invisible, understand, simply because people " + + "refuse to see me. Like the bodiless heads you see " + + "sometimes in circus sideshows, it is as though " + + "I have been surrounded by mirrors of hard, distorting glass. " + + "When they approach me they see only my surroundings, " + + "themselves, or figments of their imagination—" + + "indeed, everything and anything except me."; + String theadventuresofhuckleberryfinn = "You don't know " + "about me without you have read a book by the " + "name of The Adventures of Tom Sawyer; " From 04426943ff5dd0b30617e20c8a8e67fb0fe66277 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 19:03:26 +0800 Subject: [PATCH 047/272] Debug the gradle 'clean' --- src/main/java/seedu/typists/Main.java | 1 + text-ui-test/EXPECTED.TXT | 9 --------- text-ui-test/input.txt | 5 ----- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index ecadc5bafa..a74b9cade5 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -69,6 +69,7 @@ public void runCommandLoopUntilExitCommand() { public void exit() { uiBot.showBye(); + return; } /** Runs the program until termination. */ diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index bf603d78ca..1781ad24db 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -10,14 +10,5 @@ | Brought to you by -- AY2122S1-CS2113-T13-4. | **************************************************************** **************************************************************** -The greatest glory in living lies not in never falling. -The -Your progress:1/10 -greatest -Your progress:2/10 -glory -Your progress:4/10 -**************************************************************** -**************************************************************** **************************************************************** Bye. Hope to see you again soon! \ No newline at end of file diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 45db62e734..0abaeaa993 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,6 +1 @@ -new -The -greatest -glory -.. bye \ No newline at end of file From 28010cfc690899898381c032b9ee880f63d02323 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 14 Oct 2021 20:08:11 +0800 Subject: [PATCH 048/272] Debug, added a \n --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 1781ad24db..13a9b0146e 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -11,4 +11,4 @@ | **************************************************************** **************************************************************** **************************************************************** -Bye. Hope to see you again soon! \ No newline at end of file +Bye. Hope to see you again soon! From cd7d184c3072ad11a4fdb4de8a0c7ab95ffcef18 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 14:10:26 +0800 Subject: [PATCH 049/272] working version --- src/main/java/seedu/typists/Main.java | 9 ++- .../java/seedu/typists/common/Messages.java | 15 +++- src/main/java/seedu/typists/common/Utils.java | 34 +++++++++ .../seedu/typists/game/DataProcessor.java | 67 ++++++++++++++++ .../java/seedu/typists/game/TimeModeGame.java | 76 ++++++------------- src/main/java/seedu/typists/ui/TextUi.java | 37 +++------ 6 files changed, 151 insertions(+), 87 deletions(-) create mode 100644 src/main/java/seedu/typists/game/DataProcessor.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index dfa9a99b52..d559b20123 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,6 +1,7 @@ package seedu.typists; +import seedu.typists.game.DataProcessor; import seedu.typists.game.TimeModeGame; import seedu.typists.parser.Parser; import seedu.typists.ui.TextUi; @@ -12,14 +13,14 @@ public class Main { /** Version info of the program. */ public static final String VERSION = "Typist - Version 1.0"; public static final int LINE_LENGTH = 10; + /** game time in seconds */ + public static final int GAME_TIME = 15; TextUi uiBot; Parser parseBot; - TimeModeGame gameBot; public Main() { this.uiBot = new TextUi(); this.parseBot = new Parser(); - this.gameBot = new TimeModeGame(); } public void runCommandLoopUntilExitCommand() { @@ -32,7 +33,9 @@ public void exit() { public void start() { uiBot.showWelcomeMessage(VERSION); - gameBot.startGame(SAMPLE_TEXT,10, LINE_LENGTH); + TimeModeGame g = new TimeModeGame(SAMPLE_TEXT, GAME_TIME, LINE_LENGTH); + DataProcessor p = new DataProcessor(g); + uiBot.showSummary(p.getErrorWordCount(), p.getWPM(), p.getTotalWordTyped(), p.totalTime); } /** Runs the program until termination. */ public void run() { diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 0db0b5780e..c7780c79fb 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -15,8 +15,19 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; //This sample text is gotten from https://www.lipsum.com/ - public static final String SAMPLE_TEXT = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." + - "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; + public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting industry" + + "imply dummy text of the printing and typesetting industry ipum is simply dummy" + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy" + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry" + + "industry industry industry industry industry industry industry industry industry industry industry"; //public static final String MESSAGE_GOODBYE = "Good bye!"; //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 4f05b3ecae..a91c7ae60c 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -1,9 +1,43 @@ package seedu.typists.common; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; + /** * Utility methods. */ public class Utils { + /** convert the line of text into an arraylist of word */ + public static ArrayList splitStringIntoWordList(String line) { + return new ArrayList<>(Arrays.asList(line.split(" "))); + } + + /** group the word list into groups of x, where x is the number of words per line */ + public static ArrayList getWordLine(String text, int lineLength) { + ArrayList wordList = splitStringIntoWordList(text); + ArrayList wordLines = new ArrayList <>(); + int j = 0; + String[] line = new String[lineLength]; + for (String w : wordList) { + if (j == lineLength) { + wordLines.add(line.clone()); + j = 0; + } else { + line[j] = w; + j++; + } + } + return wordLines; + } + public static ArrayList getWordLineFromStringArray(ArrayList stringList) { + ArrayList wordLines = new ArrayList<>(); + for (String s : stringList) { + String[] wordLine = s.split(" "); + wordLines.add(wordLine); + } + return wordLines; + } } diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java new file mode 100644 index 0000000000..785ae973f9 --- /dev/null +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -0,0 +1,67 @@ +package seedu.typists.game; + +import java.util.ArrayList; + +import static seedu.typists.Main.LINE_LENGTH; +import static seedu.typists.common.Utils.getWordLineFromStringArray; + +public class DataProcessor { + private final ArrayList checkerWordLines; + private final ArrayList userWordLines; + public final int totalTime; + + public DataProcessor(TimeModeGame tg) { + //ArrayList checkerWordLines, ArrayList userText, int lineLength, int totalTime){ + this.checkerWordLines = tg.wordLines; + this.userWordLines = getWordLineFromStringArray(tg.inputLines); + this.totalTime = tg.gameTime; + } + + public int getErrorWordCount() { + int errorWordCount = 0; + int i = 0; + for (String[] sa : userWordLines) { + String[] checker = checkerWordLines.get(i); + int ii = 0; + for (String s : sa) { + if (!s.equals(checker[ii])) { + errorWordCount++; + } + ii++; + } + i++; + } + return errorWordCount; + } + + public int getTotalWordTyped() { + return userWordLines.size() * LINE_LENGTH; + } + + public double getWPM() { + return getTotalWordTyped()/ ((double)totalTime/60); + } + + + public void getWrongKeyStrokes(ArrayList checkerText, ArrayList userText){ + int totalErrorCount = 0; + for (int i = 0; i < userText.size(); i++) { + totalErrorCount += getLineWrongKeyStrokes(checkerText.get(i), userText.get(i)); + } + System.out.println("Total number of wrong keystrokes: " + totalErrorCount); + } + + public int getLineWrongKeyStrokes(String checker, String answer) { + int errorCount = 0; + for (int i = 0; i < checker.length(); i++) { + try { + if (checker.charAt(i) != answer.charAt(i)) { + errorCount++; + } + } catch (StringIndexOutOfBoundsException e) { + errorCount++; + } + } + return errorCount; + } +} diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index cb865ff5d6..1f49cefe2a 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,31 +1,26 @@ package seedu.typists.game; -import org.w3c.dom.Text; -import seedu.typists.ui.TextUi; - -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Scanner; -import java.util.Timer; -import java.util.TimerTask; -import static seedu.typists.common.Messages.SAMPLE_TEXT; +import seedu.typists.ui.TextUi; +import static seedu.typists.common.Utils.getWordLine; public class TimeModeGame extends Game { - private ArrayList displayLines; - private ArrayList inputLines; - private final TextUi uiBot; + private final TextUi ui; - public TimeModeGame() { - this.uiBot = new TextUi(); - boolean is_gameEnd = false; - displayLines = new ArrayList <>(); - inputLines = new ArrayList <>(); - } + protected final ArrayList wordLines; + protected final int gameTime; - /** Currently still a dummy */ - public String getTargetWordSet() { - return SAMPLE_TEXT; + protected ArrayList inputLines; + protected int displayTime; + + public TimeModeGame(String targetWordSet, int gameTime, int wordsPerLine) { + this.gameTime = gameTime; + ui = new TextUi(); + inputLines = new ArrayList <>(); + wordLines = getWordLine(targetWordSet, wordsPerLine); + startGame(); } public boolean readyToStartTimer () { @@ -39,56 +34,29 @@ public boolean readyToStartTimer () { return true; } - public void startGame(String targetWordSet, int timeLimitSeconds, int wordsPerLine) { + public void startGame() { Scanner in = new Scanner(System.in); - //refacter out this line later, pass in the arraylist to statGame - displayLines = uiBot.getDisplayWordLine(targetWordSet, wordsPerLine); if (readyToStartTimer()) { int i = 0; long beginTime = System.currentTimeMillis(); boolean timeOver = false; - long currTime = 0; - inputLines = new ArrayList <>(); + long realGameTime = 0; + while (!timeOver) { - currTime = System.currentTimeMillis() - beginTime; - if (currTime >= timeLimitSeconds * 1000L) { + long currTime = System.currentTimeMillis() - beginTime; + if (currTime >= gameTime * 1000L) { timeOver = true; + realGameTime = currTime; } else { - System.out.println(displayLines.get(i)); + ui.printLine(wordLines.get(i)); String userInput = in.nextLine(); inputLines.add(userInput); i++; } } - int displayTime = (int) currTime / 1000; + displayTime = (int) realGameTime / 1000; System.out.println("Game Finished. Total time taken: " + displayTime + "seconds. "); - - compareData(displayLines, inputLines); } } - - - public void compareData(ArrayList checker, ArrayList answer){ - int totalErrorCount = 0; - for (int i = 0; i < answer.size(); i++) { - totalErrorCount += compareOneLine(checker.get(i), answer.get(i)); - } - System.out.println("Total number of wrong keystrokes: " + totalErrorCount); - } - - public int compareOneLine(String checker, String answer) { - int errorCount = 0; - for (int i = 0; i < checker.length(); i++) { - try { - if (checker.charAt(i) != answer.charAt(i)) { - errorCount++; - } - } catch (StringIndexOutOfBoundsException e) { - errorCount++; - } - } - return errorCount; - } - } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index a6234381d7..3acf5b317e 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -46,37 +46,18 @@ public void printScreen(String... message) { } } - public ArrayList splitLineIntoWordList(String line) { - return new ArrayList <>(Arrays.asList(line.split(" "))); - } - - /** Print to screen the target words, each line 10 words */ - public void showTargetWordSet(String TargetWordSet) { - ArrayList wordList = splitLineIntoWordList(TargetWordSet); - int i = 1; - for (String w : wordList) { - out.print(w + " "); - if (i % 10 == 0) { - out.print("\n"); - } - i++; + public void printLine(String... message) { + out.print(LINE_PREFIX); + for (String m: message) { + out.print(m + " "); } out.print("\n"); } - public ArrayList getDisplayWordLine(String TargetWordSet, int lineLength) { - ArrayList wordList = splitLineIntoWordList(TargetWordSet); - ArrayList wordLines = new ArrayList <>(); - int i = 1; - StringBuilder sb = new StringBuilder(); - for (String w : wordList) { - sb.append(w).append(" "); - if (i % lineLength == 0) { - wordLines.add(sb.toString().trim()); - sb = new StringBuilder(); - } - i++; - } - return wordLines; + public void showSummary(int errorWordCount, double WPM, int totalWordTyped, int gameTime) { + out.println("Number of wrong words typed" + errorWordCount); + out.println("WPM: " + WPM); + out.println("Total Time taken for the game: " + gameTime); + out.println("Total words typed: " + totalWordTyped); } } From 05d97d55eda80298c1ffdf721bd9832021e12742 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 14:50:37 +0800 Subject: [PATCH 050/272] Format display --- src/main/java/seedu/typists/Main.java | 2 +- .../seedu/typists/game/DataProcessor.java | 6 ++--- .../java/seedu/typists/game/TimeModeGame.java | 27 ++++++++++++------- src/main/java/seedu/typists/ui/TextUi.java | 9 +++---- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index d559b20123..d2c1edcefb 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -33,7 +33,7 @@ public void exit() { public void start() { uiBot.showWelcomeMessage(VERSION); - TimeModeGame g = new TimeModeGame(SAMPLE_TEXT, GAME_TIME, LINE_LENGTH); + TimeModeGame g = new TimeModeGame(SAMPLE_TEXT, LINE_LENGTH); DataProcessor p = new DataProcessor(g); uiBot.showSummary(p.getErrorWordCount(), p.getWPM(), p.getTotalWordTyped(), p.totalTime); } diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 785ae973f9..fa5d1ca7a8 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -8,13 +8,13 @@ public class DataProcessor { private final ArrayList checkerWordLines; private final ArrayList userWordLines; - public final int totalTime; + public final double totalTime; public DataProcessor(TimeModeGame tg) { //ArrayList checkerWordLines, ArrayList userText, int lineLength, int totalTime){ this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); - this.totalTime = tg.gameTime; + this.totalTime = tg.realGameTime; } public int getErrorWordCount() { @@ -39,7 +39,7 @@ public int getTotalWordTyped() { } public double getWPM() { - return getTotalWordTyped()/ ((double)totalTime/60); + return getTotalWordTyped() / (totalTime / 60); } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 1f49cefe2a..90b96dedc3 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -10,30 +10,41 @@ public class TimeModeGame extends Game { private final TextUi ui; protected final ArrayList wordLines; - protected final int gameTime; protected ArrayList inputLines; + protected int gameTime; protected int displayTime; + protected double realGameTime; - public TimeModeGame(String targetWordSet, int gameTime, int wordsPerLine) { - this.gameTime = gameTime; + public TimeModeGame(String targetWordSet, int wordsPerLine) { ui = new TextUi(); inputLines = new ArrayList <>(); wordLines = getWordLine(targetWordSet, wordsPerLine); + this.gameTime = getGameTime(); startGame(); } - public boolean readyToStartTimer () { + public boolean readyToStartTimer() { Scanner in = new Scanner(System.in); String command = ""; while(!command.equals("yes")) { System.out.println("Do you want to start now?"); command = in.nextLine(); - } return true; } + public int getGameTime() { + Scanner in = new Scanner(System.in); + System.out.println("Enter how long (in seconds) you want the game to run: "); + try { + return Integer.parseInt(in.nextLine()); + } catch (NumberFormatException e) { + System.out.println("Not a Number!"); + return getGameTime(); + } + } + public void startGame() { Scanner in = new Scanner(System.in); @@ -41,13 +52,12 @@ public void startGame() { int i = 0; long beginTime = System.currentTimeMillis(); boolean timeOver = false; - long realGameTime = 0; while (!timeOver) { long currTime = System.currentTimeMillis() - beginTime; if (currTime >= gameTime * 1000L) { timeOver = true; - realGameTime = currTime; + realGameTime = (double) currTime / 1000; } else { ui.printLine(wordLines.get(i)); String userInput = in.nextLine(); @@ -55,8 +65,7 @@ public void startGame() { i++; } } - displayTime = (int) realGameTime / 1000; - System.out.println("Game Finished. Total time taken: " + displayTime + "seconds. "); + System.out.println("Game Finished."); } } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 3acf5b317e..f72999aaf9 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -54,10 +54,9 @@ public void printLine(String... message) { out.print("\n"); } - public void showSummary(int errorWordCount, double WPM, int totalWordTyped, int gameTime) { - out.println("Number of wrong words typed" + errorWordCount); - out.println("WPM: " + WPM); - out.println("Total Time taken for the game: " + gameTime); - out.println("Total words typed: " + totalWordTyped); + public void showSummary(int errorWordCount, double WPM, int totalWordTyped, double gameTime) { + out.println("Wrong words: " + errorWordCount + "/" + totalWordTyped); + out.println("WPM: " + String. format("%.2f", WPM)); + out.println("Total Time taken for the game: " + String. format("%.2f", gameTime) + " seconds"); } } From 6197445ef27cea1319023f20fa5b4fcf19a07680 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 14:55:32 +0800 Subject: [PATCH 051/272] Better ui --- src/main/java/seedu/typists/game/TimeModeGame.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 90b96dedc3..9933353a65 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -28,7 +28,7 @@ public boolean readyToStartTimer() { Scanner in = new Scanner(System.in); String command = ""; while(!command.equals("yes")) { - System.out.println("Do you want to start now?"); + ui.printScreen("Do you want to start now?"); command = in.nextLine(); } return true; @@ -36,7 +36,7 @@ public boolean readyToStartTimer() { public int getGameTime() { Scanner in = new Scanner(System.in); - System.out.println("Enter how long (in seconds) you want the game to run: "); + ui.printScreen("Enter how long (in seconds) you want the game to run: "); try { return Integer.parseInt(in.nextLine()); } catch (NumberFormatException e) { From 7d7d5e5fb3745b789ffcff14b5106f142224cd71 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 15:09:44 +0800 Subject: [PATCH 052/272] Create manual --- src/main/java/seedu/typists/Main.java | 6 +----- .../java/seedu/typists/common/Messages.java | 4 ++++ src/main/java/seedu/typists/ui/TextUi.java | 19 +++++++++---------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index a3745e5362..f9d7146ae3 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -7,7 +7,6 @@ import seedu.typists.storage.StorageFile; import seedu.typists.ui.TextUi; -import java.io.IOException; import java.util.NoSuchElementException; @@ -57,9 +56,7 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText("OOPS!!! Input after done/delete must be a number."); } catch (FaultyInputException e) { uiBot.showText(e.getMessage()); - } catch (InvalidStringInputException e) { - e.printStackTrace(); - } catch (NoSuchElementException e) { + } catch (InvalidStringInputException | NoSuchElementException e) { e.printStackTrace(); } finally { uiBot.showLine(); @@ -69,7 +66,6 @@ public void runCommandLoopUntilExitCommand() { public void exit() { uiBot.showBye(); - return; } /** Runs the program until termination. */ diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 932872e655..0de2500b22 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -13,6 +13,10 @@ public class Messages { + " /____/_/"; public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; + public static final String MESSAGE_HELP = "Manual: \n" + + "new: start a new word game\n" + + "timer game: start a new timer game\n" + + "bye: exit typist"; //public static final String MESSAGE_GOODBYE = "Good bye!"; //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index f4dea2d80c..c5af2d073f 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -7,9 +7,7 @@ import static java.lang.System.lineSeparator; import static java.lang.System.out; -import static seedu.typists.common.Messages.LOGO; -import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; -import static seedu.typists.common.Messages.MESSAGE_WELCOME; +import static seedu.typists.common.Messages.*; /** * Text UI of the application. @@ -37,6 +35,7 @@ public void showWelcomeMessage(String version) { LOGO, MESSAGE_WELCOME, MESSAGE_ACKNOWLEDGE, + MESSAGE_HELP, DIVIDER ); } @@ -47,12 +46,12 @@ public void printScreen(String... message) { } } - public static String readCommand() { + public String readCommand() { Scanner sc = new Scanner(System.in); return sc.nextLine(); } - public static void showLine() { + public void showLine() { System.out.println(DIVIDER); } @@ -60,23 +59,23 @@ public static void showLine() { * Print error message. * @param meg obtained from DukeException message */ - public static void showText(String meg) { + public void showText(String meg) { System.out.println(meg); } - public static void showNumber(int i) { + public void showNumber(int i) { System.out.println(String.valueOf(i)); } - public static void showBye() { + public void showBye() { System.out.println("Bye. Hope to see you again soon!"); } - public static void printGameMode1Progress(int a, int b) { + public void printGameMode1Progress(int a, int b) { System.out.println("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } - public static void printSuccess() { + public void printSuccess() { System.out.println("Finished!"); } From 5d7cee1d2abec2c0a0136a149dc025977a99b482 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 15:44:36 +0800 Subject: [PATCH 053/272] add parser --- src/main/java/seedu/typists/commands/NewGame.java | 2 +- .../java/seedu/typists/game/DataProcessor.java | 8 ++++++-- src/main/java/seedu/typists/parser/Parser.java | 14 ++++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java index 308dd1485f..b25e11ce01 100644 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -13,7 +13,7 @@ public class NewGame { private ArrayList game1; - private static int game_index; + private int game_index; TextUi uiGame; public NewGame() { diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index fa5d1ca7a8..761a9dd259 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -23,8 +23,12 @@ public int getErrorWordCount() { for (String[] sa : userWordLines) { String[] checker = checkerWordLines.get(i); int ii = 0; - for (String s : sa) { - if (!s.equals(checker[ii])) { + for (String s : checker) { + try { + if (!s.equals(sa[ii])) { + errorWordCount++; + } + } catch (ArrayIndexOutOfBoundsException e) { errorWordCount++; } ii++; diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index f7e2cdb62a..07f873d30b 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -33,11 +33,17 @@ public Boolean getIsExit() { public void parse() throws FaultyInputException { - if (input.equals("bye")) { + switch (input) { + case "bye": isExit = true; - command = "bye"; - } else if (input.equals("new")) { - command = "new"; + command = "bye"; + break; + case "new": + command = "new"; + break; + case "time": + command = "time"; + break; } } From 1591905bc8efddd223ca283c5df82fe5af7cf5cd Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 15:49:37 +0800 Subject: [PATCH 054/272] update test result --- src/main/java/seedu/typists/common/Messages.java | 10 +++++----- text-ui-test/EXPECTED.TXT | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 89090f474c..8a072f76d3 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -5,16 +5,16 @@ */ public class Messages { public static final String LOGO = - " ______ _ __ \n" + " ______ _ __\n" + " /_ __/_ ______ (_)____/ /_\n" + " / / / / / / __ \\/ / ___/ __/\n" - + " / / / /_/ / /_/ / (__ ) /_ \n" - + "/_/ \\__, / .___/_/____/\\__/ \n" - + " /____/_/ "; + + " / / / /_/ / /_/ / (__ ) /_\n" + + "/_/ \\__, / .___/_/____/\\__/\n" + + " /____/_/"; public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; - public static final String MESSAGE_HELP = "Manual: \n" + + public static final String MESSAGE_HELP = "Manual:\n" + "new: start a new word game\n" + "time: start a new timer game\n" + "bye: exit typist"; diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 13a9b0146e..4093c8021a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -8,7 +8,10 @@ | /____/_/ | Welcome to Typist -- the ultimate cli typing game. | Brought to you by -- AY2122S1-CS2113-T13-4. + | Manual: + | new: start a new word game + | time: start a new timer game + | bye: exit typist | **************************************************************** **************************************************************** -**************************************************************** Bye. Hope to see you again soon! From 3509de13b9356ba0eaee8450eba4a857eaa46fb7 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 15 Oct 2021 16:22:34 +0800 Subject: [PATCH 055/272] Code quality modification --- src/main/java/seedu/typists/Main.java | 2 +- .../java/seedu/typists/commands/NewGame.java | 14 ++++---- .../java/seedu/typists/common/Messages.java | 34 +++++++++---------- src/main/java/seedu/typists/common/Utils.java | 6 ++-- .../seedu/typists/game/DataProcessor.java | 5 ++- .../java/seedu/typists/game/TimeModeGame.java | 4 +-- .../java/seedu/typists/parser/Parser.java | 3 ++ src/main/java/seedu/typists/ui/TextUi.java | 10 +++--- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 6cc6982145..f1fe562b0e 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -46,7 +46,7 @@ public void startWordLimitGame() { public void startTimeLimitGame() { TimeModeGame g = new TimeModeGame(SAMPLE_TEXT, LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showSummary(p.getErrorWordCount(), p.getWPM(), p.getTotalWordTyped(), p.totalTime); + uiBot.showSummary(p.getErrorWordCount(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); } diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java index b25e11ce01..f352cdb71d 100644 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -13,12 +13,12 @@ public class NewGame { private ArrayList game1; - private int game_index; + private int gameIndex; TextUi uiGame; public NewGame() { this.game1 = new ArrayList<>(100); - this.game_index = 0; + this.gameIndex = 0; this.uiGame = new TextUi(); } @@ -32,13 +32,13 @@ public void beginNewGame() throws InvalidStringInputException { uiGame.showText(content1); boolean isExit = false; while (!isExit) { - uiGame.showText(game1.get(game_index)); + uiGame.showText(game1.get(gameIndex)); String fullCommand = uiGame.readCommand(); - TextParser c = new TextParser(fullCommand, game1.get(game_index)); + TextParser c = new TextParser(fullCommand, game1.get(gameIndex)); isExit = c.getIsExit(); - game_index += 1; - uiGame.printGameMode1Progress(game_index,getTotalSentence()); - if (game_index == getTotalSentence()) { + gameIndex += 1; + uiGame.printGameMode1Progress(gameIndex,getTotalSentence()); + if (gameIndex == getTotalSentence()) { uiGame.printSuccess(); break; } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 8a072f76d3..6747ccff20 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -14,25 +14,25 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; - public static final String MESSAGE_HELP = "Manual:\n" + - "new: start a new word game\n" + - "time: start a new timer game\n" + - "bye: exit typist"; + public static final String MESSAGE_HELP = "Manual:\n" + + "new: start a new word game\n" + + "time: start a new timer game\n" + + "bye: exit typist"; //This sample text is gotten from https://www.lipsum.com/ - public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting industry" + - "imply dummy text of the printing and typesetting industry ipum is simply dummy" + - "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy" + - "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry" + - "industry industry industry industry industry industry industry industry industry industry industry"; + public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " + + "imply dummy text of the printing and typesetting industry ipum is simply dummy" + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry "; //public static final String MESSAGE_GOODBYE = "Goodbye!"; //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index b09111f0fd..0253f6d2ee 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -8,15 +8,15 @@ */ public class Utils { - /** convert the line of text into an arraylist of word */ + /** convert the line of text into an arraylist of word. */ public static ArrayList splitStringIntoWordList(String line) { return new ArrayList<>(Arrays.asList(line.split(" "))); } - /** group the word list into groups of x, where x is the number of words per line */ + /** group the word list into groups of x, where x is the number of words per line. */ public static ArrayList getWordLine(String text, int lineLength) { ArrayList wordList = splitStringIntoWordList(text); - ArrayList wordLines = new ArrayList <>(); + ArrayList wordLines = new ArrayList<>(); int j = 0; String[] line = new String[lineLength]; for (String w : wordList) { diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 761a9dd259..6cb2a60e85 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -11,7 +11,6 @@ public class DataProcessor { public final double totalTime; public DataProcessor(TimeModeGame tg) { - //ArrayList checkerWordLines, ArrayList userText, int lineLength, int totalTime){ this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); this.totalTime = tg.realGameTime; @@ -42,12 +41,12 @@ public int getTotalWordTyped() { return userWordLines.size() * LINE_LENGTH; } - public double getWPM() { + public double getWordPerMinute() { return getTotalWordTyped() / (totalTime / 60); } - public void getWrongKeyStrokes(ArrayList checkerText, ArrayList userText){ + public void getWrongKeyStrokes(ArrayList checkerText, ArrayList userText) { int totalErrorCount = 0; for (int i = 0; i < userText.size(); i++) { totalErrorCount += getLineWrongKeyStrokes(checkerText.get(i), userText.get(i)); diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 9933353a65..4e0e4f9f7f 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -18,7 +18,7 @@ public class TimeModeGame extends Game { public TimeModeGame(String targetWordSet, int wordsPerLine) { ui = new TextUi(); - inputLines = new ArrayList <>(); + inputLines = new ArrayList<>(); wordLines = getWordLine(targetWordSet, wordsPerLine); this.gameTime = getGameTime(); startGame(); @@ -27,7 +27,7 @@ public TimeModeGame(String targetWordSet, int wordsPerLine) { public boolean readyToStartTimer() { Scanner in = new Scanner(System.in); String command = ""; - while(!command.equals("yes")) { + while (!command.equals("yes")) { ui.printScreen("Do you want to start now?"); command = in.nextLine(); } diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index 07f873d30b..d87204f7f5 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -44,6 +44,9 @@ public void parse() throws FaultyInputException { case "time": command = "time"; break; + default: + System.out.println("invalid command."); + break; } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 814520ca9e..4ef2a178bc 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -6,15 +6,13 @@ import static java.lang.System.lineSeparator; import static java.lang.System.out; import static seedu.typists.common.Messages.LOGO; -import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; import static seedu.typists.common.Messages.MESSAGE_WELCOME; - +import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; +import static seedu.typists.common.Messages.MESSAGE_HELP; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Scanner; -import static seedu.typists.common.Messages.*; - /** * Text UI of the application. */ @@ -94,9 +92,9 @@ public void printSuccess() { System.out.println("Finished!"); } - public void showSummary(int errorWordCount, double WPM, int totalWordTyped, double gameTime) { + public void showSummary(int errorWordCount, double wpm, int totalWordTyped, double gameTime) { out.println("Wrong words: " + errorWordCount + "/" + totalWordTyped); - out.println("WPM: " + String. format("%.2f", WPM)); + out.println("WPM: " + String. format("%.2f", wpm)); out.println("Total Time taken for the game: " + String. format("%.2f", gameTime) + " seconds"); } } From 0b4e36deb527c4301eb50e71efbb7b8406fc1b1f Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Fri, 15 Oct 2021 22:50:34 +0800 Subject: [PATCH 056/272] wiki --- .../seedu/typists/content/WikiImport.java | 17 +++++++++++ src/test/java/seedu/WikiImportTest.java | 29 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/seedu/typists/content/WikiImport.java create mode 100644 src/test/java/seedu/WikiImportTest.java diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java new file mode 100644 index 0000000000..1c464c7fb0 --- /dev/null +++ b/src/main/java/seedu/typists/content/WikiImport.java @@ -0,0 +1,17 @@ +package seedu.typists.content; + +import org.fastily.jwiki.core.Wiki; +import seedu.typists.exception.InvalidArticleException; + +/** + * Imports the first paragraph of a text from Wikipedia. + */ +public class WikiImport { + public String getArticle(String article) throws InvalidArticleException { + Wiki wiki = new Wiki.Builder().build(); + if (!wiki.exists(article)) { + throw new InvalidArticleException(); + } + return wiki.getTextExtract(article); + } +} diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java new file mode 100644 index 0000000000..c970cb6271 --- /dev/null +++ b/src/test/java/seedu/WikiImportTest.java @@ -0,0 +1,29 @@ +package seedu; + +import org.junit.jupiter.api.Test; +import seedu.typists.content.WikiImport; +import seedu.typists.exception.InvalidArticleException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class WikiImportTest { + + // methodBeingTested_inputGiven_expectedOutcome + // Input, GitHub, relevant article (731 characters) + @Test + void getArticle_GitHub_expectArticle() throws InvalidArticleException { + String article = "GitHub"; + WikiImport wiki = new WikiImport(); + String content = wiki.getArticle(article); + assertEquals(731, content.length()); + } + + // test failure case + // method being tested, Githob, expect exception + @Test + void getArticle_Githob_expectException() { + String article = "Githob"; + WikiImport wiki = new WikiImport(); + assertThrows(InvalidArticleException.class, () -> wiki.getArticle(article)); + } +} \ No newline at end of file From d535560b5a76b3b527eec92ee81ec62dcb2c74c9 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:00:29 +0800 Subject: [PATCH 057/272] Content selection, basic error game (not finished) --- build.gradle | 1 + src/main/java/seedu/typists/Main.java | 18 +- .../java/seedu/typists/commands/NewGame.java | 1 - src/main/java/seedu/typists/common/Error.java | 37 +- .../java/seedu/typists/common/Messages.java | 2 + .../java/seedu/typists/content/Books.java | 503 +++++++++--------- .../java/seedu/typists/content/Content.java | 131 ++++- .../typists/content/RandomGenerator.java | 6 +- .../seedu/typists/content/WikiImport.java | 6 +- .../exception/InvalidArticleException.java | 2 +- .../java/seedu/typists/game/ErrorGame.java | 46 ++ .../java/seedu/typists/parser/Parser.java | 8 +- src/main/java/seedu/typists/ui/TextUi.java | 27 +- 13 files changed, 497 insertions(+), 291 deletions(-) create mode 100644 src/main/java/seedu/typists/game/ErrorGame.java diff --git a/build.gradle b/build.gradle index f9118b05a8..65db32f9ef 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ repositories { } dependencies { + implementation 'org.fastily:jwiki:1.8.0' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' } diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index f1fe562b0e..fc3ff337ca 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,17 +1,17 @@ package seedu.typists; +import seedu.typists.content.Content; +import seedu.typists.game.ErrorGame; import seedu.typists.game.DataProcessor; import seedu.typists.game.TimeModeGame; import seedu.typists.parser.Parser; import seedu.typists.ui.TextUi; -import static seedu.typists.common.Messages.SAMPLE_TEXT; - import seedu.typists.commands.NewGame; import seedu.typists.exception.FaultyInputException; import seedu.typists.exception.InvalidStringInputException; -import seedu.typists.parser.Parser; import seedu.typists.storage.StorageFile; + import java.util.NoSuchElementException; @@ -24,10 +24,12 @@ public class Main { //Parser parseBot; NewGame wordLimitGame; StorageFile storage; + Content content; public Main() { this.uiBot = new TextUi(); this.storage = new StorageFile(); + this.content = new Content(); } public void start() { @@ -44,20 +46,28 @@ public void startWordLimitGame() { } public void startTimeLimitGame() { - TimeModeGame g = new TimeModeGame(SAMPLE_TEXT, LINE_LENGTH); + TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); uiBot.showSummary(p.getErrorWordCount(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); } + public void startErrorGame() { + ErrorGame a = new ErrorGame(content.getContent(), LINE_LENGTH); + } public void executeCommand(Parser c, NewGame game, StorageFile storage) { switch (c.getCommand()) { + case "content": + content.setContent(); + break; case "new": startWordLimitGame(); break; case "time": startTimeLimitGame(); break; + case "error": + startErrorGame(); default: break; } diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java index f352cdb71d..50500dad3c 100644 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ b/src/main/java/seedu/typists/commands/NewGame.java @@ -44,5 +44,4 @@ public void beginNewGame() throws InvalidStringInputException { } } } - } diff --git a/src/main/java/seedu/typists/common/Error.java b/src/main/java/seedu/typists/common/Error.java index 3fe25b2299..ae6d6aca6f 100644 --- a/src/main/java/seedu/typists/common/Error.java +++ b/src/main/java/seedu/typists/common/Error.java @@ -1,24 +1,45 @@ package seedu.typists.common; +import static java.lang.Math.abs; import static java.lang.Math.min; /** * Error rate calculator. */ public class Error { - public int lengthDifference(String content, String typed) { - return Math.abs(content.length() - typed.length()); + public int wordLengthDifference(String word, String typed) { + return Math.abs(word.length() - typed.length()); } - public int characterDifference(String content, String typed) { + public int wordCharacterDifference(String word, String typed) { int charDiff = 0; - for (int i = 0; i < min(content.length(), typed.length()); i++) { - charDiff += (content.charAt(i) != typed.charAt(i) ? 1 : 0); + for (int i = 0; i < min(word.length(), typed.length()); i++) { + charDiff += (word.charAt(i) != typed.charAt(i) ? 1 : 0); } - return charDiff + lengthDifference(content, typed); + return charDiff + wordLengthDifference(word, typed); } - public double errorRate(String content, String typed) { - return (double) characterDifference(content, typed) / content.length(); + public double wordErrorRate(String word, String typed) { + return (double) wordCharacterDifference(word, typed) / word.length(); + } + + public int sentenceLengthDifference(String[] content, String[] typed) { + return abs(content.length - typed.length); + } + + public double sentenceErrorRate(String[] content, String[] typed) { + double temp = 0.0; + for (int i = 0; i < min(content.length, typed.length); i++) { + temp += wordErrorRate(content[i], typed[i]); + } + return temp / (double) min(content.length, typed.length); + } + + public int wrongWordCount(String[] content, String[] typed) { + int temp = 0; + for (int i = 0; i < min(content.length, typed.length); i++) { + temp += (content[0].equals(content[1]) ? 1 : 0); + } + return temp; } } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 6747ccff20..fa012568a1 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -15,8 +15,10 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" + + "content: set the content\n" + "new: start a new word game\n" + "time: start a new timer game\n" + + "error: start a new error game\n" + "bye: exit typist"; //This sample text is gotten from https://www.lipsum.com/ diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java index 409960c46e..b8e20938b6 100644 --- a/src/main/java/seedu/typists/content/Books.java +++ b/src/main/java/seedu/typists/content/Books.java @@ -1,260 +1,251 @@ package seedu.typists.content; public class Books { - String aconfederacyofdunces = "A green hunting " - + "cap squeezed the top of the fleshy " - + "balloon of a head. The green earflaps, " - + "full of large ears and uncut hair and the fine " - + "bristles that grew in the ears themselves, " - + "stuck out on either side like turn signals " - + "indicating two directions at once. " - + "Full, pursed lips protruded beneath the bushy black " - + "moustache and, at their corners, sank into little folds " - + "filled with disapproval and potato chip crumbs. " - + "In the shadow under the green visor of the cap Ignatius J. " - + "Reilly’s supercilious blue and yellow eyes looked down " - + "upon the other people waiting under the clock at the D.H. " - + "Holmes department store, studying the crowd of " - + "people for signs of bad taste in dress. " - + "Several of the outfits, Ignatius noticed, " - + "were new enough and expensive enough to be properly " - + "considered offenses against taste and decency. " - + "Possession of anything new or expensive only reflected a " - + "person’s lack of theology and geometry;" - + "it could even cast doubts upon one’s soul. "; - - String mobydick = "Call me Ishmael. " - + "Some years ago — never mind how long precisely — " - + "having little or no money in my purse, " - + "and nothing particular to interest me on shore, " - + "I thought I would sail about " - + "a little and see the watery part of the world. It is a way " - + "I have of driving off the spleen, " - + "and regulating the circulation. " - + "Whenever I find myself growing grim about the mouth; " - + "whenever it is a damp, drizzly November in my soul; " - + "whenever I find myself involuntarily pausing before coffin " - + "warehouses, and bringing up the rear of every funeral I meet; " - + "and especially whenever my hypos get such an upper hand of me, " - + "that it requires a strong moral principle to prevent me from " - + "deliberately stepping into the street, " - + "and methodically knocking people’s hats off — then, " - + "I account it high time to get to sea as soon as I can. " - + "This is my substitute for pistol and ball. " - + "With a philosophical flourish Cato throws himself " - + "upon his sword; I quietly take to the ship. " - + "There is nothing surprising in this. If they but knew it, " - + "almost all men in their degree, some time or other, " - + "cherish very nearly the same " - + "feelings towards the ocean with me."; - - String afarewelltoarms = "In the late summer of that year we lived in " - + "a house in a village that looked across the river " - + "and the plain to the mountains. " - + "In the bed of the river there were pebbles and boulders, " - + "dry and white in the sun, and the water was clear and swiftly " - + "moving and blue in the channels. " - + "Troops went by the house and down the road and " - + "the dust they raised powdered the leaves of the trees. " - + "The trunks of the trees too were dusty and the leaves fell " - + "early that year and we saw the troops marching along the " - + "road and the dust rising and leaves, stirred by the breeze, " - + "falling and the soldiers marching and " - + "afterward the road bare and white except for the leaves."; - - String ataleoftwocities = "It was the best of times, " - + "it was the worst of times, " - + "it was the age of wisdom, it was the age of foolishness, " - + "it was the epoch of belief, it was the epoch of incredulity, " - + "it was the season of Light, it was the season of Darkness, " - + "it was the spring of hope, it was the winter of despair, " - + "we had everything before us, we had nothing before us, " - + "we were all going direct to Heaven, " - + "we were all going direct the other way — " - + "in short, the period was so far like the present period, " - + "that some of its noisiest authorities insisted on its being " - + "received, for good or for evil, " - + "in the superlative degree of comparison only. "; - - String ontheroad = "I first met Dean not long " - + "after my wife and I split up. " - + "I had just gotten over a serious illness that " - + "I won’t bother to talk about, except that " - + "it had something to do with the miserably weary " - + "split-up and my feeling that everything was dead. " - + "With the coming of Dean Moriarty began the part " - + "of my life you could call my life on the road. " - + "Before that I’d often dreamed of going West to see the " - + "country, always vaguely planning and never taking off. " - + "Dean is the perfect guy for the road because he " - + "actually was born on the road, " - + "when his parents were passing through Salt Lake City in 1926, " - + "in a jalopy, on their way to Los Angeles. " - + "First reports of him came to me through Chad King, " - + "who’d shown me a few letters from him written in a " - + "New Mexico reform school. I was tremendously interested " - + "in the letters because they so naively and sweetly asked " - + "Chad to teach him all about Nietzsche and all the wonderful " - + "intellectual things that Chad knew. At one point Carlo and " - + "I talked about the letters and wondered if we would ever meet " - + "the strange Dean Moriarty. This is all far back, " - + "when Dean was not the way he is today, when he was a " - + "young jailkid shrouded in mystery. Then news came that Dean " - + "was out of reform school and was coming to New York for the " - + "first time; also there was talk that he had just " - + "married a girl called Marylou. "; - - String brightonrock = "Hale knew, before he had been in Brighton " - + "three hours, that they meant to murder him. " - + "With his inky fingers and his bitten nails, " - + "his manner cynical and nervous, " - + "anybody could tell he didn’t belong – " - + "belong to the early summer sun, the cool " - + "Whitsun wind off the sea, the holiday crowd. " - + "They came in by train from Victoria every five minutes, " - + "rocked down Queen’s Road standing on the " - + "tops of the little local trams, stepped off " - + "in bewildered multitudes into fresh and " - + "glittering air: the new silver paint sparkled on the piers, " - + "the cream houses ran away into the west like a " - + "pale Victorian water-colour; a race in miniature motors, " - + "a band playing, flower gardens in bloom below the " - + "front, an aeroplane advertising something for " - + "the health in pale vanishing clouds across the sky."; - - String pickup = "It must have been around a quarter to eleven. " - + "A sailor came in and ordered a chile dog and coffee. " - + "I sliced a bun, jerked a frank out of the boiling water, " - + "nested it, poured a half-dipper of chile over the frank " - + "and sprinkled it liberally with chopped onions. " - + "I scribbled a check and put it by his plate. " - + "I wouldn’t have recommended the unpalatable mess " - + "to a starving animal. The sailor was the only customer, " - + "and after he ate his dog he left. " - + "That was the exact moment she entered. " - + "A small woman, hardly more than five feet. " - + "She had the figure of a teenage girl. " - + "Her suit was a blue tweed, smartly cut, " - + "and over her thin shoulders she wore a fur jacket, " - + "bolero length. Tiny gold circular earrings " - + "clung to her small pierced ears. " - + "Her hands and feet were small, " - + "and when she seated herself at " - + "the counter I noticed she wasn’t wearing any rings."; - - String prideandprejudice = "It is a truth universally acknowledged, " - + "that a single man in possession of a good fortune must be in " - + "want of a wife. However little known the feelings or " - + "views of such a man may be on his first entering a " - + "neighbourhood, this truth is so well fixed in the minds of the " - + "surrounding families, that he is considered as the rightful " - + "property of some one or other of their daughters."; - - String whitefang = "Dark spruce forest frowned on either side of the " - + "frozen waterway. The trees had been stripped by a " - + "recent wind of their white covering of frost, " - + "and they seemed to lean toward each other, " - + "black and ominous, in the fading light. " - + "A vast silence reigned over the land. " - + "The land itself was a desolation, lifeless, " - + "without movement, so lone and cold that the spirit of " - + "it was not even that of sadness. " - + "There was a hint in it of laughter, " - + "but of a laughter more terrible than any sadness — " - + "a laughter that was mirthless as the smile of the Sphinx, " - + "a laughter cold as the frost and partaking of the " - + "grimness of infallibility. " - + "It was the masterful and incommunicable " - + "wisdom of eternity laughing at the futility " - + "of life and the effort of life. " - + "It was the Wild, the savage, frozen-hearted Northland Wild."; - - String americanpsycho = "ABANDON ALL HOPE YE WHO ENTER HERE is " - + "scrawled in blood red lettering on " - + "the side of the Chemical Bank near the corner of " - + "Eleventh and First and is in print large enough to be seen " - + "from the backseat of the cab as it lurches forward in " - + "the traffic leaving Wall Street and just as Timothy " - + "Price notices the words a bus pulls up, " - + "the advertisement for Les Miserables on its side blocking " - + "his view, but Price who is with Pierce & Pierce " - + "and twenty-six doesn't seem to care because he " - + "tells the driver he will give him five dollars to turn " - + "up the radio, \"Be My Baby\" on WYNN, " - + "and the driver, black, not American, does so."; - - String notesfromunderground = "I am a sick man. ... " - + "I am a spiteful man. I am an unattractive man. " - + "I believe my liver is diseased. However, " - + "I know nothing at all about my disease, " - + "and do not know for certain what ails me. " - + "I don't consult a doctor for it, and never have, " - + "though I have a respect for medicine and doctors. " - + "Besides, I am extremely superstitious, " - + "sufficiently so to respect medicine, anyway " - + "(I am well-educated enough not to be superstitious, " - + "but I am superstitious). No, " - + "I refuse to consult a doctor from spite. " - + "That you probably will not understand. " - + "Well, I understand it, though. Of course, " - + "I can't explain who it is precisely that " - + "I am mortifying in this case by my spite: " - + "I am perfectly well aware that I cannot \"pay " - + "out\" the doctors by not consulting them; " - + "I know better than anyone that by all this " - + "I am only injuring myself and no one else. " - + "But still, if I don't consult a doctor it is from spite. " - + "My liver is bad, well then let it hurt even worse!"; - - String thehauntingofhillhouse = "No live organism can continue " - + "for long to exist sanely under conditions of absolute " - + "reality; even larks and katydids are supposed, by some, " - + "to dream. Hill House, not sane, stood by itself against " - + "its hills, holding darkness within; it had stood so for " - + "eighty years and might stand for eighty more. " - + "Within, walls continued upright, bricks met neatly, " - + "floors were firm, and doors were sensibly shut; " - + "silence lay steadily against the wood and " - + "stone of Hill House, and whatever walked there, walked alone…"; - - String metamorphosis = "As Gregor Samsa awoke one " - + "morning from uneasy dreams he found himself transformed " - + "in his bed into a gigantic insect. " - + "He was lying on his hard, as it were armor-plated, " - + "back and when he lifted his head a little he " - + "could see his dome-like brown belly divided into " - + "stiff arched segments on top of which the " - + "bed quilt could hardly keep in position and " - + "was about to slide off completely. " - + "His numerous legs, which were pitifully thin " - + "compared to the rest of his bulk, " - + "waved helplessly before his eyes."; - - String invisibleman = "I am an invisible man. " - + "No, I am not a spook like those who haunted Edgar Allan Poe; " - + "nor am I one of your Hollywood-movie ectoplasms. " - + "I am a man of substance, of flesh and bone, fiber " - + "and liquids—and I might even be said to possess a mind. " - + "I am invisible, understand, simply because people " - + "refuse to see me. Like the bodiless heads you see " - + "sometimes in circus sideshows, it is as though " - + "I have been surrounded by mirrors of hard, distorting glass. " - + "When they approach me they see only my surroundings, " - + "themselves, or figments of their imagination—" - + "indeed, everything and anything except me."; - - String theadventuresofhuckleberryfinn = "You don't know " - + "about me without you have read a book by the " - + "name of The Adventures of Tom Sawyer; " - + "but that ain't no matter. That book was made " - + "by Mr. Mark Twain, and he told the truth, mainly. " - + "There was things which he stretched, " - + "but mainly he told the truth. " - + "That is nothing. I never seen anybody " - + "but lied one time or another, without " - + "it was Aunt Polly, or the widow, or " - + "maybe Mary. Aunt Polly - Tom's Aunt Polly, " - + "she is - and Mary, and the Widow Douglas is " - + "all told about in that book, which is mostly a " - + "true book, with some stretchers, as I said before."; + private static String[] bookContent = { + "A green hunting " + + "cap squeezed the top of the fleshy " + + "balloon of a head. The green earflaps, " + + "full of large ears and uncut hair and the fine " + + "bristles that grew in the ears themselves, " + + "stuck out on either side like turn signals " + + "indicating two directions at once. " + + "Full, pursed lips protruded beneath the bushy black " + + "moustache and, at their corners, sank into little folds " + + "filled with disapproval and potato chip crumbs. " + + "In the shadow under the green visor of the cap Ignatius J. " + + "Reilly’s supercilious blue and yellow eyes looked down " + + "upon the other people waiting under the clock at the D.H. " + + "Holmes department store, studying the crowd of " + + "people for signs of bad taste in dress. " + + "Several of the outfits, Ignatius noticed, " + + "were new enough and expensive enough to be properly " + + "considered offenses against taste and decency. " + + "Possession of anything new or expensive only reflected a " + + "person’s lack of theology and geometry;" + + "it could even cast doubts upon one’s soul.", + "Call me Ishmael. " + + "Some years ago — never mind how long precisely — " + + "having little or no money in my purse, " + + "and nothing particular to interest me on shore, " + + "I thought I would sail about " + + "a little and see the watery part of the world. It is a way " + + "I have of driving off the spleen, " + + "and regulating the circulation. " + + "Whenever I find myself growing grim about the mouth; " + + "whenever it is a damp, drizzly November in my soul; " + + "whenever I find myself involuntarily pausing before coffin " + + "warehouses, and bringing up the rear of every funeral I meet; " + + "and especially whenever my hypos get such an upper hand of me, " + + "that it requires a strong moral principle to prevent me from " + + "deliberately stepping into the street, " + + "and methodically knocking people’s hats off — then, " + + "I account it high time to get to sea as soon as I can. " + + "This is my substitute for pistol and ball. " + + "With a philosophical flourish Cato throws himself " + + "upon his sword; I quietly take to the ship. " + + "There is nothing surprising in this. If they but knew it, " + + "almost all men in their degree, some time or other, " + + "cherish very nearly the same " + + "feelings towards the ocean with me.", + "In the late summer of that year we lived in " + + "a house in a village that looked across the river " + + "and the plain to the mountains. " + + "In the bed of the river there were pebbles and boulders, " + + "dry and white in the sun, and the water was clear and swiftly " + + "moving and blue in the channels. " + + "Troops went by the house and down the road and " + + "the dust they raised powdered the leaves of the trees. " + + "The trunks of the trees too were dusty and the leaves fell " + + "early that year and we saw the troops marching along the " + + "road and the dust rising and leaves, stirred by the breeze, " + + "falling and the soldiers marching and " + + "afterward the road bare and white except for the leaves.", + "It was the best of times, " + + "it was the worst of times, " + + "it was the age of wisdom, it was the age of foolishness, " + + "it was the epoch of belief, it was the epoch of incredulity, " + + "it was the season of Light, it was the season of Darkness, " + + "it was the spring of hope, it was the winter of despair, " + + "we had everything before us, we had nothing before us, " + + "we were all going direct to Heaven, " + + "we were all going direct the other way — " + + "in short, the period was so far like the present period, " + + "that some of its noisiest authorities insisted on its being " + + "received, for good or for evil, " + + "in the superlative degree of comparison only.", + "I first met Dean not long " + + "after my wife and I split up. " + + "I had just gotten over a serious illness that " + + "I won’t bother to talk about, except that " + + "it had something to do with the miserably weary " + + "split-up and my feeling that everything was dead. " + + "With the coming of Dean Moriarty began the part " + + "of my life you could call my life on the road. " + + "Before that I’d often dreamed of going West to see the " + + "country, always vaguely planning and never taking off. " + + "Dean is the perfect guy for the road because he " + + "actually was born on the road, " + + "when his parents were passing through Salt Lake City in 1926, " + + "in a jalopy, on their way to Los Angeles. " + + "First reports of him came to me through Chad King, " + + "who’d shown me a few letters from him written in a " + + "New Mexico reform school. I was tremendously interested " + + "in the letters because they so naively and sweetly asked " + + "Chad to teach him all about Nietzsche and all the wonderful " + + "intellectual things that Chad knew. At one point Carlo and " + + "I talked about the letters and wondered if we would ever meet " + + "the strange Dean Moriarty. This is all far back, " + + "when Dean was not the way he is today, when he was a " + + "young jailkid shrouded in mystery. Then news came that Dean " + + "was out of reform school and was coming to New York for the " + + "first time; also there was talk that he had just " + + "married a girl called Marylou.", + "Hale knew, before he had been in Brighton " + + "three hours, that they meant to murder him. " + + "With his inky fingers and his bitten nails, " + + "his manner cynical and nervous, " + + "anybody could tell he didn’t belong – " + + "belong to the early summer sun, the cool " + + "Whitsun wind off the sea, the holiday crowd. " + + "They came in by train from Victoria every five minutes, " + + "rocked down Queen’s Road standing on the " + + "tops of the little local trams, stepped off " + + "in bewildered multitudes into fresh and " + + "glittering air: the new silver paint sparkled on the piers, " + + "the cream houses ran away into the west like a " + + "pale Victorian water-colour; a race in miniature motors, " + + "a band playing, flower gardens in bloom below the " + + "front, an aeroplane advertising something for " + + "the health in pale vanishing clouds across the sky.", + "It must have been around a quarter to eleven. " + + "A sailor came in and ordered a chile dog and coffee. " + + "I sliced a bun, jerked a frank out of the boiling water, " + + "nested it, poured a half-dipper of chile over the frank " + + "and sprinkled it liberally with chopped onions. " + + "I scribbled a check and put it by his plate. " + + "I wouldn’t have recommended the unpalatable mess " + + "to a starving animal. The sailor was the only customer, " + + "and after he ate his dog he left. " + + "That was the exact moment she entered. " + + "A small woman, hardly more than five feet. " + + "She had the figure of a teenage girl. " + + "Her suit was a blue tweed, smartly cut, " + + "and over her thin shoulders she wore a fur jacket, " + + "bolero length. Tiny gold circular earrings " + + "clung to her small pierced ears. " + + "Her hands and feet were small, " + + "and when she seated herself at " + + "the counter I noticed she wasn’t wearing any rings.", + "It is a truth universally acknowledged, " + + "that a single man in possession of a good fortune must be in " + + "want of a wife. However little known the feelings or " + + "views of such a man may be on his first entering a " + + "neighbourhood, this truth is so well fixed in the minds of the " + + "surrounding families, that he is considered as the rightful " + + "property of some one or other of their daughters.", + "Dark spruce forest frowned on either side of the " + + "frozen waterway. The trees had been stripped by a " + + "recent wind of their white covering of frost, " + + "and they seemed to lean toward each other, " + + "black and ominous, in the fading light. " + + "A vast silence reigned over the land. " + + "The land itself was a desolation, lifeless, " + + "without movement, so lone and cold that the spirit of " + + "it was not even that of sadness. " + + "There was a hint in it of laughter, " + + "but of a laughter more terrible than any sadness — " + + "a laughter that was mirthless as the smile of the Sphinx, " + + "a laughter cold as the frost and partaking of the " + + "grimness of infallibility. " + + "It was the masterful and incommunicable " + + "wisdom of eternity laughing at the futility " + + "of life and the effort of life. " + + "It was the Wild, the savage, frozen-hearted Northland Wild.", + "ABANDON ALL HOPE YE WHO ENTER HERE is " + + "scrawled in blood red lettering on " + + "the side of the Chemical Bank near the corner of " + + "Eleventh and First and is in print large enough to be seen " + + "from the backseat of the cab as it lurches forward in " + + "the traffic leaving Wall Street and just as Timothy " + + "Price notices the words a bus pulls up, " + + "the advertisement for Les Miserables on its side blocking " + + "his view, but Price who is with Pierce & Pierce " + + "and twenty-six doesn't seem to care because he " + + "tells the driver he will give him five dollars to turn " + + "up the radio, \"Be My Baby\" on WYNN, " + + "and the driver, black, not American, does so.", + "I am a sick man. ... " + + "I am a spiteful man. I am an unattractive man. " + + "I believe my liver is diseased. However, " + + "I know nothing at all about my disease, " + + "and do not know for certain what ails me. " + + "I don't consult a doctor for it, and never have, " + + "though I have a respect for medicine and doctors. " + + "Besides, I am extremely superstitious, " + + "sufficiently so to respect medicine, anyway " + + "(I am well-educated enough not to be superstitious, " + + "but I am superstitious). No, " + + "I refuse to consult a doctor from spite. " + + "That you probably will not understand. " + + "Well, I understand it, though. Of course, " + + "I can't explain who it is precisely that " + + "I am mortifying in this case by my spite: " + + "I am perfectly well aware that I cannot \"pay " + + "out\" the doctors by not consulting them; " + + "I know better than anyone that by all this " + + "I am only injuring myself and no one else. " + + "But still, if I don't consult a doctor it is from spite. " + + "My liver is bad, well then let it hurt even worse!", + "No live organism can continue " + + "for long to exist sanely under conditions of absolute " + + "reality; even larks and katydids are supposed, by some, " + + "to dream. Hill House, not sane, stood by itself against " + + "its hills, holding darkness within; it had stood so for " + + "eighty years and might stand for eighty more. " + + "Within, walls continued upright, bricks met neatly, " + + "floors were firm, and doors were sensibly shut; " + + "silence lay steadily against the wood and " + + "stone of Hill House, and whatever walked there, walked alone…", + "As Gregor Samsa awoke one " + + "morning from uneasy dreams he found himself transformed " + + "in his bed into a gigantic insect. " + + "He was lying on his hard, as it were armor-plated, " + + "back and when he lifted his head a little he " + + "could see his dome-like brown belly divided into " + + "stiff arched segments on top of which the " + + "bed quilt could hardly keep in position and " + + "was about to slide off completely. " + + "His numerous legs, which were pitifully thin " + + "compared to the rest of his bulk, " + + "waved helplessly before his eyes.", + "I am an invisible man. " + + "No, I am not a spook like those who haunted Edgar Allan Poe; " + + "nor am I one of your Hollywood-movie ectoplasms. " + + "I am a man of substance, of flesh and bone, fiber " + + "and liquids—and I might even be said to possess a mind. " + + "I am invisible, understand, simply because people " + + "refuse to see me. Like the bodiless heads you see " + + "sometimes in circus sideshows, it is as though " + + "I have been surrounded by mirrors of hard, distorting glass. " + + "When they approach me they see only my surroundings, " + + "themselves, or figments of their imagination—" + + "indeed, everything and anything except me.", + "You don't know " + + "about me without you have read a book by the " + + "name of The Adventures of Tom Sawyer; " + + "but that ain't no matter. That book was made " + + "by Mr. Mark Twain, and he told the truth, mainly. " + + "There was things which he stretched, " + + "but mainly he told the truth. " + + "That is nothing. I never seen anybody " + + "but lied one time or another, without " + + "it was Aunt Polly, or the widow, or " + + "maybe Mary. Aunt Polly - Tom's Aunt Polly, " + + "she is - and Mary, and the Widow Douglas is " + + "all told about in that book, which is mostly a " + + "true book, with some stretchers, as I said before." + }; + public static String getBook(int index) { + return bookContent[index]; + } } diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 0532a137a4..1ac3e79bbd 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -1,23 +1,126 @@ package seedu.typists.content; -import java.util.ArrayList; +import seedu.typists.exception.FaultyInputException; +import seedu.typists.exception.InvalidArticleException; +import seedu.typists.ui.TextUi; + +import java.util.Random; +import java.util.Scanner; +import java.util.InputMismatchException; +import static seedu.typists.common.Messages.SAMPLE_TEXT; -/** - * Content object. - */ public class Content { - private ArrayList content; - - public void setContent(String content) { - this.content = new ArrayList<>(100); - String content1 = "The greatest glory in living lies not in never falling, but in rising every time we fall."; - String content2 = "The way to get started is to quit talking and begin doing."; - this.content.set(0,content1); - this.content.set(1,content2); + private String content = SAMPLE_TEXT; + private final TextUi ui; + + public Content() { + this.ui = new TextUi(); } + public String getContent() { + return content; + } + + public void setContent() { + ui.showText("Content selection (input 0 to go back):\n" + + "1. Opening of famous books\n" + + "2. Wikipedia article\n" + + "3. Random sentence of custom length" + ); + Scanner in = new Scanner(System.in); + int command = -1; + do { + ui.showText("Enter your selection: "); + try { + command = in.nextInt(); + } catch (InputMismatchException e) { + ui.showText("Invalid selection."); + in.nextLine(); + } + } while (command < 0 || command > 3); + switch (command) { + case 1: + setBooks(); + break; + case 2: + setWikipedia(); + break; + case 3: + setRandomContent(); + break; + default: + break; + } + } + + private void setBooks() { + Scanner in = new Scanner(System.in); + ui.printBookSelection(); + int selection = -1; + do { + ui.showText("Enter your selection:"); + try { + selection = in.nextInt(); + } catch (InputMismatchException e) { + ui.showText("Not an integer."); + in.nextLine(); + } + } while (selection < 0 || selection > 15); + if (selection == 0) { + setContent(); + } else { + this.content = Books.getBook(selection - 1); + ui.showText("Content set"); + } + } + + private void setWikipedia() { + Scanner in = new Scanner(System.in); + WikiImport wi = new WikiImport(); + String title; + boolean articleNotFound = true; + do { + ui.showText("Enter the article name (input 0 to go back):"); + title = in.nextLine(); + if (title.equals("0")) { + articleNotFound = false; + setContent(); + } else { + try { + String temp = wi.getArticle(title); + articleNotFound = false; + this.content = temp; + ui.showText("Content set"); + } catch (InvalidArticleException e) { + ui.showText(e.getMessage()); + } + } + } while (articleNotFound); + } - public String getContent(int index) { - return content.get(index); + private void setRandomContent() { + Scanner in = new Scanner(System.in); + RandomGenerator rg = new RandomGenerator(); + int length = -1; + do { + ui.showText("Enter the word count (between 1 - 100, input 0 to go back):"); + try { + length = in.nextInt(); + } catch (InputMismatchException e) { + ui.showText("Invalid selection."); + in.nextLine(); + } + } while (length < 0 || length > 100); + if (length == 0) { + setContent(); + } else { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < length; i++) { + Random r = new Random(); + s.append(rg.randomString(r.nextInt(10) + 5)).append(" "); + } + this.content = s.toString(); + ui.showText("Content set"); + } } } diff --git a/src/main/java/seedu/typists/content/RandomGenerator.java b/src/main/java/seedu/typists/content/RandomGenerator.java index 3010490a59..29cf49b823 100644 --- a/src/main/java/seedu/typists/content/RandomGenerator.java +++ b/src/main/java/seedu/typists/content/RandomGenerator.java @@ -11,13 +11,11 @@ public String randomString(int length) { Random rand = new Random(); StringBuilder s = new StringBuilder(); for (int i = 0; i < length; i++) { - int random = 0; if (isCaps.nextBoolean()) { - random = rand.nextInt(26) + 65; + s.append((char) (rand.nextInt(26) + 'A')); } else { - random = rand.nextInt(26) + 97; + s.append((char) (rand.nextInt(26) + 'a')); } - s.append((char) random); } return s.toString(); } diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java index 1c464c7fb0..e218b2aec0 100644 --- a/src/main/java/seedu/typists/content/WikiImport.java +++ b/src/main/java/seedu/typists/content/WikiImport.java @@ -12,6 +12,10 @@ public String getArticle(String article) throws InvalidArticleException { if (!wiki.exists(article)) { throw new InvalidArticleException(); } - return wiki.getTextExtract(article); + String temp = wiki.getTextExtract(article); + if (temp.length() < 1) { + throw new InvalidArticleException(); + } + return temp; } } diff --git a/src/main/java/seedu/typists/exception/InvalidArticleException.java b/src/main/java/seedu/typists/exception/InvalidArticleException.java index a6db81f253..29d729d850 100644 --- a/src/main/java/seedu/typists/exception/InvalidArticleException.java +++ b/src/main/java/seedu/typists/exception/InvalidArticleException.java @@ -3,6 +3,6 @@ public class InvalidArticleException extends Exception { @Override public String getMessage() { - return "Invalid article given" + super.getMessage(); + return "Invalid article given"; } } diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java new file mode 100644 index 0000000000..5da24716e3 --- /dev/null +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -0,0 +1,46 @@ +package seedu.typists.game; + +import seedu.typists.ui.TextUi; +import java.util.ArrayList; +import java.util.Scanner; + +import static seedu.typists.common.Utils.getWordLine; + +public class ErrorGame extends Game { + private final TextUi ui; + + protected ArrayList inputLines; + protected final ArrayList wordLines; + + public ErrorGame(String targetWordSet, int wordsPerLine) { + ui = new TextUi(); + inputLines = new ArrayList<>(); + wordLines = getWordLine(targetWordSet, wordsPerLine); + startGame(); + } + + public boolean readyToStartGame() { + Scanner in = new Scanner(System.in); + String command = ""; + while (!command.equals("yes")) { + ui.printScreen("Do you want to start now?"); + command = in.nextLine(); + } + return true; + } + + public void startGame() { + if (readyToStartGame()) { + for (int i = 0; i < wordLines.size(); i++) { + ui.printLine(wordLines.get(i)); + } + } + Scanner in = new Scanner(System.in); + for (int i = 0; i < wordLines.size(); i++) { + String userInput = in.nextLine(); + inputLines.add(userInput); + i++; + } + System.out.println("Game Finished."); + } +} diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index d87204f7f5..970d9b362f 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -44,7 +44,13 @@ public void parse() throws FaultyInputException { case "time": command = "time"; break; - default: + case "error": + command = "error"; + break; + case "content": + command = "content"; + break; + default: System.out.println("invalid command."); break; } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 4ef2a178bc..d2f914a801 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -92,9 +92,34 @@ public void printSuccess() { System.out.println("Finished!"); } + public void printBookSelection() { + System.out.println("Input '0' to go back.\n" + + "Content list:\n" + + "1. A Confederacy of Dunces\n" + + "2. Moby Dick\n" + + "3. A Farewell to Arms\n" + + "4. A Tale of Two Cities\n" + + "5. On the Road\n" + + "6. Bright on Rock\n" + + "7. Pick Up\n" + + "8. Pride and Prejudice\n" + + "9. White Fang\n" + + "10. American Psycho\n" + + "11. Notes from Underground\n" + + "12. The Haunting of Hill House\n" + + "13. Metamorphosis\n" + + "14. Invisible Man\n" + + "15. The Adventures of Huckleberry Finn"); + } + + public void showErrorSummary(int wrongWordCount, int totalWordCount, double sentenceErrorRate) { + out.println("Wrong words: " + wrongWordCount + "/" + totalWordCount); + out.println("Error rate: " + String.format("%.2f", sentenceErrorRate)); + } + public void showSummary(int errorWordCount, double wpm, int totalWordTyped, double gameTime) { out.println("Wrong words: " + errorWordCount + "/" + totalWordTyped); out.println("WPM: " + String. format("%.2f", wpm)); - out.println("Total Time taken for the game: " + String. format("%.2f", gameTime) + " seconds"); + out.println("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); } } From 5287008c15c94b22808f5b6ed3dafe10b5486430 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:07:46 +0800 Subject: [PATCH 058/272] Content selection, basic error game (not finished) --- src/main/java/seedu/typists/Main.java | 1 + src/main/java/seedu/typists/content/Books.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index fc3ff337ca..9b73698372 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -68,6 +68,7 @@ public void executeCommand(Parser c, NewGame game, StorageFile storage) { break; case "error": startErrorGame(); + break; default: break; } diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java index b8e20938b6..a44fdae0bc 100644 --- a/src/main/java/seedu/typists/content/Books.java +++ b/src/main/java/seedu/typists/content/Books.java @@ -245,6 +245,7 @@ public class Books { + "all told about in that book, which is mostly a " + "true book, with some stretchers, as I said before." }; + public static String getBook(int index) { return bookContent[index]; } From b113ebb8baad08b73e8b76b2a1ca1b5ee2375363 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:26:08 +0800 Subject: [PATCH 059/272] Content selection, basic error game (not finished) --- .../java/seedu/typists/content/Books.java | 484 +++++++++--------- 1 file changed, 242 insertions(+), 242 deletions(-) diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java index a44fdae0bc..48f54743be 100644 --- a/src/main/java/seedu/typists/content/Books.java +++ b/src/main/java/seedu/typists/content/Books.java @@ -2,248 +2,248 @@ public class Books { private static String[] bookContent = { - "A green hunting " - + "cap squeezed the top of the fleshy " - + "balloon of a head. The green earflaps, " - + "full of large ears and uncut hair and the fine " - + "bristles that grew in the ears themselves, " - + "stuck out on either side like turn signals " - + "indicating two directions at once. " - + "Full, pursed lips protruded beneath the bushy black " - + "moustache and, at their corners, sank into little folds " - + "filled with disapproval and potato chip crumbs. " - + "In the shadow under the green visor of the cap Ignatius J. " - + "Reilly’s supercilious blue and yellow eyes looked down " - + "upon the other people waiting under the clock at the D.H. " - + "Holmes department store, studying the crowd of " - + "people for signs of bad taste in dress. " - + "Several of the outfits, Ignatius noticed, " - + "were new enough and expensive enough to be properly " - + "considered offenses against taste and decency. " - + "Possession of anything new or expensive only reflected a " - + "person’s lack of theology and geometry;" - + "it could even cast doubts upon one’s soul.", - "Call me Ishmael. " - + "Some years ago — never mind how long precisely — " - + "having little or no money in my purse, " - + "and nothing particular to interest me on shore, " - + "I thought I would sail about " - + "a little and see the watery part of the world. It is a way " - + "I have of driving off the spleen, " - + "and regulating the circulation. " - + "Whenever I find myself growing grim about the mouth; " - + "whenever it is a damp, drizzly November in my soul; " - + "whenever I find myself involuntarily pausing before coffin " - + "warehouses, and bringing up the rear of every funeral I meet; " - + "and especially whenever my hypos get such an upper hand of me, " - + "that it requires a strong moral principle to prevent me from " - + "deliberately stepping into the street, " - + "and methodically knocking people’s hats off — then, " - + "I account it high time to get to sea as soon as I can. " - + "This is my substitute for pistol and ball. " - + "With a philosophical flourish Cato throws himself " - + "upon his sword; I quietly take to the ship. " - + "There is nothing surprising in this. If they but knew it, " - + "almost all men in their degree, some time or other, " - + "cherish very nearly the same " - + "feelings towards the ocean with me.", - "In the late summer of that year we lived in " - + "a house in a village that looked across the river " - + "and the plain to the mountains. " - + "In the bed of the river there were pebbles and boulders, " - + "dry and white in the sun, and the water was clear and swiftly " - + "moving and blue in the channels. " - + "Troops went by the house and down the road and " - + "the dust they raised powdered the leaves of the trees. " - + "The trunks of the trees too were dusty and the leaves fell " - + "early that year and we saw the troops marching along the " - + "road and the dust rising and leaves, stirred by the breeze, " - + "falling and the soldiers marching and " - + "afterward the road bare and white except for the leaves.", - "It was the best of times, " - + "it was the worst of times, " - + "it was the age of wisdom, it was the age of foolishness, " - + "it was the epoch of belief, it was the epoch of incredulity, " - + "it was the season of Light, it was the season of Darkness, " - + "it was the spring of hope, it was the winter of despair, " - + "we had everything before us, we had nothing before us, " - + "we were all going direct to Heaven, " - + "we were all going direct the other way — " - + "in short, the period was so far like the present period, " - + "that some of its noisiest authorities insisted on its being " - + "received, for good or for evil, " - + "in the superlative degree of comparison only.", - "I first met Dean not long " - + "after my wife and I split up. " - + "I had just gotten over a serious illness that " - + "I won’t bother to talk about, except that " - + "it had something to do with the miserably weary " - + "split-up and my feeling that everything was dead. " - + "With the coming of Dean Moriarty began the part " - + "of my life you could call my life on the road. " - + "Before that I’d often dreamed of going West to see the " - + "country, always vaguely planning and never taking off. " - + "Dean is the perfect guy for the road because he " - + "actually was born on the road, " - + "when his parents were passing through Salt Lake City in 1926, " - + "in a jalopy, on their way to Los Angeles. " - + "First reports of him came to me through Chad King, " - + "who’d shown me a few letters from him written in a " - + "New Mexico reform school. I was tremendously interested " - + "in the letters because they so naively and sweetly asked " - + "Chad to teach him all about Nietzsche and all the wonderful " - + "intellectual things that Chad knew. At one point Carlo and " - + "I talked about the letters and wondered if we would ever meet " - + "the strange Dean Moriarty. This is all far back, " - + "when Dean was not the way he is today, when he was a " - + "young jailkid shrouded in mystery. Then news came that Dean " - + "was out of reform school and was coming to New York for the " - + "first time; also there was talk that he had just " - + "married a girl called Marylou.", - "Hale knew, before he had been in Brighton " - + "three hours, that they meant to murder him. " - + "With his inky fingers and his bitten nails, " - + "his manner cynical and nervous, " - + "anybody could tell he didn’t belong – " - + "belong to the early summer sun, the cool " - + "Whitsun wind off the sea, the holiday crowd. " - + "They came in by train from Victoria every five minutes, " - + "rocked down Queen’s Road standing on the " - + "tops of the little local trams, stepped off " - + "in bewildered multitudes into fresh and " - + "glittering air: the new silver paint sparkled on the piers, " - + "the cream houses ran away into the west like a " - + "pale Victorian water-colour; a race in miniature motors, " - + "a band playing, flower gardens in bloom below the " - + "front, an aeroplane advertising something for " - + "the health in pale vanishing clouds across the sky.", - "It must have been around a quarter to eleven. " - + "A sailor came in and ordered a chile dog and coffee. " - + "I sliced a bun, jerked a frank out of the boiling water, " - + "nested it, poured a half-dipper of chile over the frank " - + "and sprinkled it liberally with chopped onions. " - + "I scribbled a check and put it by his plate. " - + "I wouldn’t have recommended the unpalatable mess " - + "to a starving animal. The sailor was the only customer, " - + "and after he ate his dog he left. " - + "That was the exact moment she entered. " - + "A small woman, hardly more than five feet. " - + "She had the figure of a teenage girl. " - + "Her suit was a blue tweed, smartly cut, " - + "and over her thin shoulders she wore a fur jacket, " - + "bolero length. Tiny gold circular earrings " - + "clung to her small pierced ears. " - + "Her hands and feet were small, " - + "and when she seated herself at " - + "the counter I noticed she wasn’t wearing any rings.", - "It is a truth universally acknowledged, " - + "that a single man in possession of a good fortune must be in " - + "want of a wife. However little known the feelings or " - + "views of such a man may be on his first entering a " - + "neighbourhood, this truth is so well fixed in the minds of the " - + "surrounding families, that he is considered as the rightful " - + "property of some one or other of their daughters.", - "Dark spruce forest frowned on either side of the " - + "frozen waterway. The trees had been stripped by a " - + "recent wind of their white covering of frost, " - + "and they seemed to lean toward each other, " - + "black and ominous, in the fading light. " - + "A vast silence reigned over the land. " - + "The land itself was a desolation, lifeless, " - + "without movement, so lone and cold that the spirit of " - + "it was not even that of sadness. " - + "There was a hint in it of laughter, " - + "but of a laughter more terrible than any sadness — " - + "a laughter that was mirthless as the smile of the Sphinx, " - + "a laughter cold as the frost and partaking of the " - + "grimness of infallibility. " - + "It was the masterful and incommunicable " - + "wisdom of eternity laughing at the futility " - + "of life and the effort of life. " - + "It was the Wild, the savage, frozen-hearted Northland Wild.", - "ABANDON ALL HOPE YE WHO ENTER HERE is " - + "scrawled in blood red lettering on " - + "the side of the Chemical Bank near the corner of " - + "Eleventh and First and is in print large enough to be seen " - + "from the backseat of the cab as it lurches forward in " - + "the traffic leaving Wall Street and just as Timothy " - + "Price notices the words a bus pulls up, " - + "the advertisement for Les Miserables on its side blocking " - + "his view, but Price who is with Pierce & Pierce " - + "and twenty-six doesn't seem to care because he " - + "tells the driver he will give him five dollars to turn " - + "up the radio, \"Be My Baby\" on WYNN, " - + "and the driver, black, not American, does so.", - "I am a sick man. ... " - + "I am a spiteful man. I am an unattractive man. " - + "I believe my liver is diseased. However, " - + "I know nothing at all about my disease, " - + "and do not know for certain what ails me. " - + "I don't consult a doctor for it, and never have, " - + "though I have a respect for medicine and doctors. " - + "Besides, I am extremely superstitious, " - + "sufficiently so to respect medicine, anyway " - + "(I am well-educated enough not to be superstitious, " - + "but I am superstitious). No, " - + "I refuse to consult a doctor from spite. " - + "That you probably will not understand. " - + "Well, I understand it, though. Of course, " - + "I can't explain who it is precisely that " - + "I am mortifying in this case by my spite: " - + "I am perfectly well aware that I cannot \"pay " - + "out\" the doctors by not consulting them; " - + "I know better than anyone that by all this " - + "I am only injuring myself and no one else. " - + "But still, if I don't consult a doctor it is from spite. " - + "My liver is bad, well then let it hurt even worse!", - "No live organism can continue " - + "for long to exist sanely under conditions of absolute " - + "reality; even larks and katydids are supposed, by some, " - + "to dream. Hill House, not sane, stood by itself against " - + "its hills, holding darkness within; it had stood so for " - + "eighty years and might stand for eighty more. " - + "Within, walls continued upright, bricks met neatly, " - + "floors were firm, and doors were sensibly shut; " - + "silence lay steadily against the wood and " - + "stone of Hill House, and whatever walked there, walked alone…", - "As Gregor Samsa awoke one " - + "morning from uneasy dreams he found himself transformed " - + "in his bed into a gigantic insect. " - + "He was lying on his hard, as it were armor-plated, " - + "back and when he lifted his head a little he " - + "could see his dome-like brown belly divided into " - + "stiff arched segments on top of which the " - + "bed quilt could hardly keep in position and " - + "was about to slide off completely. " - + "His numerous legs, which were pitifully thin " - + "compared to the rest of his bulk, " - + "waved helplessly before his eyes.", - "I am an invisible man. " - + "No, I am not a spook like those who haunted Edgar Allan Poe; " - + "nor am I one of your Hollywood-movie ectoplasms. " - + "I am a man of substance, of flesh and bone, fiber " - + "and liquids—and I might even be said to possess a mind. " - + "I am invisible, understand, simply because people " - + "refuse to see me. Like the bodiless heads you see " - + "sometimes in circus sideshows, it is as though " - + "I have been surrounded by mirrors of hard, distorting glass. " - + "When they approach me they see only my surroundings, " - + "themselves, or figments of their imagination—" - + "indeed, everything and anything except me.", - "You don't know " - + "about me without you have read a book by the " - + "name of The Adventures of Tom Sawyer; " - + "but that ain't no matter. That book was made " - + "by Mr. Mark Twain, and he told the truth, mainly. " - + "There was things which he stretched, " - + "but mainly he told the truth. " - + "That is nothing. I never seen anybody " - + "but lied one time or another, without " - + "it was Aunt Polly, or the widow, or " - + "maybe Mary. Aunt Polly - Tom's Aunt Polly, " - + "she is - and Mary, and the Widow Douglas is " - + "all told about in that book, which is mostly a " - + "true book, with some stretchers, as I said before." + "A green hunting " + + "cap squeezed the top of the fleshy " + + "balloon of a head. The green earflaps, " + + "full of large ears and uncut hair and the fine " + + "bristles that grew in the ears themselves, " + + "stuck out on either side like turn signals " + + "indicating two directions at once. " + + "Full, pursed lips protruded beneath the bushy black " + + "moustache and, at their corners, sank into little folds " + + "filled with disapproval and potato chip crumbs. " + + "In the shadow under the green visor of the cap Ignatius J. " + + "Reilly’s supercilious blue and yellow eyes looked down " + + "upon the other people waiting under the clock at the D.H. " + + "Holmes department store, studying the crowd of " + + "people for signs of bad taste in dress. " + + "Several of the outfits, Ignatius noticed, " + + "were new enough and expensive enough to be properly " + + "considered offenses against taste and decency. " + + "Possession of anything new or expensive only reflected a " + + "person’s lack of theology and geometry;" + + "it could even cast doubts upon one’s soul.", + "Call me Ishmael. " + + "Some years ago — never mind how long precisely — " + + "having little or no money in my purse, " + + "and nothing particular to interest me on shore, " + + "I thought I would sail about " + + "a little and see the watery part of the world. It is a way " + + "I have of driving off the spleen, " + + "and regulating the circulation. " + + "Whenever I find myself growing grim about the mouth; " + + "whenever it is a damp, drizzly November in my soul; " + + "whenever I find myself involuntarily pausing before coffin " + + "warehouses, and bringing up the rear of every funeral I meet; " + + "and especially whenever my hypos get such an upper hand of me, " + + "that it requires a strong moral principle to prevent me from " + + "deliberately stepping into the street, " + + "and methodically knocking people’s hats off — then, " + + "I account it high time to get to sea as soon as I can. " + + "This is my substitute for pistol and ball. " + + "With a philosophical flourish Cato throws himself " + + "upon his sword; I quietly take to the ship. " + + "There is nothing surprising in this. If they but knew it, " + + "almost all men in their degree, some time or other, " + + "cherish very nearly the same " + + "feelings towards the ocean with me.", + "In the late summer of that year we lived in " + + "a house in a village that looked across the river " + + "and the plain to the mountains. " + + "In the bed of the river there were pebbles and boulders, " + + "dry and white in the sun, and the water was clear and swiftly " + + "moving and blue in the channels. " + + "Troops went by the house and down the road and " + + "the dust they raised powdered the leaves of the trees. " + + "The trunks of the trees too were dusty and the leaves fell " + + "early that year and we saw the troops marching along the " + + "road and the dust rising and leaves, stirred by the breeze, " + + "falling and the soldiers marching and " + + "afterward the road bare and white except for the leaves.", + "It was the best of times, " + + "it was the worst of times, " + + "it was the age of wisdom, it was the age of foolishness, " + + "it was the epoch of belief, it was the epoch of incredulity, " + + "it was the season of Light, it was the season of Darkness, " + + "it was the spring of hope, it was the winter of despair, " + + "we had everything before us, we had nothing before us, " + + "we were all going direct to Heaven, " + + "we were all going direct the other way — " + + "in short, the period was so far like the present period, " + + "that some of its noisiest authorities insisted on its being " + + "received, for good or for evil, " + + "in the superlative degree of comparison only.", + "I first met Dean not long " + + "after my wife and I split up. " + + "I had just gotten over a serious illness that " + + "I won’t bother to talk about, except that " + + "it had something to do with the miserably weary " + + "split-up and my feeling that everything was dead. " + + "With the coming of Dean Moriarty began the part " + + "of my life you could call my life on the road. " + + "Before that I’d often dreamed of going West to see the " + + "country, always vaguely planning and never taking off. " + + "Dean is the perfect guy for the road because he " + + "actually was born on the road, " + + "when his parents were passing through Salt Lake City in 1926, " + + "in a jalopy, on their way to Los Angeles. " + + "First reports of him came to me through Chad King, " + + "who’d shown me a few letters from him written in a " + + "New Mexico reform school. I was tremendously interested " + + "in the letters because they so naively and sweetly asked " + + "Chad to teach him all about Nietzsche and all the wonderful " + + "intellectual things that Chad knew. At one point Carlo and " + + "I talked about the letters and wondered if we would ever meet " + + "the strange Dean Moriarty. This is all far back, " + + "when Dean was not the way he is today, when he was a " + + "young jailkid shrouded in mystery. Then news came that Dean " + + "was out of reform school and was coming to New York for the " + + "first time; also there was talk that he had just " + + "married a girl called Marylou.", + "Hale knew, before he had been in Brighton " + + "three hours, that they meant to murder him. " + + "With his inky fingers and his bitten nails, " + + "his manner cynical and nervous, " + + "anybody could tell he didn’t belong – " + + "belong to the early summer sun, the cool " + + "Whitsun wind off the sea, the holiday crowd. " + + "They came in by train from Victoria every five minutes, " + + "rocked down Queen’s Road standing on the " + + "tops of the little local trams, stepped off " + + "in bewildered multitudes into fresh and " + + "glittering air: the new silver paint sparkled on the piers, " + + "the cream houses ran away into the west like a " + + "pale Victorian water-colour; a race in miniature motors, " + + "a band playing, flower gardens in bloom below the " + + "front, an aeroplane advertising something for " + + "the health in pale vanishing clouds across the sky.", + "It must have been around a quarter to eleven. " + + "A sailor came in and ordered a chile dog and coffee. " + + "I sliced a bun, jerked a frank out of the boiling water, " + + "nested it, poured a half-dipper of chile over the frank " + + "and sprinkled it liberally with chopped onions. " + + "I scribbled a check and put it by his plate. " + + "I wouldn’t have recommended the unpalatable mess " + + "to a starving animal. The sailor was the only customer, " + + "and after he ate his dog he left. " + + "That was the exact moment she entered. " + + "A small woman, hardly more than five feet. " + + "She had the figure of a teenage girl. " + + "Her suit was a blue tweed, smartly cut, " + + "and over her thin shoulders she wore a fur jacket, " + + "bolero length. Tiny gold circular earrings " + + "clung to her small pierced ears. " + + "Her hands and feet were small, " + + "and when she seated herself at " + + "the counter I noticed she wasn’t wearing any rings.", + "It is a truth universally acknowledged, " + + "that a single man in possession of a good fortune must be in " + + "want of a wife. However little known the feelings or " + + "views of such a man may be on his first entering a " + + "neighbourhood, this truth is so well fixed in the minds of the " + + "surrounding families, that he is considered as the rightful " + + "property of some one or other of their daughters.", + "Dark spruce forest frowned on either side of the " + + "frozen waterway. The trees had been stripped by a " + + "recent wind of their white covering of frost, " + + "and they seemed to lean toward each other, " + + "black and ominous, in the fading light. " + + "A vast silence reigned over the land. " + + "The land itself was a desolation, lifeless, " + + "without movement, so lone and cold that the spirit of " + + "it was not even that of sadness. " + + "There was a hint in it of laughter, " + + "but of a laughter more terrible than any sadness — " + + "a laughter that was mirthless as the smile of the Sphinx, " + + "a laughter cold as the frost and partaking of the " + + "grimness of infallibility. " + + "It was the masterful and incommunicable " + + "wisdom of eternity laughing at the futility " + + "of life and the effort of life. " + + "It was the Wild, the savage, frozen-hearted Northland Wild.", + "ABANDON ALL HOPE YE WHO ENTER HERE is " + + "scrawled in blood red lettering on " + + "the side of the Chemical Bank near the corner of " + + "Eleventh and First and is in print large enough to be seen " + + "from the backseat of the cab as it lurches forward in " + + "the traffic leaving Wall Street and just as Timothy " + + "Price notices the words a bus pulls up, " + + "the advertisement for Les Miserables on its side blocking " + + "his view, but Price who is with Pierce & Pierce " + + "and twenty-six doesn't seem to care because he " + + "tells the driver he will give him five dollars to turn " + + "up the radio, \"Be My Baby\" on WYNN, " + + "and the driver, black, not American, does so.", + "I am a sick man. ... " + + "I am a spiteful man. I am an unattractive man. " + + "I believe my liver is diseased. However, " + + "I know nothing at all about my disease, " + + "and do not know for certain what ails me. " + + "I don't consult a doctor for it, and never have, " + + "though I have a respect for medicine and doctors. " + + "Besides, I am extremely superstitious, " + + "sufficiently so to respect medicine, anyway " + + "(I am well-educated enough not to be superstitious, " + + "but I am superstitious). No, " + + "I refuse to consult a doctor from spite. " + + "That you probably will not understand. " + + "Well, I understand it, though. Of course, " + + "I can't explain who it is precisely that " + + "I am mortifying in this case by my spite: " + + "I am perfectly well aware that I cannot \"pay " + + "out\" the doctors by not consulting them; " + + "I know better than anyone that by all this " + + "I am only injuring myself and no one else. " + + "But still, if I don't consult a doctor it is from spite. " + + "My liver is bad, well then let it hurt even worse!", + "No live organism can continue " + + "for long to exist sanely under conditions of absolute " + + "reality; even larks and katydids are supposed, by some, " + + "to dream. Hill House, not sane, stood by itself against " + + "its hills, holding darkness within; it had stood so for " + + "eighty years and might stand for eighty more. " + + "Within, walls continued upright, bricks met neatly, " + + "floors were firm, and doors were sensibly shut; " + + "silence lay steadily against the wood and " + + "stone of Hill House, and whatever walked there, walked alone…", + "As Gregor Samsa awoke one " + + "morning from uneasy dreams he found himself transformed " + + "in his bed into a gigantic insect. " + + "He was lying on his hard, as it were armor-plated, " + + "back and when he lifted his head a little he " + + "could see his dome-like brown belly divided into " + + "stiff arched segments on top of which the " + + "bed quilt could hardly keep in position and " + + "was about to slide off completely. " + + "His numerous legs, which were pitifully thin " + + "compared to the rest of his bulk, " + + "waved helplessly before his eyes.", + "I am an invisible man. " + + "No, I am not a spook like those who haunted Edgar Allan Poe; " + + "nor am I one of your Hollywood-movie ectoplasms. " + + "I am a man of substance, of flesh and bone, fiber " + + "and liquids—and I might even be said to possess a mind. " + + "I am invisible, understand, simply because people " + + "refuse to see me. Like the bodiless heads you see " + + "sometimes in circus sideshows, it is as though " + + "I have been surrounded by mirrors of hard, distorting glass. " + + "When they approach me they see only my surroundings, " + + "themselves, or figments of their imagination—" + + "indeed, everything and anything except me.", + "You don't know " + + "about me without you have read a book by the " + + "name of The Adventures of Tom Sawyer; " + + "but that ain't no matter. That book was made " + + "by Mr. Mark Twain, and he told the truth, mainly. " + + "There was things which he stretched, " + + "but mainly he told the truth. " + + "That is nothing. I never seen anybody " + + "but lied one time or another, without " + + "it was Aunt Polly, or the widow, or " + + "maybe Mary. Aunt Polly - Tom's Aunt Polly, " + + "she is - and Mary, and the Widow Douglas is " + + "all told about in that book, which is mostly a " + + "true book, with some stretchers, as I said before." }; public static String getBook(int index) { From 4da66928f8303f53cc8d6503f12beba477781157 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:28:02 +0800 Subject: [PATCH 060/272] Content selection, basic error game (not finished) --- src/main/java/seedu/typists/parser/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index 970d9b362f..fe0fde8255 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -50,7 +50,7 @@ public void parse() throws FaultyInputException { case "content": command = "content"; break; - default: + default: System.out.println("invalid command."); break; } From 099b254fd35b6f3dbf7ad8e2ff0fb25becf66181 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:31:31 +0800 Subject: [PATCH 061/272] Content selection, basic error game (not finished) --- src/test/java/seedu/WikiImportTest.java | 8 ++++---- text-ui-test/EXPECTED.TXT | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java index c970cb6271..c656b75e4c 100644 --- a/src/test/java/seedu/WikiImportTest.java +++ b/src/test/java/seedu/WikiImportTest.java @@ -3,19 +3,19 @@ import org.junit.jupiter.api.Test; import seedu.typists.content.WikiImport; import seedu.typists.exception.InvalidArticleException; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; + +import static org.junit.jupiter.api.Assertions.*; public class WikiImportTest { // methodBeingTested_inputGiven_expectedOutcome - // Input, GitHub, relevant article (731 characters) + // Input, GitHub, relevant article (longer than 0) @Test void getArticle_GitHub_expectArticle() throws InvalidArticleException { String article = "GitHub"; WikiImport wiki = new WikiImport(); String content = wiki.getArticle(article); - assertEquals(731, content.length()); + assertTrue(content.length() > 0); } // test failure case diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 4093c8021a..0f37c07d29 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -9,8 +9,10 @@ | Welcome to Typist -- the ultimate cli typing game. | Brought to you by -- AY2122S1-CS2113-T13-4. | Manual: + | content: set the content | new: start a new word game | time: start a new timer game + | error: start a new error game | bye: exit typist | **************************************************************** **************************************************************** From c31dcbcfe4bd9e473c72b0bae4f6762cedae00ba Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:42:45 +0800 Subject: [PATCH 062/272] Some ascii art --- src/main/java/seedu/typists/Main.java | 1 + .../java/seedu/typists/common/Messages.java | 47 +++++++++++++++++++ .../java/seedu/typists/content/Content.java | 1 + src/main/java/seedu/typists/ui/TextUi.java | 18 +++++-- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 9b73698372..431e5d2b98 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -46,6 +46,7 @@ public void startWordLimitGame() { } public void startTimeLimitGame() { + uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); uiBot.showSummary(p.getErrorWordCount(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index fa012568a1..f8357c4c82 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -12,6 +12,53 @@ public class Messages { + "/_/ \\__, / .___/_/____/\\__/\n" + " /____/_/"; + public static final String KEYBOARD = + ",---,---,---,---,---,---,---,---,---,---,---,---,---,-------,\n" + + "|1/2| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | + | ' | <- |\n" + + "|---'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-----|\n" + + "| ->| | Q | W | E | R | T | Y | U | I | O | P | ] | ^ | |\n" + + "|-----',--',--',--',--',--',--',--',--',--',--',--',--'| |\n" + + "| Caps | A | S | D | F | G | H | J | K | L | \\ | [ | * | |\n" + + "|----,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'---'----|\n" + + "| | < | Z | X | C | V | B | N | M | , | . | - | |\n" + + "|----'-,-',--'--,'---'---'---'---'---'---'-,-'---',--,------|\n" + + "| ctrl | | alt | |altgr | | ctrl |\n" + + "'------' '-----'--------------------------'------' '------'\n"; + + public static final String LETTER = + "(\\ \n" + + "\\'\\ \n" + + " \\'\\ __________ \n" + + " / '| ()_________)\n" + + " \\ '/ \\ ~~~~~~~~ \\\n" + + " \\ \\ ~~~~~~ \\\n" + + " ==). \\__________\\\n" + + " (__) ()__________)"; + + public static final String CLOCK = + " ,--.-----.--.\n" + + " |--|-----|--|\n" + + " |--| |--|\n" + + " | |-----| |\n" + + " __|--| |--|__\n" + + " / | |-----| | \\\n" + + " / \\__|-----|__/ \\\n" + + " / ______---______ \\/\\\n" + + " / / \\ \\/\n" + + "{ / _ _ _ \\ }\n" + + "| { | | . | | | | } |-,\n" + + "| | |_| . |_| |_| | | |\n" + + "| { } |-'\n" + + "{ \\ / }\n" + + " \\ `------___------' /\\\n" + + " \\ __|-----|__ /\\/\n" + + " \\ / |-----| \\ /\n" + + " \\ |--| |--| /\n" + + " --| |-----| |--\n" + + " |--| |--|\n" + + " |--|-----|--|\n" + + " `--'-----`--'"; + public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 1ac3e79bbd..1fd51bc51f 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -22,6 +22,7 @@ public String getContent() { } public void setContent() { + ui.printLetter(); ui.showText("Content selection (input 0 to go back):\n" + "1. Opening of famous books\n" + "2. Wikipedia article\n" diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index d2f914a801..bc07154fa8 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -5,10 +5,8 @@ import static java.lang.System.lineSeparator; import static java.lang.System.out; -import static seedu.typists.common.Messages.LOGO; -import static seedu.typists.common.Messages.MESSAGE_WELCOME; -import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; -import static seedu.typists.common.Messages.MESSAGE_HELP; +import static seedu.typists.common.Messages.*; + import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Scanner; @@ -92,6 +90,18 @@ public void printSuccess() { System.out.println("Finished!"); } + public void printKeyboard() { + out.println(KEYBOARD); + } + + public void printLetter() { + out.println(LETTER); + } + + public void printClock() { + out.println(CLOCK); + } + public void printBookSelection() { System.out.println("Input '0' to go back.\n" + "Content list:\n" From 0a48ba697a096e790c1e31b128c59e7be1a07fdb Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:44:47 +0800 Subject: [PATCH 063/272] Some ascii art --- src/main/java/seedu/typists/ui/TextUi.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index bc07154fa8..c7014ee65a 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -5,7 +5,13 @@ import static java.lang.System.lineSeparator; import static java.lang.System.out; -import static seedu.typists.common.Messages.*; +import static seedu.typists.common.Messages.CLOCK; +import static seedu.typists.common.Messages.KEYBOARD; +import static seedu.typists.common.Messages.LETTER; +import static seedu.typists.common.Messages.LOGO; +import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; +import static seedu.typists.common.Messages.MESSAGE_HELP; +import static seedu.typists.common.Messages.MESSAGE_WELCOME; import java.sql.Timestamp; import java.text.SimpleDateFormat; From 148ad596dc5d3160d13b53e706fe769b84d5aaab Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 02:47:44 +0800 Subject: [PATCH 064/272] Some ascii art --- src/test/java/seedu/WikiImportTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java index c656b75e4c..75cb546e15 100644 --- a/src/test/java/seedu/WikiImportTest.java +++ b/src/test/java/seedu/WikiImportTest.java @@ -4,7 +4,8 @@ import seedu.typists.content.WikiImport; import seedu.typists.exception.InvalidArticleException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; public class WikiImportTest { From a29a5c3e0ddb1ce78d14431bc47ef5d354fd3d98 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 03:01:26 +0800 Subject: [PATCH 065/272] Some ascii art --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b7c8c5dbf5..f371643eed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From b63520200ca07b5ab90c613024434371fee3d054 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 03:05:10 +0800 Subject: [PATCH 066/272] Revert "Some ascii art" This reverts commit a29a5c3e0ddb1ce78d14431bc47ef5d354fd3d98. --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f371643eed..b7c8c5dbf5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 408c586c56e86a3b9ef342f2c4633466a3978109 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 04:21:24 +0800 Subject: [PATCH 067/272] Minor changes --- src/main/java/seedu/typists/content/Content.java | 10 +++++----- src/main/java/seedu/typists/game/DataProcessor.java | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 1fd51bc51f..0783df15b3 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -115,13 +115,13 @@ private void setRandomContent() { if (length == 0) { setContent(); } else { - StringBuilder s = new StringBuilder(); + String s = ""; + Random r = new Random(); for (int i = 0; i < length; i++) { - Random r = new Random(); - s.append(rg.randomString(r.nextInt(10) + 5)).append(" "); + s += (rg.randomString(r.nextInt(10) + 5) + " "); } - this.content = s.toString(); - ui.showText("Content set"); + this.content = s; + ui.showText("Content set " + this.content); } } } diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 6cb2a60e85..b46ca9c987 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -45,7 +45,6 @@ public double getWordPerMinute() { return getTotalWordTyped() / (totalTime / 60); } - public void getWrongKeyStrokes(ArrayList checkerText, ArrayList userText) { int totalErrorCount = 0; for (int i = 0; i < userText.size(); i++) { From 490fe8fe6d339f172bd74ebb8f8d1802d6ad82c9 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 16 Oct 2021 04:24:54 +0800 Subject: [PATCH 068/272] Minor changes --- src/main/java/seedu/typists/Main.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 431e5d2b98..dd1b695b26 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -37,6 +37,7 @@ public void start() { } public void startWordLimitGame() { + uiBot.printKeyboard(); this.wordLimitGame = new NewGame(); try { wordLimitGame.beginNewGame(); From 8f85ff76c620676ad92d02efbd9146920b507071 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 17 Oct 2021 13:38:22 +0800 Subject: [PATCH 069/272] Update limjiajing-AboutUs --- docs/AboutUs.md | 2 +- docs/team/limjiajing.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/team/limjiajing.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 9d40eefe9d..a0c18b4fb9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/johndoe.md) +![img.png](img.png) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/limjiajing.md) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) | Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](docs/team/shizhansen.md) | William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](docs/team/williamwahyudi.md) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md new file mode 100644 index 0000000000..5b00fe8e74 --- /dev/null +++ b/docs/team/limjiajing.md @@ -0,0 +1,6 @@ +# Lim Jia Jing - Project Portfolio Page + +## Overview + + +### Summary of Contributions From 951559378adb40f84adf1ad02ab325a27e048c6a Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 17 Oct 2021 13:49:47 +0800 Subject: [PATCH 070/272] Change image in AboutUs --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index a0c18b4fb9..b5de7acb35 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: -![img.png](img.png) | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/limjiajing.md) + | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/limjiajing.md) | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) | Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](docs/team/shizhansen.md) | William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](docs/team/williamwahyudi.md) From 4e6b1e93a616efbb7fcdc30a60e08f92bd3a7eb4 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 17 Oct 2021 16:39:35 +0800 Subject: [PATCH 071/272] Improve show summary method. --- src/main/java/seedu/typists/Main.java | 2 +- src/main/java/seedu/typists/common/Messages.java | 7 +++++++ src/main/java/seedu/typists/game/DataProcessor.java | 5 +++++ src/main/java/seedu/typists/ui/TextUi.java | 6 ++++-- src/test/java/seedu/typists/ui/TextUiTest.java | 4 ++++ 5 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/test/java/seedu/typists/ui/TextUiTest.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index dd1b695b26..9fe1cea51d 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -50,7 +50,7 @@ public void startTimeLimitGame() { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showSummary(p.getErrorWordCount(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); + uiBot.showSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); } public void startErrorGame() { diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index f8357c4c82..92ee84031e 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -12,6 +12,13 @@ public class Messages { + "/_/ \\__, / .___/_/____/\\__/\n" + " /____/_/"; + public static final String SUMMARY = + " _____ __ ____ _____ ______ ______ __\n" + + " / ___// / / / |/ / |/ / | / __ \\ \\/ /\n" + + " \\__ \\/ / / / /|_/ / /|_/ / /| | / /_/ /\\ / \n" + + " ___/ / /_/ / / / / / / / ___ |/ _, _/ / / \n" + + "/____/\\____/_/ /_/_/ /_/_/ |_/_/ |_| /_/"; + public static final String KEYBOARD = ",---,---,---,---,---,---,---,---,---,---,---,---,---,-------,\n" + "|1/2| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | + | ' | <- |\n" diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index b46ca9c987..100d04747e 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -66,4 +66,9 @@ public int getLineWrongKeyStrokes(String checker, String answer) { } return errorCount; } + + public double getErrorPercentage(){ + double percentage = (double)getErrorWordCount()/(double)getTotalWordTyped(); + return percentage; + } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index c7014ee65a..b7565a0a56 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -12,11 +12,11 @@ import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; import static seedu.typists.common.Messages.MESSAGE_HELP; import static seedu.typists.common.Messages.MESSAGE_WELCOME; +import static seedu.typists.common.Messages.SUMMARY; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Scanner; - /** * Text UI of the application. */ @@ -133,8 +133,10 @@ public void showErrorSummary(int wrongWordCount, int totalWordCount, double sent out.println("Error rate: " + String.format("%.2f", sentenceErrorRate)); } - public void showSummary(int errorWordCount, double wpm, int totalWordTyped, double gameTime) { + public void showSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) { + out.println(SUMMARY); out.println("Wrong words: " + errorWordCount + "/" + totalWordTyped); + out.println("Error percentage: "+ String. format("%.2f", errorPercentage)); out.println("WPM: " + String. format("%.2f", wpm)); out.println("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java new file mode 100644 index 0000000000..78657059b2 --- /dev/null +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -0,0 +1,4 @@ +import static org.junit.jupiter.api.Assertions.*; +class TextUiTest { + +} \ No newline at end of file From 82bf2e2f0e6d798818c25743cb015552e21374da Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 17 Oct 2021 16:41:41 +0800 Subject: [PATCH 072/272] Debug and add JUnit test for showSummary method in package seedu.typists.ui.TextUi --- src/main/java/seedu/typists/ui/TextUi.java | 10 ++--- .../java/seedu/typists/ui/TextUiTest.java | 39 ++++++++++++++++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index b7565a0a56..aa896b2789 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -134,10 +134,10 @@ public void showErrorSummary(int wrongWordCount, int totalWordCount, double sent } public void showSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) { - out.println(SUMMARY); - out.println("Wrong words: " + errorWordCount + "/" + totalWordTyped); - out.println("Error percentage: "+ String. format("%.2f", errorPercentage)); - out.println("WPM: " + String. format("%.2f", wpm)); - out.println("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); + out.print(SUMMARY+'\n'); + out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + out.print("Error Percentage: "+ String. format("%.2f", errorPercentage) +"%\n"); + out.print("WPM: " + String. format("%.2f", wpm)+'\n'); + out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index 78657059b2..c879215259 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -1,4 +1,39 @@ -import static org.junit.jupiter.api.Assertions.*; +package seedu.typists.ui; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static seedu.typists.common.Messages.SUMMARY; + class TextUiTest { - + //This code (lines 15 to 38) was referenced from https://www.baeldung.com/java-testing-system-out-println + private final PrintStream standardOut = System.out; + private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); + + @BeforeEach + public void setUp() { + System.setOut(new PrintStream(outputStreamCaptor)); + } + + @Test + void showSummary() { + TextUi textUi = new TextUi(); + String expected = SUMMARY + '\n'+ + "Wrong Words: 5/10\n" + + "Error Percentage: 50.00%\n"+ + "WPM: 40.08\n" + + "Total Time taken for the game: 10.07 seconds\n"; + textUi.showSummary(5,50.00000,40.08,10,10.07); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + @AfterEach + public void tearDown() { + System.setOut(standardOut); + } } \ No newline at end of file From cc5cf634175aea7e7e236c2d1d6b904f9786e521 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 17 Oct 2021 16:50:19 +0800 Subject: [PATCH 073/272] Edit layout to abid by coding conventions --- src/main/java/seedu/typists/ui/TextUi.java | 12 +++++++----- src/test/java/seedu/typists/ui/TextUiTest.java | 7 ++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index aa896b2789..33c1e948d4 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -17,6 +17,7 @@ import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Scanner; + /** * Text UI of the application. */ @@ -50,14 +51,14 @@ public void showWelcomeMessage(String version) { } public void printScreen(String... message) { - for (String m: message) { + for (String m : message) { out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); } } public void printLine(String... message) { out.print(LINE_PREFIX); - for (String m: message) { + for (String m : message) { out.print(m + " "); } out.print("\n"); @@ -74,6 +75,7 @@ public void showLine() { /** * Print error message. + * * @param meg obtained from DukeException message */ public void showText(String meg) { @@ -134,10 +136,10 @@ public void showErrorSummary(int wrongWordCount, int totalWordCount, double sent } public void showSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) { - out.print(SUMMARY+'\n'); + out.print(SUMMARY + '\n'); out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage: "+ String. format("%.2f", errorPercentage) +"%\n"); - out.print("WPM: " + String. format("%.2f", wpm)+'\n'); + out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index c879215259..aa636d5fd3 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -23,15 +23,16 @@ public void setUp() { @Test void showSummary() { TextUi textUi = new TextUi(); - String expected = SUMMARY + '\n'+ + String expected = SUMMARY + '\n' + "Wrong Words: 5/10\n" + - "Error Percentage: 50.00%\n"+ + "Error Percentage: 50.00%\n" + "WPM: 40.08\n" + "Total Time taken for the game: 10.07 seconds\n"; - textUi.showSummary(5,50.00000,40.08,10,10.07); + textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); } + @AfterEach public void tearDown() { System.setOut(standardOut); From be562ff482cc266521b66b8688534683ae89ec86 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 17 Oct 2021 16:55:48 +0800 Subject: [PATCH 074/272] Edit layout to abide by coding conventions --- src/main/java/seedu/typists/Main.java | 15 +++++--- .../java/seedu/typists/common/Messages.java | 34 +++++++++---------- .../seedu/typists/game/DataProcessor.java | 4 +-- src/main/java/seedu/typists/ui/TextUi.java | 3 +- .../java/seedu/typists/ui/TextUiTest.java | 10 +++--- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 9fe1cea51d..b3b7b67c76 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -17,7 +17,9 @@ //solution below adapted from https://github.com/se-edu/addressbook-level2/ public class Main { - /** Version info of the program. */ + /** + * Version info of the program. + */ public static final String VERSION = "Typist - Version 1.0"; public static final int LINE_LENGTH = 10; TextUi uiBot; @@ -49,8 +51,9 @@ public void startWordLimitGame() { public void startTimeLimitGame() { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); - DataProcessor p = new DataProcessor(g); - uiBot.showSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); + DataProcessor p = new DataProcessor(g); + uiBot.showSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), + p.getTotalWordTyped(), p.totalTime); } public void startErrorGame() { @@ -84,7 +87,7 @@ public void runCommandLoopUntilExitCommand() { String fullCommand = uiBot.readCommand(); Parser c = new Parser(fullCommand); c.parse(); - executeCommand(c,wordLimitGame,storage); + executeCommand(c, wordLimitGame, storage); isExit = c.getIsExit(); } catch (StringIndexOutOfBoundsException e) { uiBot.showText("OOPS!!! The description after this command word cannot be empty."); @@ -106,7 +109,9 @@ public void exit() { uiBot.showBye(); } - /** Runs the program until termination. */ + /** + * Runs the program until termination. + */ public void run() { start(); runCommandLoopUntilExitCommand(); diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 92ee84031e..e196e50c28 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -13,11 +13,11 @@ public class Messages { + " /____/_/"; public static final String SUMMARY = - " _____ __ ____ _____ ______ ______ __\n" + - " / ___// / / / |/ / |/ / | / __ \\ \\/ /\n" + - " \\__ \\/ / / / /|_/ / /|_/ / /| | / /_/ /\\ / \n" + - " ___/ / /_/ / / / / / / / ___ |/ _, _/ / / \n" + - "/____/\\____/_/ /_/_/ /_/_/ |_/_/ |_| /_/"; + " _____ __ ____ _____ ______ ______ __\n" + + " / ___// / / / |/ / |/ / | / __ \\ \\/ /\n" + + " \\__ \\/ / / / /|_/ / /|_/ / /| | / /_/ /\\ / \n" + + " ___/ / /_/ / / / / / / / ___ |/ _, _/ / / \n" + + "/____/\\____/_/ /_/_/ /_/_/ |_/_/ |_| /_/"; public static final String KEYBOARD = ",---,---,---,---,---,---,---,---,---,---,---,---,---,-------,\n" @@ -77,18 +77,18 @@ public class Messages { //This sample text is gotten from https://www.lipsum.com/ public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " - + "imply dummy text of the printing and typesetting industry ipum is simply dummy" - + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " - + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry "; + + "imply dummy text of the printing and typesetting industry ipum is simply dummy" + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry "; //public static final String MESSAGE_GOODBYE = "Goodbye!"; //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 100d04747e..4b6498992c 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -67,8 +67,8 @@ public int getLineWrongKeyStrokes(String checker, String answer) { return errorCount; } - public double getErrorPercentage(){ - double percentage = (double)getErrorWordCount()/(double)getTotalWordTyped(); + public double getErrorPercentage() { + double percentage = (double) getErrorWordCount() / (double) getTotalWordTyped(); return percentage; } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 33c1e948d4..9951eddb96 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -135,7 +135,8 @@ public void showErrorSummary(int wrongWordCount, int totalWordCount, double sent out.println("Error rate: " + String.format("%.2f", sentenceErrorRate)); } - public void showSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) { + public void showSummary(int errorWordCount, double errorPercentage, double wpm, + int totalWordTyped, double gameTime) { out.print(SUMMARY + '\n'); out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index aa636d5fd3..a9382fc7ed 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -23,11 +23,11 @@ public void setUp() { @Test void showSummary() { TextUi textUi = new TextUi(); - String expected = SUMMARY + '\n' + - "Wrong Words: 5/10\n" + - "Error Percentage: 50.00%\n" + - "WPM: 40.08\n" + - "Total Time taken for the game: 10.07 seconds\n"; + String expected = SUMMARY + '\n' + + "Wrong Words: 5/10\n" + + "Error Percentage: 50.00%\n" + + "WPM: 40.08\n" + + "Total Time taken for the game: 10.07 seconds\n"; textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); From 9759d6fcc271d05e132af7850f88c7ae7bd2322d Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 18 Oct 2021 13:01:51 +0800 Subject: [PATCH 075/272] add UtilsTest --- .../java/seedu/typists/common/Messages.java | 31 +++++------------ src/main/java/seedu/typists/common/Utils.java | 4 ++- .../java/seedu/typists/game/TimeModeGame.java | 1 - src/test/java/seedu/DataProcessorTest.java | 14 ++++++++ src/test/java/seedu/TimeModeGameTest.java | 21 ++++++++++++ src/test/java/seedu/UtilsTest.java | 33 +++++++++++++++++++ 6 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 src/test/java/seedu/DataProcessorTest.java create mode 100644 src/test/java/seedu/TimeModeGameTest.java create mode 100644 src/test/java/seedu/UtilsTest.java diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index f8357c4c82..5a5e058b49 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -36,28 +36,13 @@ public class Messages { + " (__) ()__________)"; public static final String CLOCK = - " ,--.-----.--.\n" - + " |--|-----|--|\n" - + " |--| |--|\n" - + " | |-----| |\n" - + " __|--| |--|__\n" - + " / | |-----| | \\\n" - + " / \\__|-----|__/ \\\n" - + " / ______---______ \\/\\\n" - + " / / \\ \\/\n" - + "{ / _ _ _ \\ }\n" - + "| { | | . | | | | } |-,\n" - + "| | |_| . |_| |_| | | |\n" - + "| { } |-'\n" - + "{ \\ / }\n" - + " \\ `------___------' /\\\n" - + " \\ __|-----|__ /\\/\n" - + " \\ / |-----| \\ /\n" - + " \\ |--| |--| /\n" - + " --| |-----| |--\n" - + " |--| |--|\n" - + " |--|-----|--|\n" - + " `--'-----`--'"; + ".'`~~~~~~~~~~~`'.\n" + + "( .'11 12 1'. )\n" + + "| :10 \\| 2: |\n" + + "| :9 @ 3: |\n" + + "| :8 4; |\n" + + "'. '..7 6 5..' .'\n" + + " ~-------------~ "; public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; @@ -70,7 +55,7 @@ public class Messages { //This sample text is gotten from https://www.lipsum.com/ public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " - + "imply dummy text of the printing and typesetting industry ipum is simply dummy" + + "imply dummy text of the printing and typesetting industry ipum is simply dummy " + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + "industry industry industry industry industry industry industry industry industry industry industry " diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 0253f6d2ee..da0a22876a 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -20,7 +20,8 @@ public static ArrayList getWordLine(String text, int lineLength) { int j = 0; String[] line = new String[lineLength]; for (String w : wordList) { - if (j == lineLength) { + if (j == lineLength - 1) { + line[j] = w; wordLines.add(line.clone()); j = 0; } else { @@ -31,6 +32,7 @@ public static ArrayList getWordLine(String text, int lineLength) { return wordLines; } + /** same function as getWordLines, but the param is ArrayList not string. */ public static ArrayList getWordLineFromStringArray(ArrayList stringList) { ArrayList wordLines = new ArrayList<>(); for (String s : stringList) { diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 4e0e4f9f7f..5a1b54b48b 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -13,7 +13,6 @@ public class TimeModeGame extends Game { protected ArrayList inputLines; protected int gameTime; - protected int displayTime; protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { diff --git a/src/test/java/seedu/DataProcessorTest.java b/src/test/java/seedu/DataProcessorTest.java new file mode 100644 index 0000000000..59d58d9b1d --- /dev/null +++ b/src/test/java/seedu/DataProcessorTest.java @@ -0,0 +1,14 @@ +package seedu; + +import org.junit.jupiter.api.Test; +import seedu.typists.game.TimeModeGame; + +public class DataProcessorTest { + private static final String TEST_TXT = " testing testing testing"; + //name: whatIsBeingTested_descriptionOfTestInputs_expectedOutcome + + @Test + public void getTotalWordPerMinute_validTotalTime_success() { + + } +} diff --git a/src/test/java/seedu/TimeModeGameTest.java b/src/test/java/seedu/TimeModeGameTest.java new file mode 100644 index 0000000000..249258ed5a --- /dev/null +++ b/src/test/java/seedu/TimeModeGameTest.java @@ -0,0 +1,21 @@ +package seedu; + +import org.junit.jupiter.api.Test; +import seedu.typists.game.TimeModeGame; + +import java.util.ArrayList; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TimeModeGameTest { + private static final String TEXT_TXT = "this is test text"; + //name: whatIsBeingTested_descriptionOfTestInputs_expectedOutcome + + @Test + public void wordLines_sampleTxt_correct() { + //TimeModeGame g = new TimeModeGame(TEXT_TXT, 15); + //should get an error cause the text is not enough words + //need update + } +} diff --git a/src/test/java/seedu/UtilsTest.java b/src/test/java/seedu/UtilsTest.java new file mode 100644 index 0000000000..12dbe35c30 --- /dev/null +++ b/src/test/java/seedu/UtilsTest.java @@ -0,0 +1,33 @@ +package seedu; + +import org.junit.jupiter.api.Test; + +import static seedu.typists.common.Utils.getWordLine; +import static seedu.typists.common.Utils.splitStringIntoWordList; + +import java.util.ArrayList; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class UtilsTest { + private static final String SAMPLE = "this is test text here"; + //name: whatIsBeingTested_descriptionOfTestInputs_expectedOutcome + + @Test + public void splitStringIntoWordList_sampleTxt_success() { + ArrayList result = new ArrayList<>(Arrays.asList("this", "is", "test", "text", "here")); + assertEquals(result, splitStringIntoWordList(SAMPLE)); + } + + // this test is commented out + // because it will fail due to array address allocation + // but the result strings are identical + // @Test + //public void getWordLine_sampleTxt_success() { + // String[] a = new String[]{"this", "is"}; + // String[] b = new String[]{"test", "text"}; + // ArrayList result = new ArrayList<>(Arrays.asList(a,b)); + // assertEquals(result, getWordLine(SAMPLE, 2)); + // } +} From 2ac23b7e5ec60bf950491e5a79ee2e4db730274d Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Tue, 19 Oct 2021 01:30:26 +0800 Subject: [PATCH 076/272] Finished word-limited game mode - Add function to limit word - Now it display 5 words each time - Add some assert -Update the User Guide --- docs/UserGuide.md | 36 +++++--- docs/team/shizhansen.md | 1 + src/main/java/seedu/typists/Main.java | 22 ++--- .../java/seedu/typists/commands/NewGame.java | 47 ----------- .../java/seedu/typists/content/Content.java | 1 - .../typists/game/WordLimitDataProcessor.java | 51 +++++++++++ .../seedu/typists/game/WordLimitGame.java | 84 +++++++++++++++++++ .../seedu/typists/parser/StringParser.java | 1 + .../java/seedu/typists/parser/TextParser.java | 20 ----- src/main/java/seedu/typists/ui/TextUi.java | 9 +- .../ui/WordLimitDataProcessorTest.java | 18 ++++ 11 files changed, 197 insertions(+), 93 deletions(-) delete mode 100644 src/main/java/seedu/typists/commands/NewGame.java create mode 100644 src/main/java/seedu/typists/game/WordLimitDataProcessor.java create mode 100644 src/main/java/seedu/typists/game/WordLimitGame.java delete mode 100644 src/main/java/seedu/typists/parser/TextParser.java create mode 100644 src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..137a2ca486 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,24 +11,40 @@ 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). -## Features +### Usage +### Open Game -{Give detailed description of each feature} +### `Keyword` - Describe action -### Adding a todo: `todo` -Adds a new item to the list of todo items. +List of the keywords are shown below: -Format: `todo n/TODO_NAME d/DEADLINE` +`content`-Set the content -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. +`new`-Enter a word-limited game mode -Example of usage: +>Exit word-limited game mode command: `Exit` -`todo n/Write the rest of the User Guide d/next week` +`time`-Enter a time-limited game mode -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` +`error`-Enter a error detecting game mode +`bye`-Exit the program. + +## Example of usage: + +>`new` +``` +| Enter how many words you want the game to run: +``` +>`12` +``` +lorem ipsum is simply dummy +``` +>`lorem ipsum is simply dummy` +``` +Your progress:5/12 +text of the printing and +``` ## FAQ **Q**: How do I transfer my data to another computer? diff --git a/docs/team/shizhansen.md b/docs/team/shizhansen.md index 0d2004b781..b2689e648a 100644 --- a/docs/team/shizhansen.md +++ b/docs/team/shizhansen.md @@ -4,3 +4,4 @@ ### Summary of Contributions + diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b3b7b67c76..b75fadb7b2 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -7,7 +7,7 @@ import seedu.typists.parser.Parser; import seedu.typists.ui.TextUi; -import seedu.typists.commands.NewGame; +import seedu.typists.game.WordLimitGame; import seedu.typists.exception.FaultyInputException; import seedu.typists.exception.InvalidStringInputException; import seedu.typists.storage.StorageFile; @@ -24,7 +24,7 @@ public class Main { public static final int LINE_LENGTH = 10; TextUi uiBot; //Parser parseBot; - NewGame wordLimitGame; + WordLimitGame wordLimitGame; StorageFile storage; Content content; @@ -38,14 +38,10 @@ public void start() { uiBot.showWelcomeMessage(VERSION); } - public void startWordLimitGame() { + public void startWordLimitGame() throws InvalidStringInputException { uiBot.printKeyboard(); - this.wordLimitGame = new NewGame(); - try { - wordLimitGame.beginNewGame(); - } catch (InvalidStringInputException e) { - //some error msg, @zhansen - } + this.wordLimitGame = new WordLimitGame(content.getContent()); + wordLimitGame.beginNewGame(); } public void startTimeLimitGame() { @@ -60,7 +56,7 @@ public void startErrorGame() { ErrorGame a = new ErrorGame(content.getContent(), LINE_LENGTH); } - public void executeCommand(Parser c, NewGame game, StorageFile storage) { + public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException { switch (c.getCommand()) { case "content": content.setContent(); @@ -87,7 +83,7 @@ public void runCommandLoopUntilExitCommand() { String fullCommand = uiBot.readCommand(); Parser c = new Parser(fullCommand); c.parse(); - executeCommand(c, wordLimitGame, storage); + executeCommand(c, storage); isExit = c.getIsExit(); } catch (StringIndexOutOfBoundsException e) { uiBot.showText("OOPS!!! The description after this command word cannot be empty."); @@ -99,13 +95,17 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText(e.getMessage()); } catch (NoSuchElementException e) { e.printStackTrace(); + } catch (InvalidStringInputException e) { + e.printStackTrace(); } finally { uiBot.showLine(); } } + assert isExit : "isExit should be true"; } public void exit() { + uiBot.showBye(); } diff --git a/src/main/java/seedu/typists/commands/NewGame.java b/src/main/java/seedu/typists/commands/NewGame.java deleted file mode 100644 index 50500dad3c..0000000000 --- a/src/main/java/seedu/typists/commands/NewGame.java +++ /dev/null @@ -1,47 +0,0 @@ -package seedu.typists.commands; - -import seedu.typists.exception.FaultyInputException; -import seedu.typists.exception.InvalidStringInputException; -import seedu.typists.parser.Parser; -import seedu.typists.parser.TextParser; -import seedu.typists.ui.TextUi; - -import java.util.ArrayList; - -import static seedu.typists.parser.StringParser.splitString; - -public class NewGame { - - private ArrayList game1; - private int gameIndex; - TextUi uiGame; - - public NewGame() { - this.game1 = new ArrayList<>(100); - this.gameIndex = 0; - this.uiGame = new TextUi(); - } - - public int getTotalSentence() { - return game1.size(); - } - - public void beginNewGame() throws InvalidStringInputException { - String content1 = "The greatest glory in living lies not in never falling."; - game1 = splitString(content1," "); - uiGame.showText(content1); - boolean isExit = false; - while (!isExit) { - uiGame.showText(game1.get(gameIndex)); - String fullCommand = uiGame.readCommand(); - TextParser c = new TextParser(fullCommand, game1.get(gameIndex)); - isExit = c.getIsExit(); - gameIndex += 1; - uiGame.printGameMode1Progress(gameIndex,getTotalSentence()); - if (gameIndex == getTotalSentence()) { - uiGame.printSuccess(); - break; - } - } - } -} diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 0783df15b3..e428e48d1a 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -1,6 +1,5 @@ package seedu.typists.content; -import seedu.typists.exception.FaultyInputException; import seedu.typists.exception.InvalidArticleException; import seedu.typists.ui.TextUi; diff --git a/src/main/java/seedu/typists/game/WordLimitDataProcessor.java b/src/main/java/seedu/typists/game/WordLimitDataProcessor.java new file mode 100644 index 0000000000..1efd18b866 --- /dev/null +++ b/src/main/java/seedu/typists/game/WordLimitDataProcessor.java @@ -0,0 +1,51 @@ +package seedu.typists.game; + +import seedu.typists.exception.InvalidStringInputException; + +import java.util.ArrayList; + +import static seedu.typists.parser.StringParser.splitString; + +public class WordLimitDataProcessor { + protected String userInput; + protected String contentWords; + protected Boolean isExit; + + /** + * Ture if the 2 inputs are different. + * @param input one of inputs + * @param text another input + */ + public WordLimitDataProcessor(String input, String text) { + this.userInput = input; + this.contentWords = text; + this.isExit = !input.equals(text); + } + + /** + * Get exit. + * @return obtain the Exit status + */ + public Boolean getIsExit() { + return isExit; + } + + public int getError() throws InvalidStringInputException { + ArrayList userInput0 = splitString(userInput," "); + ArrayList contentWords0 = splitString(contentWords," "); + ArrayList list3 = new ArrayList(); + + for (int i = 0; i < contentWords0.size(); i++) { + for (int j = 0; j < userInput0.size(); j++) { + if (contentWords0.contains(userInput0.get(j))) { + if (contentWords0.get(i).equals(userInput0.get(j))) { + list3.add(contentWords0.get(i)); + } + } else { + break; + } + } + } + return contentWords0.size() - list3.size(); + } +} diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java new file mode 100644 index 0000000000..82761c2081 --- /dev/null +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -0,0 +1,84 @@ +package seedu.typists.game; + +import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.ui.TextUi; + +import java.util.ArrayList; +import java.util.Scanner; + +import static seedu.typists.parser.StringParser.splitString; + +public class WordLimitGame extends Game { + private final TextUi ui; + + private ArrayList eachWord; + protected int wordLimit; + private int gameIndex; + private final int numberOfWordsDisplayed; + private final String content1; + + + public WordLimitGame(String targetWordSet) { + this.eachWord = new ArrayList<>(100); + this.gameIndex = 0; + this.numberOfWordsDisplayed = 5; + this.ui = new TextUi(); + this.content1 = targetWordSet; + this.wordLimit = getWordLimit(); + } + + + public int getTotalSentence() { + return eachWord.size(); + } + + public int getWordLimit() { + Scanner in = new Scanner(System.in); + ui.printScreen("Enter how many words you want the game to run: "); + try { + return Integer.parseInt(in.nextLine()); + } catch (NumberFormatException e) { + System.out.println("Not a Number!"); + return getWordLimit(); + } + } + + public void trimContent(int wordLimit) throws InvalidStringInputException { + eachWord = splitString(content1," "); + eachWord = new ArrayList(eachWord.subList(0, wordLimit)); + } + + public void beginNewGame() throws InvalidStringInputException { + trimContent(wordLimit); + boolean isExit = false; + int totalError = 0; + while (!isExit) { + assert gameIndex < getTotalSentence() : "There are still texts to be typed."; + String temp = ""; + int number = 0; + while (gameIndex < getTotalSentence()) { + temp += eachWord.get(gameIndex) + " "; + gameIndex += 1; + number += 1; + if (number >= numberOfWordsDisplayed) { + break; + } + } + temp = temp.trim(); + ui.showText(temp); + String fullCommand = ui.readCommand(); + if (fullCommand.equals("Exit")) { + ui.showWordLimitSummary(totalError, gameIndex); + break; + } + WordLimitDataProcessor recordError = new WordLimitDataProcessor(fullCommand, temp); + totalError += recordError.getError(); + //isExit = recordError.getIsExit(); + ui.printGameMode1Progress(gameIndex,getTotalSentence()); + if (gameIndex >= getTotalSentence()) { + ui.showWordLimitSummary(totalError,getTotalSentence()); + break; + } + } + } +} diff --git a/src/main/java/seedu/typists/parser/StringParser.java b/src/main/java/seedu/typists/parser/StringParser.java index 3743df093d..085e71fe77 100644 --- a/src/main/java/seedu/typists/parser/StringParser.java +++ b/src/main/java/seedu/typists/parser/StringParser.java @@ -24,4 +24,5 @@ public static ArrayList splitString(String s, String separator) throws I return stringParts; } + } \ No newline at end of file diff --git a/src/main/java/seedu/typists/parser/TextParser.java b/src/main/java/seedu/typists/parser/TextParser.java deleted file mode 100644 index 676bead072..0000000000 --- a/src/main/java/seedu/typists/parser/TextParser.java +++ /dev/null @@ -1,20 +0,0 @@ -package seedu.typists.parser; - -public class TextParser { - protected String input; - protected Boolean isExit; - - - public TextParser(String input, String text) { - this.input = input; - this.isExit = !input.equals(text); - } - - /** - * Get exit. - * @return obtain the Exit status - */ - public Boolean getIsExit() { - return isExit; - } -} diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 9951eddb96..8144422d17 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -94,10 +94,6 @@ public void printGameMode1Progress(int a, int b) { System.out.println("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } - public void printSuccess() { - System.out.println("Finished!"); - } - public void printKeyboard() { out.println(KEYBOARD); } @@ -135,6 +131,11 @@ public void showErrorSummary(int wrongWordCount, int totalWordCount, double sent out.println("Error rate: " + String.format("%.2f", sentenceErrorRate)); } + public void showWordLimitSummary(int errorWordCount, int totalWordTyped) { + out.print(SUMMARY + '\n'); + out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + } + public void showSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) { out.print(SUMMARY + '\n'); diff --git a/src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java b/src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java new file mode 100644 index 0000000000..591b5b38c4 --- /dev/null +++ b/src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java @@ -0,0 +1,18 @@ +package seedu.typists.ui; + +import org.junit.jupiter.api.Test; +import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.game.WordLimitDataProcessor; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WordLimitDataProcessorTest { + + @Test + void getError_expect1() throws InvalidStringInputException { + String a = "Equal Or Not"; + String b = "Equal Or Not?"; + WordLimitDataProcessor c = new WordLimitDataProcessor(a, b); + assertEquals(1,c.getError()); + } +} From a37d484df8b786d366ec2fcc4dae215afa7d1eb2 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 20 Oct 2021 19:13:44 +0800 Subject: [PATCH 077/272] Some animation --- src/main/java/seedu/typists/Main.java | 3 +- .../java/seedu/typists/content/Animation.java | 102 ++++++++++++++++++ .../java/seedu/typists/content/Content.java | 2 +- .../java/seedu/typists/game/ErrorGame.java | 37 +++++-- 4 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 src/main/java/seedu/typists/content/Animation.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b75fadb7b2..031aa3e633 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -105,7 +105,6 @@ public void runCommandLoopUntilExitCommand() { } public void exit() { - uiBot.showBye(); } @@ -121,7 +120,7 @@ public void run() { /** * Main entry-point for the java.duke.Duke application. */ - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { new Main().run(); } } diff --git a/src/main/java/seedu/typists/content/Animation.java b/src/main/java/seedu/typists/content/Animation.java new file mode 100644 index 0000000000..392b865495 --- /dev/null +++ b/src/main/java/seedu/typists/content/Animation.java @@ -0,0 +1,102 @@ +package seedu.typists.content; + +public class Animation { + private String lastLine = ""; + + public void print(String line) { + //clear the last line if longer + if (lastLine.length() > line.length()) { + String temp = ""; + for (int i = 0; i < lastLine.length(); i++) { + temp += " "; + } + if (temp.length() > 1) + System.out.print("\r" + temp); + } + System.out.print("\r" + line); + lastLine = line; + } + + private byte animWait; + + public void resetAnimWait() { + animWait = 1; + } + + public void animateWait(String s) { + switch (animWait) { + case 1: + print("[ \\ ] " + s); + break; + case 2: + print("[ | ] " + s); + break; + case 3: + print("[ / ] " + s); + break; + default: + animWait = 0; + print("[ - ] " + s); + } + animWait++; + } + + private byte animLeft; + private byte animRight; + + public void resetAnimLeft() { + animLeft = 1; + } + public void resetAnimRight() { + animRight = 1; + } + + public void animateLeft(String s) { + switch (animLeft) { + case 1: + print(" | " + s); + break; + case 2: + print(" | " + s); + break; + case 3: + print(" | " + s); + break; + case 4: + print(" | " + s); + break; + case 5: + print(" | " + s); + break; + default: + animLeft = 0; + print("| " + s); + } + animLeft++; + } + + public void animateRight(String s) { + switch (animRight) { + case 1: + print("| " + s); + break; + case 2: + print(" | " + s); + break; + case 3: + print(" | " + s); + break; + case 4: + print(" | " + s); + break; + case 5: + print(" | " + s); + break; + default: + animRight = 0; + print(" | " + s); + } + animRight++; + } + +} diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index e428e48d1a..38463bc820 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -120,7 +120,7 @@ private void setRandomContent() { s += (rg.randomString(r.nextInt(10) + 5) + " "); } this.content = s; - ui.showText("Content set " + this.content); + ui.showText("Content set"); } } } diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java index 5da24716e3..3cfd59585d 100644 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -1,5 +1,6 @@ package seedu.typists.game; +import seedu.typists.content.Animation; import seedu.typists.ui.TextUi; import java.util.ArrayList; import java.util.Scanner; @@ -16,31 +17,47 @@ public ErrorGame(String targetWordSet, int wordsPerLine) { ui = new TextUi(); inputLines = new ArrayList<>(); wordLines = getWordLine(targetWordSet, wordsPerLine); - startGame(); + try { + startGame(); + } catch (InterruptedException e) { + e.printStackTrace(); + } } public boolean readyToStartGame() { Scanner in = new Scanner(System.in); String command = ""; while (!command.equals("yes")) { - ui.printScreen("Do you want to start now?"); + ui.printScreen("Do you want to start now? (enter !bye to quit the game at any time)"); command = in.nextLine(); } return true; } - public void startGame() { + public void startGame() throws InterruptedException { if (readyToStartGame()) { + String userInput = ""; + Scanner in = new Scanner(System.in); for (int i = 0; i < wordLines.size(); i++) { ui.printLine(wordLines.get(i)); + userInput = in.nextLine(); + if (userInput.equals("!bye")) { + break; + } + else { + inputLines.add(userInput); + Animation animation = new Animation(); + animation.resetAnimLeft(); + int k = 0; + while (k < 6) { + animation.animateLeft("Line " + (i + 1) + " out of " + wordLines.size()); + Thread.sleep(300); + k++; + } + System.out.println(""); + } } + System.out.println("Game Finished."); } - Scanner in = new Scanner(System.in); - for (int i = 0; i < wordLines.size(); i++) { - String userInput = in.nextLine(); - inputLines.add(userInput); - i++; - } - System.out.println("Game Finished."); } } From efe3247837384cded47239d25467227f97a6254e Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 20 Oct 2021 19:20:50 +0800 Subject: [PATCH 078/272] Some animation --- .../java/seedu/typists/content/Animation.java | 63 ++++++++++--------- .../java/seedu/typists/game/ErrorGame.java | 3 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/main/java/seedu/typists/content/Animation.java b/src/main/java/seedu/typists/content/Animation.java index 392b865495..d8b41ae9a5 100644 --- a/src/main/java/seedu/typists/content/Animation.java +++ b/src/main/java/seedu/typists/content/Animation.java @@ -10,8 +10,9 @@ public void print(String line) { for (int i = 0; i < lastLine.length(); i++) { temp += " "; } - if (temp.length() > 1) + if (temp.length() > 1) { System.out.print("\r" + temp); + } } System.out.print("\r" + line); lastLine = line; @@ -25,18 +26,18 @@ public void resetAnimWait() { public void animateWait(String s) { switch (animWait) { - case 1: - print("[ \\ ] " + s); - break; - case 2: - print("[ | ] " + s); - break; - case 3: - print("[ / ] " + s); - break; - default: - animWait = 0; - print("[ - ] " + s); + case 1: + print("[ \\ ] " + s); + break; + case 2: + print("[ | ] " + s); + break; + case 3: + print("[ / ] " + s); + break; + default: + animWait = 0; + print("[ - ] " + s); } animWait++; } @@ -53,24 +54,24 @@ public void resetAnimRight() { public void animateLeft(String s) { switch (animLeft) { - case 1: - print(" | " + s); - break; - case 2: - print(" | " + s); - break; - case 3: - print(" | " + s); - break; - case 4: - print(" | " + s); - break; - case 5: - print(" | " + s); - break; - default: - animLeft = 0; - print("| " + s); + case 1: + print(" | " + s); + break; + case 2: + print(" | " + s); + break; + case 3: + print(" | " + s); + break; + case 4: + print(" | " + s); + break; + case 5: + print(" | " + s); + break; + default: + animLeft = 0; + print("| " + s); } animLeft++; } diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java index 3cfd59585d..795abf2160 100644 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -43,8 +43,7 @@ public void startGame() throws InterruptedException { userInput = in.nextLine(); if (userInput.equals("!bye")) { break; - } - else { + } else { inputLines.add(userInput); Animation animation = new Animation(); animation.resetAnimLeft(); From 7516aa51e4b72d73ed9b4b2e5be9ab4870f93749 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 20 Oct 2021 19:22:48 +0800 Subject: [PATCH 079/272] Some animation --- .../java/seedu/typists/content/Animation.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/main/java/seedu/typists/content/Animation.java b/src/main/java/seedu/typists/content/Animation.java index d8b41ae9a5..7af8fe02f6 100644 --- a/src/main/java/seedu/typists/content/Animation.java +++ b/src/main/java/seedu/typists/content/Animation.java @@ -48,6 +48,7 @@ public void animateWait(String s) { public void resetAnimLeft() { animLeft = 1; } + public void resetAnimRight() { animRight = 1; } @@ -78,24 +79,24 @@ public void animateLeft(String s) { public void animateRight(String s) { switch (animRight) { - case 1: - print("| " + s); - break; - case 2: - print(" | " + s); - break; - case 3: - print(" | " + s); - break; - case 4: - print(" | " + s); - break; - case 5: - print(" | " + s); - break; - default: - animRight = 0; - print(" | " + s); + case 1: + print("| " + s); + break; + case 2: + print(" | " + s); + break; + case 3: + print(" | " + s); + break; + case 4: + print(" | " + s); + break; + case 5: + print(" | " + s); + break; + default: + animRight = 0; + print(" | " + s); } animRight++; } From 4b671e38f61ef562687cf6a3b80ef100e0c316b8 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 20 Oct 2021 23:13:56 +0800 Subject: [PATCH 080/272] add logging and assertion add some logging add some assertions create a method in dataprocessor that gets the list of wrong words user typed --- src/main/java/seedu/typists/Main.java | 17 +++++------ .../seedu/typists/game/DataProcessor.java | 29 +++++++++++++------ .../java/seedu/typists/game/TimeModeGame.java | 10 +++++-- .../java/seedu/typists/parser/Parser.java | 2 +- src/main/java/seedu/typists/ui/TextUi.java | 2 +- text-ui-test/EXPECTED.TXT | 6 ++-- 6 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b75fadb7b2..bf9491d827 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -48,8 +48,13 @@ public void startTimeLimitGame() { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), - p.getTotalWordTyped(), p.totalTime); + uiBot.showSummary( + p.getErrorWordCount(), + p.getErrorPercentage(), + p.getWordPerMinute(), + p.getTotalWordTyped(), + p.totalTime + ); } public void startErrorGame() { @@ -91,21 +96,15 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText("OOPS!!! It's out of range."); } catch (NumberFormatException e) { uiBot.showText("OOPS!!! Number not found. "); - } catch (FaultyInputException e) { - uiBot.showText(e.getMessage()); - } catch (NoSuchElementException e) { - e.printStackTrace(); - } catch (InvalidStringInputException e) { + } catch (NoSuchElementException | InvalidStringInputException e) { e.printStackTrace(); } finally { uiBot.showLine(); } } - assert isExit : "isExit should be true"; } public void exit() { - uiBot.showBye(); } diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 4b6498992c..f5dc2ab41f 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -1,23 +1,30 @@ package seedu.typists.game; import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.common.Utils.getWordLineFromStringArray; public class DataProcessor { - private final ArrayList checkerWordLines; - private final ArrayList userWordLines; + private static final Logger logger = Logger.getLogger("Foo"); + private final List checkerWordLines; + private final List userWordLines; public final double totalTime; + private final List errorWords; public DataProcessor(TimeModeGame tg) { this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); this.totalTime = tg.realGameTime; + this.errorWords = getErrorWords(); } - public int getErrorWordCount() { - int errorWordCount = 0; + /** Get the list of words that the user made mistakes on. */ + public List getErrorWords() { + List errorWords = new ArrayList<>(); int i = 0; for (String[] sa : userWordLines) { String[] checker = checkerWordLines.get(i); @@ -25,16 +32,21 @@ public int getErrorWordCount() { for (String s : checker) { try { if (!s.equals(sa[ii])) { - errorWordCount++; + errorWords.add(s); } } catch (ArrayIndexOutOfBoundsException e) { - errorWordCount++; + logger.log(Level.INFO, "word(s) missed during input."); } ii++; } i++; } - return errorWordCount; + return errorWords; + } + + /** Get the total number of wrong words typed.*/ + public int getErrorWordCount() { + return errorWords.size(); } public int getTotalWordTyped() { @@ -68,7 +80,6 @@ public int getLineWrongKeyStrokes(String checker, String answer) { } public double getErrorPercentage() { - double percentage = (double) getErrorWordCount() / (double) getTotalWordTyped(); - return percentage; + return (double) getErrorWordCount() / (double) getTotalWordTyped(); } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 5a1b54b48b..2727384b00 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -2,11 +2,14 @@ import java.util.ArrayList; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; import seedu.typists.ui.TextUi; import static seedu.typists.common.Utils.getWordLine; public class TimeModeGame extends Game { + private static final Logger logger = Logger.getLogger("Foo"); private final TextUi ui; protected final ArrayList wordLines; @@ -16,9 +19,10 @@ public class TimeModeGame extends Game { protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { - ui = new TextUi(); - inputLines = new ArrayList<>(); - wordLines = getWordLine(targetWordSet, wordsPerLine); + assert targetWordSet != null : "text passed into Time Game should not be null."; + this.ui = new TextUi(); + this.inputLines = new ArrayList<>(); + this.wordLines = getWordLine(targetWordSet, wordsPerLine); this.gameTime = getGameTime(); startGame(); } diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index fe0fde8255..0c0dd0f0a6 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -32,7 +32,7 @@ public Boolean getIsExit() { } - public void parse() throws FaultyInputException { + public void parse() { switch (input) { case "bye": isExit = true; diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 8144422d17..fd9bba3a0f 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -24,7 +24,7 @@ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "****************************************************************"; + private static final String DIVIDER = "==========================================================="; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 0f37c07d29..6922ea6ef4 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,5 +1,5 @@ | Typist - Version 1.0 - | **************************************************************** + | =========================================================== | ______ _ __ | /_ __/_ ______ (_)____/ /_ | / / / / / / __ \/ / ___/ __/ @@ -14,6 +14,6 @@ | time: start a new timer game | error: start a new error game | bye: exit typist - | **************************************************************** -**************************************************************** + | =========================================================== +=========================================================== Bye. Hope to see you again soon! From 4af09ada0230f45a70eedc6e63291c7ebe96078c Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 02:30:47 +0800 Subject: [PATCH 081/272] Incorporate animation and error, some fixes --- src/main/java/seedu/typists/Main.java | 22 ++---- src/main/java/seedu/typists/common/Error.java | 26 ++++--- .../java/seedu/typists/common/Messages.java | 1 - .../java/seedu/typists/content/Animation.java | 1 - .../java/seedu/typists/content/Content.java | 3 + .../java/seedu/typists/game/ErrorGame.java | 62 ---------------- .../seedu/typists/game/WordLimitGame.java | 25 +++++-- .../java/seedu/typists/parser/Parser.java | 4 - .../seedu/typists/storage/StorageFile.java | 1 - src/main/java/seedu/typists/ui/TextUi.java | 73 ++++++++++++++++--- 10 files changed, 111 insertions(+), 107 deletions(-) delete mode 100644 src/main/java/seedu/typists/game/ErrorGame.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 031aa3e633..b924e5221d 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,7 +1,6 @@ package seedu.typists; import seedu.typists.content.Content; -import seedu.typists.game.ErrorGame; import seedu.typists.game.DataProcessor; import seedu.typists.game.TimeModeGame; import seedu.typists.parser.Parser; @@ -38,25 +37,21 @@ public void start() { uiBot.showWelcomeMessage(VERSION); } - public void startWordLimitGame() throws InvalidStringInputException { + public void startWordLimitGame() throws InvalidStringInputException, InterruptedException { uiBot.printKeyboard(); this.wordLimitGame = new WordLimitGame(content.getContent()); wordLimitGame.beginNewGame(); } - public void startTimeLimitGame() { + public void startTimeLimitGame() throws InterruptedException { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), + uiBot.showAnimatedSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime); } - public void startErrorGame() { - ErrorGame a = new ErrorGame(content.getContent(), LINE_LENGTH); - } - - public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException { + public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException, InterruptedException { switch (c.getCommand()) { case "content": content.setContent(); @@ -67,9 +62,6 @@ public void executeCommand(Parser c, StorageFile storage) throws InvalidStringIn case "time": startTimeLimitGame(); break; - case "error": - startErrorGame(); - break; default: break; } @@ -97,6 +89,8 @@ public void runCommandLoopUntilExitCommand() { e.printStackTrace(); } catch (InvalidStringInputException e) { e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); } finally { uiBot.showLine(); } @@ -120,7 +114,7 @@ public void run() { /** * Main entry-point for the java.duke.Duke application. */ - public static void main(String[] args) throws InterruptedException { + public static void main(String[] args) { new Main().run(); } -} +} \ No newline at end of file diff --git a/src/main/java/seedu/typists/common/Error.java b/src/main/java/seedu/typists/common/Error.java index ae6d6aca6f..602c985157 100644 --- a/src/main/java/seedu/typists/common/Error.java +++ b/src/main/java/seedu/typists/common/Error.java @@ -1,7 +1,15 @@ package seedu.typists.common; +import seedu.typists.ui.TextUi; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.ArrayList; + import static java.lang.Math.abs; import static java.lang.Math.min; +import static java.lang.System.out; +import static seedu.typists.common.Messages.SUMMARY; /** * Error rate calculator. @@ -23,22 +31,22 @@ public double wordErrorRate(String word, String typed) { return (double) wordCharacterDifference(word, typed) / word.length(); } - public int sentenceLengthDifference(String[] content, String[] typed) { - return abs(content.length - typed.length); + public int sentenceLengthDifference(ArrayList content, ArrayList typed) { + return abs(content.size() - typed.size()); } - public double sentenceErrorRate(String[] content, String[] typed) { + public double sentenceErrorRate(ArrayList content, ArrayList typed) { double temp = 0.0; - for (int i = 0; i < min(content.length, typed.length); i++) { - temp += wordErrorRate(content[i], typed[i]); + for (int i = 0; i < min(content.size(), typed.size()); i++) { + temp += wordErrorRate(content.get(i), typed.get(i)); } - return temp / (double) min(content.length, typed.length); + return temp / (double) min(content.size(), typed.size()); } - public int wrongWordCount(String[] content, String[] typed) { + public int wrongWordCount(ArrayList content, ArrayList typed) { int temp = 0; - for (int i = 0; i < min(content.length, typed.length); i++) { - temp += (content[0].equals(content[1]) ? 1 : 0); + for (int i = 0; i < min(content.size(), typed.size()); i++) { + temp += (content.get(i).equals(typed.get(i)) ? 0 : 1); } return temp; } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 6da6fcb62b..923384f19e 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -57,7 +57,6 @@ public class Messages { + "content: set the content\n" + "new: start a new word game\n" + "time: start a new timer game\n" - + "error: start a new error game\n" + "bye: exit typist"; //This sample text is gotten from https://www.lipsum.com/ diff --git a/src/main/java/seedu/typists/content/Animation.java b/src/main/java/seedu/typists/content/Animation.java index 7af8fe02f6..392771156b 100644 --- a/src/main/java/seedu/typists/content/Animation.java +++ b/src/main/java/seedu/typists/content/Animation.java @@ -100,5 +100,4 @@ public void animateRight(String s) { } animRight++; } - } diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 38463bc820..024faef381 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -70,6 +70,7 @@ private void setBooks() { setContent(); } else { this.content = Books.getBook(selection - 1); + assert this.content.length() > 0; ui.showText("Content set"); } } @@ -90,6 +91,7 @@ private void setWikipedia() { String temp = wi.getArticle(title); articleNotFound = false; this.content = temp; + assert this.content.length() > 0; ui.showText("Content set"); } catch (InvalidArticleException e) { ui.showText(e.getMessage()); @@ -120,6 +122,7 @@ private void setRandomContent() { s += (rg.randomString(r.nextInt(10) + 5) + " "); } this.content = s; + assert this.content.length() > 0; ui.showText("Content set"); } } diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java deleted file mode 100644 index 795abf2160..0000000000 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ /dev/null @@ -1,62 +0,0 @@ -package seedu.typists.game; - -import seedu.typists.content.Animation; -import seedu.typists.ui.TextUi; -import java.util.ArrayList; -import java.util.Scanner; - -import static seedu.typists.common.Utils.getWordLine; - -public class ErrorGame extends Game { - private final TextUi ui; - - protected ArrayList inputLines; - protected final ArrayList wordLines; - - public ErrorGame(String targetWordSet, int wordsPerLine) { - ui = new TextUi(); - inputLines = new ArrayList<>(); - wordLines = getWordLine(targetWordSet, wordsPerLine); - try { - startGame(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public boolean readyToStartGame() { - Scanner in = new Scanner(System.in); - String command = ""; - while (!command.equals("yes")) { - ui.printScreen("Do you want to start now? (enter !bye to quit the game at any time)"); - command = in.nextLine(); - } - return true; - } - - public void startGame() throws InterruptedException { - if (readyToStartGame()) { - String userInput = ""; - Scanner in = new Scanner(System.in); - for (int i = 0; i < wordLines.size(); i++) { - ui.printLine(wordLines.get(i)); - userInput = in.nextLine(); - if (userInput.equals("!bye")) { - break; - } else { - inputLines.add(userInput); - Animation animation = new Animation(); - animation.resetAnimLeft(); - int k = 0; - while (k < 6) { - animation.animateLeft("Line " + (i + 1) + " out of " + wordLines.size()); - Thread.sleep(300); - k++; - } - System.out.println(""); - } - } - System.out.println("Game Finished."); - } - } -} diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 82761c2081..b9c131a5e3 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -1,5 +1,6 @@ package seedu.typists.game; +import seedu.typists.common.Error; import seedu.typists.exception.InvalidStringInputException; import seedu.typists.ui.TextUi; @@ -17,7 +18,6 @@ public class WordLimitGame extends Game { private final int numberOfWordsDisplayed; private final String content1; - public WordLimitGame(String targetWordSet) { this.eachWord = new ArrayList<>(100); this.gameIndex = 0; @@ -27,7 +27,6 @@ public WordLimitGame(String targetWordSet) { this.wordLimit = getWordLimit(); } - public int getTotalSentence() { return eachWord.size(); } @@ -35,6 +34,7 @@ public int getTotalSentence() { public int getWordLimit() { Scanner in = new Scanner(System.in); ui.printScreen("Enter how many words you want the game to run: "); + try { return Integer.parseInt(in.nextLine()); } catch (NumberFormatException e) { @@ -48,14 +48,19 @@ public void trimContent(int wordLimit) throws InvalidStringInputException { eachWord = new ArrayList(eachWord.subList(0, wordLimit)); } - public void beginNewGame() throws InvalidStringInputException { + public void beginNewGame() throws InvalidStringInputException, InterruptedException { trimContent(wordLimit); boolean isExit = false; int totalError = 0; + + String actualWord = ""; + String inputWord = ""; + while (!isExit) { assert gameIndex < getTotalSentence() : "There are still texts to be typed."; String temp = ""; int number = 0; + while (gameIndex < getTotalSentence()) { temp += eachWord.get(gameIndex) + " "; gameIndex += 1; @@ -64,19 +69,29 @@ public void beginNewGame() throws InvalidStringInputException { break; } } + + actualWord += temp; temp = temp.trim(); ui.showText(temp); String fullCommand = ui.readCommand(); + inputWord += fullCommand + " "; + if (fullCommand.equals("Exit")) { - ui.showWordLimitSummary(totalError, gameIndex); + ui.showAnimatedWordLimitSummary(totalError, gameIndex); break; } + WordLimitDataProcessor recordError = new WordLimitDataProcessor(fullCommand, temp); totalError += recordError.getError(); //isExit = recordError.getIsExit(); ui.printGameMode1Progress(gameIndex,getTotalSentence()); + if (gameIndex >= getTotalSentence()) { - ui.showWordLimitSummary(totalError,getTotalSentence()); + ui.showAnimatedError( + splitString(actualWord.trim()," "), + splitString(inputWord.trim()," "), + getTotalSentence() + ); break; } } diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java index fe0fde8255..8a3174b004 100644 --- a/src/main/java/seedu/typists/parser/Parser.java +++ b/src/main/java/seedu/typists/parser/Parser.java @@ -31,7 +31,6 @@ public Boolean getIsExit() { return isExit; } - public void parse() throws FaultyInputException { switch (input) { case "bye": @@ -44,9 +43,6 @@ public void parse() throws FaultyInputException { case "time": command = "time"; break; - case "error": - command = "error"; - break; case "content": command = "content"; break; diff --git a/src/main/java/seedu/typists/storage/StorageFile.java b/src/main/java/seedu/typists/storage/StorageFile.java index 18162de3fd..cd4c079efc 100644 --- a/src/main/java/seedu/typists/storage/StorageFile.java +++ b/src/main/java/seedu/typists/storage/StorageFile.java @@ -4,5 +4,4 @@ * Represents the file used to store Typing data. */ public class StorageFile { - } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 8144422d17..16719f1530 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,5 +1,10 @@ package seedu.typists.ui; +import seedu.typists.common.Error; +import seedu.typists.content.Animation; + +import java.math.BigDecimal; +import java.math.MathContext; import java.sql.Timestamp; import java.text.SimpleDateFormat; @@ -14,8 +19,7 @@ import static seedu.typists.common.Messages.MESSAGE_WELCOME; import static seedu.typists.common.Messages.SUMMARY; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Scanner; /** @@ -90,8 +94,8 @@ public void showBye() { System.out.println("Bye. Hope to see you again soon!"); } - public void printGameMode1Progress(int a, int b) { - System.out.println("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); + public void printGameMode1Progress(int a, int b) throws InterruptedException { + viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } public void printKeyboard() { @@ -126,16 +130,56 @@ public void printBookSelection() { + "15. The Adventures of Huckleberry Finn"); } - public void showErrorSummary(int wrongWordCount, int totalWordCount, double sentenceErrorRate) { - out.println("Wrong words: " + wrongWordCount + "/" + totalWordCount); - out.println("Error rate: " + String.format("%.2f", sentenceErrorRate)); + public void viewAnimateLeft(String string) throws InterruptedException { + Animation animation = new Animation(); + animation.resetAnimLeft(); + int k = 0; + while (k < 6) { + animation.animateLeft(string); + Thread.sleep(300); + k++; + } + System.out.println(""); } - public void showWordLimitSummary(int errorWordCount, int totalWordTyped) { - out.print(SUMMARY + '\n'); - out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + public void viewAnimateRight(String string) throws InterruptedException { + Animation animation = new Animation(); + animation.resetAnimRight(); + int k = 0; + while (k < 6) { + animation.animateRight(string); + Thread.sleep(300); + k++; + } + System.out.println(""); + } + + public void showAnimatedWordLimitSummary(int errorWordCount, int totalWordTyped) throws InterruptedException { + viewAnimateRight("Wrong Words: " + errorWordCount + "/" + totalWordTyped); + } + + public void showAnimatedSentenceErrorRateSummary(double sentenceErrorRate) throws InterruptedException { + viewAnimateRight("Sentence Error Rate: " + sentenceErrorRate); + } + + public void showAnimatedError(ArrayList content, ArrayList typed, int totalWord) throws InterruptedException { + TextUi ui = new TextUi(); + out.println(SUMMARY); + Error error = new Error(); + + ui.showAnimatedWordLimitSummary( + error.wrongWordCount(content, typed), + totalWord + ); + + double sentenceErrorRate = error.sentenceErrorRate(content, typed); + BigDecimal bd = new BigDecimal(sentenceErrorRate); + bd = bd.round(new MathContext(3)); + double rounded = bd.doubleValue(); + ui.showAnimatedSentenceErrorRateSummary(rounded); } + public void showSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) { out.print(SUMMARY + '\n'); @@ -144,4 +188,13 @@ public void showSummary(int errorWordCount, double errorPercentage, double wpm, out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } + + public void showAnimatedSummary(int errorWordCount, double errorPercentage, double wpm, + int totalWordTyped, double gameTime) throws InterruptedException { + out.print(SUMMARY + '\n'); + viewAnimateRight("Wrong Words: " + errorWordCount + "/" + totalWordTyped); + viewAnimateRight("Error Percentage: " + String.format("%.2f", errorPercentage)); + viewAnimateRight("WPM: " + String.format("%.2f", wpm)); + viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); + } } From 106d9d9cbfe52bf5154705d2dfdb69ea8248a657 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 02:32:32 +0800 Subject: [PATCH 082/272] Incorporate animation and error, some fixes --- src/main/java/seedu/typists/ui/TextUi.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 16719f1530..dde2a3253f 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -162,7 +162,10 @@ public void showAnimatedSentenceErrorRateSummary(double sentenceErrorRate) throw viewAnimateRight("Sentence Error Rate: " + sentenceErrorRate); } - public void showAnimatedError(ArrayList content, ArrayList typed, int totalWord) throws InterruptedException { + public void showAnimatedError(ArrayList content, + ArrayList typed, + int totalWord) + throws InterruptedException { TextUi ui = new TextUi(); out.println(SUMMARY); Error error = new Error(); From e3b5357823512f2bbc640d6714ca1d921571275b Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 02:34:49 +0800 Subject: [PATCH 083/272] Incorporate animation and error, some fixes --- text-ui-test/EXPECTED.TXT | 1 - 1 file changed, 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 0f37c07d29..c761eea04c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -12,7 +12,6 @@ | content: set the content | new: start a new word game | time: start a new timer game - | error: start a new error game | bye: exit typist | **************************************************************** **************************************************************** From 832c7f290f29544eca7eaa90d1403f0ec481aee4 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 02:40:42 +0800 Subject: [PATCH 084/272] Incorporate animation and error, some fixes --- src/main/java/seedu/typists/common/Error.java | 6 ------ src/main/java/seedu/typists/content/WikiImport.java | 1 + src/main/java/seedu/typists/game/WordLimitGame.java | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main/java/seedu/typists/common/Error.java b/src/main/java/seedu/typists/common/Error.java index 602c985157..93432ae250 100644 --- a/src/main/java/seedu/typists/common/Error.java +++ b/src/main/java/seedu/typists/common/Error.java @@ -1,15 +1,9 @@ package seedu.typists.common; -import seedu.typists.ui.TextUi; - -import java.math.BigDecimal; -import java.math.MathContext; import java.util.ArrayList; import static java.lang.Math.abs; import static java.lang.Math.min; -import static java.lang.System.out; -import static seedu.typists.common.Messages.SUMMARY; /** * Error rate calculator. diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java index e218b2aec0..b24b09d492 100644 --- a/src/main/java/seedu/typists/content/WikiImport.java +++ b/src/main/java/seedu/typists/content/WikiImport.java @@ -16,6 +16,7 @@ public String getArticle(String article) throws InvalidArticleException { if (temp.length() < 1) { throw new InvalidArticleException(); } + assert temp.length() > 1; return temp; } } diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index b9c131a5e3..1173b76f67 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -1,9 +1,7 @@ package seedu.typists.game; -import seedu.typists.common.Error; import seedu.typists.exception.InvalidStringInputException; import seedu.typists.ui.TextUi; - import java.util.ArrayList; import java.util.Scanner; From 8d881a68a939c91942f91273a6a038f93e465f16 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 03:01:19 +0800 Subject: [PATCH 085/272] UI fixes --- .../java/seedu/typists/content/Content.java | 34 +++++++++---------- .../seedu/typists/game/WordLimitGame.java | 2 +- src/main/java/seedu/typists/ui/TextUi.java | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index 024faef381..a3b730e50d 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -22,19 +22,19 @@ public String getContent() { public void setContent() { ui.printLetter(); - ui.showText("Content selection (input 0 to go back):\n" - + "1. Opening of famous books\n" - + "2. Wikipedia article\n" - + "3. Random sentence of custom length" - ); + ui.printLine("Content selection (input 0 to go back):"); + ui.printLine("1. Opening of famous books"); + ui.printLine("2. Wikipedia article"); + ui.printLine("3. Random sentence of custom length"); + Scanner in = new Scanner(System.in); int command = -1; do { - ui.showText("Enter your selection: "); + ui.printLine("Enter your selection: "); try { command = in.nextInt(); } catch (InputMismatchException e) { - ui.showText("Invalid selection."); + ui.printLine("Invalid selection."); in.nextLine(); } } while (command < 0 || command > 3); @@ -58,11 +58,11 @@ private void setBooks() { ui.printBookSelection(); int selection = -1; do { - ui.showText("Enter your selection:"); + ui.printLine("Enter your selection:"); try { selection = in.nextInt(); } catch (InputMismatchException e) { - ui.showText("Not an integer."); + ui.printLine("Not an integer."); in.nextLine(); } } while (selection < 0 || selection > 15); @@ -71,7 +71,7 @@ private void setBooks() { } else { this.content = Books.getBook(selection - 1); assert this.content.length() > 0; - ui.showText("Content set"); + ui.printLine("Content set"); } } @@ -81,7 +81,7 @@ private void setWikipedia() { String title; boolean articleNotFound = true; do { - ui.showText("Enter the article name (input 0 to go back):"); + ui.printLine("Enter the article name (input 0 to go back):"); title = in.nextLine(); if (title.equals("0")) { articleNotFound = false; @@ -92,9 +92,9 @@ private void setWikipedia() { articleNotFound = false; this.content = temp; assert this.content.length() > 0; - ui.showText("Content set"); + ui.printLine("Content set"); } catch (InvalidArticleException e) { - ui.showText(e.getMessage()); + ui.printLine(e.getMessage()); } } } while (articleNotFound); @@ -105,15 +105,15 @@ private void setRandomContent() { RandomGenerator rg = new RandomGenerator(); int length = -1; do { - ui.showText("Enter the word count (between 1 - 100, input 0 to go back):"); + ui.printLine("Enter the word count (between 5 - 100, input 0 to go back):"); try { length = in.nextInt(); } catch (InputMismatchException e) { - ui.showText("Invalid selection."); + ui.printLine("Invalid selection."); in.nextLine(); } } while (length < 0 || length > 100); - if (length == 0) { + if (length < 5) { setContent(); } else { String s = ""; @@ -123,7 +123,7 @@ private void setRandomContent() { } this.content = s; assert this.content.length() > 0; - ui.showText("Content set"); + ui.printLine("Content set"); } } } diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 1173b76f67..85c1110eb0 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -70,7 +70,7 @@ public void beginNewGame() throws InvalidStringInputException, InterruptedExcept actualWord += temp; temp = temp.trim(); - ui.showText(temp); + ui.printLine(temp); String fullCommand = ui.readCommand(); inputWord += fullCommand + " "; diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index dde2a3253f..d42f416e3c 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -111,7 +111,7 @@ public void printClock() { } public void printBookSelection() { - System.out.println("Input '0' to go back.\n" + printScreen("Input '0' to go back.\n" + "Content list:\n" + "1. A Confederacy of Dunces\n" + "2. Moby Dick\n" From faa9ac569cccd37769d9a035de0c16f808b847df Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 21 Oct 2021 06:33:32 +0800 Subject: [PATCH 086/272] Update UG and DG Update user guide for feature 'Showing summary of a game', update format of UG. Update 'acknowledgements' section in DG with link referenced. Fixes #50 --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..aa879ee413 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -3,7 +3,7 @@ ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} - +* https://www.baeldung.com/java-testing-system-out-println ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 137a2ca486..bb690c50bc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,9 +11,23 @@ 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). +## Features ### Usage ### Open Game +### {Feature name}: {`Keyword`} +Description of feature +Format: {format of command} +* Explanation 1 of format +* Explanation 2 of format + +Examples +* command example 1 +* command example 2 + + + + ### `Keyword` - Describe action List of the keywords are shown below: @@ -30,6 +44,9 @@ List of the keywords are shown below: `bye`-Exit the program. +### Showing summary of a game +Statistics of game is shown automatically after a game is finished. + ## Example of usage: >`new` From 37230d64b505ae574a8b19b799ad79e0a5b24903 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 21 Oct 2021 14:56:03 +0800 Subject: [PATCH 087/272] Enhance summary feature to show print error words Add functional code and the Junit tests for the enhancement. Add logger to TextUi. Add assertions to printErrorWords and ShowSummary. Add setUpLog method in TextUi. --- src/main/java/seedu/typists/Main.java | 1 + src/main/java/seedu/typists/ui/TextUi.java | 61 ++++++++++++++++++- .../java/seedu/typists/ui/TextUiTest.java | 49 ++++++++++++++- 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index bf9491d827..bd944064f4 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -51,6 +51,7 @@ public void startTimeLimitGame() { uiBot.showSummary( p.getErrorWordCount(), p.getErrorPercentage(), + p.getErrorWords(), p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index fd9bba3a0f..643e4ce144 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,5 +1,6 @@ package seedu.typists.ui; +import java.io.IOException; import java.sql.Timestamp; import java.text.SimpleDateFormat; @@ -16,7 +17,9 @@ import java.sql.Timestamp; import java.text.SimpleDateFormat; +import java.util.List; import java.util.Scanner; +import java.util.logging.*; /** * Text UI of the application. @@ -27,6 +30,7 @@ public class TextUi { private static final String DIVIDER = "==========================================================="; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); + private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); //get current timestamp //unused because it interferes with the EXPECTED.TXT in runtest @@ -136,12 +140,63 @@ public void showWordLimitSummary(int errorWordCount, int totalWordTyped) { out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); } - public void showSummary(int errorWordCount, double errorPercentage, double wpm, + public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, int totalWordTyped, double gameTime) { + assert errorWordCount >= 0; + assert errorPercentage >= 0; + assert totalWordTyped >= 0; + assert gameTime > 0; + assert wpm >= 0; + out.print(SUMMARY + '\n'); - out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("Number of Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + out.print("Error Percentage of Wrong Words: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("Wrong Words:\n"); + printErrorWords(errorWords); out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } + + void printErrorWords(List errorWords) { + setUpLog(); + if (errorWords == null) { + out.print("No words typed wrongly.\n"); + return; + } + for (int i = 0; i < errorWords.size(); i++) { + assert errorWords != null; + if (i != 0 && i % 8 == 0) { + out.print("\n"); + } + out.print(errorWords.get(i)); + if (i != (errorWords.size() - 1)) { + out.print("|"); + } + } + if ((errorWords.size() - 1) % 8 != 0) { + out.print("\n"); + } + } + + void setUpLog(){ + LogManager.getLogManager().reset(); + LOGGER.setLevel(Level.ALL); + + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.SEVERE); + LOGGER.addHandler(ch); + + try { + FileHandler fh = new FileHandler(TextUi.class.getName()+".log"); + fh.setFormatter(new SimpleFormatter()); + fh.setLevel(Level.FINE); + LOGGER.addHandler(fh); + } catch (IOException e) { + LOGGER.log(Level.SEVERE,"File logger failed to set up\n", e); + } + + LOGGER.info("Set up log in TextUi"); + + + } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index a9382fc7ed..e1a83807fa 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -6,6 +6,8 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.Arrays; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.typists.common.Messages.SUMMARY; @@ -24,11 +26,14 @@ public void setUp() { void showSummary() { TextUi textUi = new TextUi(); String expected = SUMMARY + '\n' - + "Wrong Words: 5/10\n" - + "Error Percentage: 50.00%\n" + + "Number of Wrong Words: 5/10\n" + + "Error Percentage of Wrong Words: 50.00%\n" + + "Wrong Words:\n" + + "foo|bar\n" + "WPM: 40.08\n" + "Total Time taken for the game: 10.07 seconds\n"; - textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); + + textUi.showSummary(5, 50.00000, java.util.Arrays.asList("foo", "bar"), 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); } @@ -37,4 +42,42 @@ void showSummary() { public void tearDown() { System.setOut(standardOut); } + + @Test + void printErrorWords_noErrorWords_noExceptionThrown() { + List errorWords = null; + String expected = "No words typed wrongly.\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_multipleOfEight() { + List errorWords = Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7", "bar8" + ); + String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7|bar8\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_notMultipleOfEight() { + List errorWords = Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7" + ); + String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } } \ No newline at end of file From 8d0a95c146c5b1db08e6797a27c0ddc2ab6f0e48 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 21 Oct 2021 14:57:18 +0800 Subject: [PATCH 088/272] Format code --- src/main/java/seedu/typists/ui/TextUi.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 643e4ce144..9cc224b778 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -178,7 +178,7 @@ void printErrorWords(List errorWords) { } } - void setUpLog(){ + void setUpLog() { LogManager.getLogManager().reset(); LOGGER.setLevel(Level.ALL); @@ -187,12 +187,12 @@ void setUpLog(){ LOGGER.addHandler(ch); try { - FileHandler fh = new FileHandler(TextUi.class.getName()+".log"); + FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); fh.setFormatter(new SimpleFormatter()); fh.setLevel(Level.FINE); LOGGER.addHandler(fh); } catch (IOException e) { - LOGGER.log(Level.SEVERE,"File logger failed to set up\n", e); + LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); } LOGGER.info("Set up log in TextUi"); From 1ad2a138c09128d71f897ff736e8a42f64569c7b Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 21 Oct 2021 15:00:58 +0800 Subject: [PATCH 089/272] Format code --- src/main/java/seedu/typists/ui/TextUi.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 9cc224b778..3fec0eacc9 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -19,7 +19,12 @@ import java.text.SimpleDateFormat; import java.util.List; import java.util.Scanner; -import java.util.logging.*; +import java.util.logging.Logger; +import java.util.logging.LogManager; +import java.util.logging.Level; +import java.util.logging.SimpleFormatter; +import java.util.logging.FileHandler; +import java.util.logging.ConsoleHandler; /** * Text UI of the application. From 40ce359073ca582b6545e418a3b8afd328f8d593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 18:40:54 +0800 Subject: [PATCH 090/272] Update TextUi.java --- src/main/java/seedu/typists/ui/TextUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index ba166eeb29..179b5327fa 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -236,7 +236,7 @@ void printErrorWords(List errorWords) { } } - void setUpLog() { + public void setUpLog() { LogManager.getLogManager().reset(); LOGGER.setLevel(Level.ALL); From f17c918a38114f3f9716289f76e9a9eee720750d Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:22:24 +0800 Subject: [PATCH 091/272] dhrtrth --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 17 ----- src/main/java/seedu/typists/Main.java | 17 +++-- .../seedu/typists/game/DataProcessor.java | 29 +++----- .../java/seedu/typists/game/TimeModeGame.java | 10 +-- src/main/java/seedu/typists/ui/TextUi.java | 71 +++---------------- .../java/seedu/typists/ui/TextUiTest.java | 49 +------------ text-ui-test/EXPECTED.TXT | 6 +- 8 files changed, 35 insertions(+), 166 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index aa879ee413..64e1f0ed2b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -3,7 +3,7 @@ ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} -* https://www.baeldung.com/java-testing-system-out-println + ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} diff --git a/docs/UserGuide.md b/docs/UserGuide.md index bb690c50bc..137a2ca486 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,23 +11,9 @@ 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). -## Features ### Usage ### Open Game -### {Feature name}: {`Keyword`} -Description of feature -Format: {format of command} -* Explanation 1 of format -* Explanation 2 of format - -Examples -* command example 1 -* command example 2 - - - - ### `Keyword` - Describe action List of the keywords are shown below: @@ -44,9 +30,6 @@ List of the keywords are shown below: `bye`-Exit the program. -### Showing summary of a game -Statistics of game is shown automatically after a game is finished. - ## Example of usage: >`new` diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index ebc147d9bd..b924e5221d 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -47,14 +47,8 @@ public void startTimeLimitGame() throws InterruptedException { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showSummary( - p.getErrorWordCount(), - p.getErrorPercentage(), - p.getErrorWords(), - p.getWordPerMinute(), - p.getTotalWordTyped(), - p.totalTime - ); + uiBot.showAnimatedSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), + p.getTotalWordTyped(), p.totalTime); } public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException, InterruptedException { @@ -89,7 +83,11 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText("OOPS!!! It's out of range."); } catch (NumberFormatException e) { uiBot.showText("OOPS!!! Number not found. "); - } catch (NoSuchElementException | InvalidStringInputException e) { + } catch (FaultyInputException e) { + uiBot.showText(e.getMessage()); + } catch (NoSuchElementException e) { + e.printStackTrace(); + } catch (InvalidStringInputException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); @@ -97,6 +95,7 @@ public void runCommandLoopUntilExitCommand() { uiBot.showLine(); } } + assert isExit : "isExit should be true"; } public void exit() { diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index f5dc2ab41f..4b6498992c 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -1,30 +1,23 @@ package seedu.typists.game; import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.common.Utils.getWordLineFromStringArray; public class DataProcessor { - private static final Logger logger = Logger.getLogger("Foo"); - private final List checkerWordLines; - private final List userWordLines; + private final ArrayList checkerWordLines; + private final ArrayList userWordLines; public final double totalTime; - private final List errorWords; public DataProcessor(TimeModeGame tg) { this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); this.totalTime = tg.realGameTime; - this.errorWords = getErrorWords(); } - /** Get the list of words that the user made mistakes on. */ - public List getErrorWords() { - List errorWords = new ArrayList<>(); + public int getErrorWordCount() { + int errorWordCount = 0; int i = 0; for (String[] sa : userWordLines) { String[] checker = checkerWordLines.get(i); @@ -32,21 +25,16 @@ public List getErrorWords() { for (String s : checker) { try { if (!s.equals(sa[ii])) { - errorWords.add(s); + errorWordCount++; } } catch (ArrayIndexOutOfBoundsException e) { - logger.log(Level.INFO, "word(s) missed during input."); + errorWordCount++; } ii++; } i++; } - return errorWords; - } - - /** Get the total number of wrong words typed.*/ - public int getErrorWordCount() { - return errorWords.size(); + return errorWordCount; } public int getTotalWordTyped() { @@ -80,6 +68,7 @@ public int getLineWrongKeyStrokes(String checker, String answer) { } public double getErrorPercentage() { - return (double) getErrorWordCount() / (double) getTotalWordTyped(); + double percentage = (double) getErrorWordCount() / (double) getTotalWordTyped(); + return percentage; } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 2727384b00..5a1b54b48b 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -2,14 +2,11 @@ import java.util.ArrayList; import java.util.Scanner; -import java.util.logging.Level; -import java.util.logging.Logger; import seedu.typists.ui.TextUi; import static seedu.typists.common.Utils.getWordLine; public class TimeModeGame extends Game { - private static final Logger logger = Logger.getLogger("Foo"); private final TextUi ui; protected final ArrayList wordLines; @@ -19,10 +16,9 @@ public class TimeModeGame extends Game { protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { - assert targetWordSet != null : "text passed into Time Game should not be null."; - this.ui = new TextUi(); - this.inputLines = new ArrayList<>(); - this.wordLines = getWordLine(targetWordSet, wordsPerLine); + ui = new TextUi(); + inputLines = new ArrayList<>(); + wordLines = getWordLine(targetWordSet, wordsPerLine); this.gameTime = getGameTime(); startGame(); } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 179b5327fa..d42f416e3c 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -2,11 +2,12 @@ import seedu.typists.common.Error; import seedu.typists.content.Animation; + import java.math.BigDecimal; import java.math.MathContext; -import java.io.IOException; import java.sql.Timestamp; import java.text.SimpleDateFormat; + import static java.lang.System.lineSeparator; import static java.lang.System.out; import static seedu.typists.common.Messages.CLOCK; @@ -17,17 +18,9 @@ import static seedu.typists.common.Messages.MESSAGE_HELP; import static seedu.typists.common.Messages.MESSAGE_WELCOME; import static seedu.typists.common.Messages.SUMMARY; + import java.util.ArrayList; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.List; import java.util.Scanner; -import java.util.logging.Logger; -import java.util.logging.LogManager; -import java.util.logging.Level; -import java.util.logging.SimpleFormatter; -import java.util.logging.FileHandler; -import java.util.logging.ConsoleHandler; /** * Text UI of the application. @@ -35,10 +28,9 @@ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "==========================================================="; + private static final String DIVIDER = "****************************************************************"; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); - private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); //get current timestamp //unused because it interferes with the EXPECTED.TXT in runtest @@ -190,19 +182,12 @@ public void showAnimatedError(ArrayList content, ui.showAnimatedSentenceErrorRateSummary(rounded); } - public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, - int totalWordTyped, double gameTime) { - assert errorWordCount >= 0; - assert errorPercentage >= 0; - assert totalWordTyped >= 0; - assert gameTime > 0; - assert wpm >= 0; + public void showSummary(int errorWordCount, double errorPercentage, double wpm, + int totalWordTyped, double gameTime) { out.print(SUMMARY + '\n'); - out.print("Number of Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage of Wrong Words: " + String.format("%.2f", errorPercentage) + "%\n"); - out.print("Wrong Words:\n"); - printErrorWords(errorWords); + out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } @@ -214,45 +199,5 @@ public void showAnimatedSummary(int errorWordCount, double errorPercentage, doub viewAnimateRight("Error Percentage: " + String.format("%.2f", errorPercentage)); viewAnimateRight("WPM: " + String.format("%.2f", wpm)); viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); - - void printErrorWords(List errorWords) { - setUpLog(); - if (errorWords == null) { - out.print("No words typed wrongly.\n"); - return; - } - for (int i = 0; i < errorWords.size(); i++) { - assert errorWords != null; - if (i != 0 && i % 8 == 0) { - out.print("\n"); - } - out.print(errorWords.get(i)); - if (i != (errorWords.size() - 1)) { - out.print("|"); - } - } - if ((errorWords.size() - 1) % 8 != 0) { - out.print("\n"); - } - } - - public void setUpLog() { - LogManager.getLogManager().reset(); - LOGGER.setLevel(Level.ALL); - - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.SEVERE); - LOGGER.addHandler(ch); - - try { - FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); - fh.setFormatter(new SimpleFormatter()); - fh.setLevel(Level.FINE); - LOGGER.addHandler(fh); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); - } - - LOGGER.info("Set up log in TextUi"); } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index e1a83807fa..a9382fc7ed 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -6,8 +6,6 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import java.util.Arrays; -import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.typists.common.Messages.SUMMARY; @@ -26,14 +24,11 @@ public void setUp() { void showSummary() { TextUi textUi = new TextUi(); String expected = SUMMARY + '\n' - + "Number of Wrong Words: 5/10\n" - + "Error Percentage of Wrong Words: 50.00%\n" - + "Wrong Words:\n" - + "foo|bar\n" + + "Wrong Words: 5/10\n" + + "Error Percentage: 50.00%\n" + "WPM: 40.08\n" + "Total Time taken for the game: 10.07 seconds\n"; - - textUi.showSummary(5, 50.00000, java.util.Arrays.asList("foo", "bar"), 40.08, 10, 10.07); + textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); } @@ -42,42 +37,4 @@ void showSummary() { public void tearDown() { System.setOut(standardOut); } - - @Test - void printErrorWords_noErrorWords_noExceptionThrown() { - List errorWords = null; - String expected = "No words typed wrongly.\n"; - TextUi textUi = new TextUi(); - textUi.printErrorWords(errorWords); - String actual = outputStreamCaptor.toString(); - assertEquals(expected, actual); - } - - @Test - void printErrorWords_multipleOfEight() { - List errorWords = Arrays.asList( - "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", - "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7", "bar8" - ); - String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" - + "bar1|bar2|bar3|bar4|bar5|bar6|bar7|bar8\n"; - TextUi textUi = new TextUi(); - textUi.printErrorWords(errorWords); - String actual = outputStreamCaptor.toString(); - assertEquals(expected, actual); - } - - @Test - void printErrorWords_notMultipleOfEight() { - List errorWords = Arrays.asList( - "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", - "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7" - ); - String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" - + "bar1|bar2|bar3|bar4|bar5|bar6|bar7\n"; - TextUi textUi = new TextUi(); - textUi.printErrorWords(errorWords); - String actual = outputStreamCaptor.toString(); - assertEquals(expected, actual); - } } \ No newline at end of file diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 26a71e2579..c761eea04c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,5 +1,5 @@ | Typist - Version 1.0 - | =========================================================== + | **************************************************************** | ______ _ __ | /_ __/_ ______ (_)____/ /_ | / / / / / / __ \/ / ___/ __/ @@ -13,6 +13,6 @@ | new: start a new word game | time: start a new timer game | bye: exit typist - | =========================================================== -=========================================================== + | **************************************************************** +**************************************************************** Bye. Hope to see you again soon! From f0f8e084b40f3a1984510934bccc1873a628f77c Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:22:36 +0800 Subject: [PATCH 092/272] Revert "dhrtrth" This reverts commit f17c918a38114f3f9716289f76e9a9eee720750d. --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 17 +++++ src/main/java/seedu/typists/Main.java | 17 ++--- .../seedu/typists/game/DataProcessor.java | 29 +++++--- .../java/seedu/typists/game/TimeModeGame.java | 10 ++- src/main/java/seedu/typists/ui/TextUi.java | 71 ++++++++++++++++--- .../java/seedu/typists/ui/TextUiTest.java | 49 ++++++++++++- text-ui-test/EXPECTED.TXT | 6 +- 8 files changed, 166 insertions(+), 35 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..aa879ee413 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -3,7 +3,7 @@ ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} - +* https://www.baeldung.com/java-testing-system-out-println ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 137a2ca486..bb690c50bc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,9 +11,23 @@ 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). +## Features ### Usage ### Open Game +### {Feature name}: {`Keyword`} +Description of feature +Format: {format of command} +* Explanation 1 of format +* Explanation 2 of format + +Examples +* command example 1 +* command example 2 + + + + ### `Keyword` - Describe action List of the keywords are shown below: @@ -30,6 +44,9 @@ List of the keywords are shown below: `bye`-Exit the program. +### Showing summary of a game +Statistics of game is shown automatically after a game is finished. + ## Example of usage: >`new` diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b924e5221d..ebc147d9bd 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -47,8 +47,14 @@ public void startTimeLimitGame() throws InterruptedException { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showAnimatedSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), - p.getTotalWordTyped(), p.totalTime); + uiBot.showSummary( + p.getErrorWordCount(), + p.getErrorPercentage(), + p.getErrorWords(), + p.getWordPerMinute(), + p.getTotalWordTyped(), + p.totalTime + ); } public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException, InterruptedException { @@ -83,11 +89,7 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText("OOPS!!! It's out of range."); } catch (NumberFormatException e) { uiBot.showText("OOPS!!! Number not found. "); - } catch (FaultyInputException e) { - uiBot.showText(e.getMessage()); - } catch (NoSuchElementException e) { - e.printStackTrace(); - } catch (InvalidStringInputException e) { + } catch (NoSuchElementException | InvalidStringInputException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); @@ -95,7 +97,6 @@ public void runCommandLoopUntilExitCommand() { uiBot.showLine(); } } - assert isExit : "isExit should be true"; } public void exit() { diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 4b6498992c..f5dc2ab41f 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -1,23 +1,30 @@ package seedu.typists.game; import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.common.Utils.getWordLineFromStringArray; public class DataProcessor { - private final ArrayList checkerWordLines; - private final ArrayList userWordLines; + private static final Logger logger = Logger.getLogger("Foo"); + private final List checkerWordLines; + private final List userWordLines; public final double totalTime; + private final List errorWords; public DataProcessor(TimeModeGame tg) { this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); this.totalTime = tg.realGameTime; + this.errorWords = getErrorWords(); } - public int getErrorWordCount() { - int errorWordCount = 0; + /** Get the list of words that the user made mistakes on. */ + public List getErrorWords() { + List errorWords = new ArrayList<>(); int i = 0; for (String[] sa : userWordLines) { String[] checker = checkerWordLines.get(i); @@ -25,16 +32,21 @@ public int getErrorWordCount() { for (String s : checker) { try { if (!s.equals(sa[ii])) { - errorWordCount++; + errorWords.add(s); } } catch (ArrayIndexOutOfBoundsException e) { - errorWordCount++; + logger.log(Level.INFO, "word(s) missed during input."); } ii++; } i++; } - return errorWordCount; + return errorWords; + } + + /** Get the total number of wrong words typed.*/ + public int getErrorWordCount() { + return errorWords.size(); } public int getTotalWordTyped() { @@ -68,7 +80,6 @@ public int getLineWrongKeyStrokes(String checker, String answer) { } public double getErrorPercentage() { - double percentage = (double) getErrorWordCount() / (double) getTotalWordTyped(); - return percentage; + return (double) getErrorWordCount() / (double) getTotalWordTyped(); } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 5a1b54b48b..2727384b00 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -2,11 +2,14 @@ import java.util.ArrayList; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; import seedu.typists.ui.TextUi; import static seedu.typists.common.Utils.getWordLine; public class TimeModeGame extends Game { + private static final Logger logger = Logger.getLogger("Foo"); private final TextUi ui; protected final ArrayList wordLines; @@ -16,9 +19,10 @@ public class TimeModeGame extends Game { protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { - ui = new TextUi(); - inputLines = new ArrayList<>(); - wordLines = getWordLine(targetWordSet, wordsPerLine); + assert targetWordSet != null : "text passed into Time Game should not be null."; + this.ui = new TextUi(); + this.inputLines = new ArrayList<>(); + this.wordLines = getWordLine(targetWordSet, wordsPerLine); this.gameTime = getGameTime(); startGame(); } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index d42f416e3c..179b5327fa 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -2,12 +2,11 @@ import seedu.typists.common.Error; import seedu.typists.content.Animation; - import java.math.BigDecimal; import java.math.MathContext; +import java.io.IOException; import java.sql.Timestamp; import java.text.SimpleDateFormat; - import static java.lang.System.lineSeparator; import static java.lang.System.out; import static seedu.typists.common.Messages.CLOCK; @@ -18,9 +17,17 @@ import static seedu.typists.common.Messages.MESSAGE_HELP; import static seedu.typists.common.Messages.MESSAGE_WELCOME; import static seedu.typists.common.Messages.SUMMARY; - import java.util.ArrayList; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.List; import java.util.Scanner; +import java.util.logging.Logger; +import java.util.logging.LogManager; +import java.util.logging.Level; +import java.util.logging.SimpleFormatter; +import java.util.logging.FileHandler; +import java.util.logging.ConsoleHandler; /** * Text UI of the application. @@ -28,9 +35,10 @@ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "****************************************************************"; + private static final String DIVIDER = "==========================================================="; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); + private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); //get current timestamp //unused because it interferes with the EXPECTED.TXT in runtest @@ -182,12 +190,19 @@ public void showAnimatedError(ArrayList content, ui.showAnimatedSentenceErrorRateSummary(rounded); } - - public void showSummary(int errorWordCount, double errorPercentage, double wpm, + public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, int totalWordTyped, double gameTime) { + assert errorWordCount >= 0; + assert errorPercentage >= 0; + assert totalWordTyped >= 0; + assert gameTime > 0; + assert wpm >= 0; + out.print(SUMMARY + '\n'); - out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("Number of Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + out.print("Error Percentage of Wrong Words: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("Wrong Words:\n"); + printErrorWords(errorWords); out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } @@ -199,5 +214,45 @@ public void showAnimatedSummary(int errorWordCount, double errorPercentage, doub viewAnimateRight("Error Percentage: " + String.format("%.2f", errorPercentage)); viewAnimateRight("WPM: " + String.format("%.2f", wpm)); viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); + + void printErrorWords(List errorWords) { + setUpLog(); + if (errorWords == null) { + out.print("No words typed wrongly.\n"); + return; + } + for (int i = 0; i < errorWords.size(); i++) { + assert errorWords != null; + if (i != 0 && i % 8 == 0) { + out.print("\n"); + } + out.print(errorWords.get(i)); + if (i != (errorWords.size() - 1)) { + out.print("|"); + } + } + if ((errorWords.size() - 1) % 8 != 0) { + out.print("\n"); + } + } + + public void setUpLog() { + LogManager.getLogManager().reset(); + LOGGER.setLevel(Level.ALL); + + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.SEVERE); + LOGGER.addHandler(ch); + + try { + FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); + fh.setFormatter(new SimpleFormatter()); + fh.setLevel(Level.FINE); + LOGGER.addHandler(fh); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); + } + + LOGGER.info("Set up log in TextUi"); } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index a9382fc7ed..e1a83807fa 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -6,6 +6,8 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.Arrays; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.typists.common.Messages.SUMMARY; @@ -24,11 +26,14 @@ public void setUp() { void showSummary() { TextUi textUi = new TextUi(); String expected = SUMMARY + '\n' - + "Wrong Words: 5/10\n" - + "Error Percentage: 50.00%\n" + + "Number of Wrong Words: 5/10\n" + + "Error Percentage of Wrong Words: 50.00%\n" + + "Wrong Words:\n" + + "foo|bar\n" + "WPM: 40.08\n" + "Total Time taken for the game: 10.07 seconds\n"; - textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); + + textUi.showSummary(5, 50.00000, java.util.Arrays.asList("foo", "bar"), 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); } @@ -37,4 +42,42 @@ void showSummary() { public void tearDown() { System.setOut(standardOut); } + + @Test + void printErrorWords_noErrorWords_noExceptionThrown() { + List errorWords = null; + String expected = "No words typed wrongly.\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_multipleOfEight() { + List errorWords = Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7", "bar8" + ); + String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7|bar8\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_notMultipleOfEight() { + List errorWords = Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7" + ); + String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } } \ No newline at end of file diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index c761eea04c..26a71e2579 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,5 +1,5 @@ | Typist - Version 1.0 - | **************************************************************** + | =========================================================== | ______ _ __ | /_ __/_ ______ (_)____/ /_ | / / / / / / __ \/ / ___/ __/ @@ -13,6 +13,6 @@ | new: start a new word game | time: start a new timer game | bye: exit typist - | **************************************************************** -**************************************************************** + | =========================================================== +=========================================================== Bye. Hope to see you again soon! From 1922aa6ea837f9aea915e59364bc4e305056d458 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:22:40 +0800 Subject: [PATCH 093/272] Revert "Update TextUi.java" This reverts commit 40ce359073ca582b6545e418a3b8afd328f8d593. --- src/main/java/seedu/typists/ui/TextUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 179b5327fa..ba166eeb29 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -236,7 +236,7 @@ void printErrorWords(List errorWords) { } } - public void setUpLog() { + void setUpLog() { LogManager.getLogManager().reset(); LOGGER.setLevel(Level.ALL); From 11db19fcbd213748473ef7089a398fc47e55f799 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:22:44 +0800 Subject: [PATCH 094/272] Revert "Merge branch 'master' into master" This reverts commit b1b0854b9b8a876890155e4059465157f2934316, reversing changes made to 8d881a68a939c91942f91273a6a038f93e465f16. --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 17 ----- src/main/java/seedu/typists/Main.java | 17 +++-- .../seedu/typists/game/DataProcessor.java | 29 +++----- .../java/seedu/typists/game/TimeModeGame.java | 10 +-- src/main/java/seedu/typists/ui/TextUi.java | 71 +++---------------- .../java/seedu/typists/ui/TextUiTest.java | 49 +------------ text-ui-test/EXPECTED.TXT | 6 +- 8 files changed, 35 insertions(+), 166 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index aa879ee413..64e1f0ed2b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -3,7 +3,7 @@ ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} -* https://www.baeldung.com/java-testing-system-out-println + ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} diff --git a/docs/UserGuide.md b/docs/UserGuide.md index bb690c50bc..137a2ca486 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,23 +11,9 @@ 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). -## Features ### Usage ### Open Game -### {Feature name}: {`Keyword`} -Description of feature -Format: {format of command} -* Explanation 1 of format -* Explanation 2 of format - -Examples -* command example 1 -* command example 2 - - - - ### `Keyword` - Describe action List of the keywords are shown below: @@ -44,9 +30,6 @@ List of the keywords are shown below: `bye`-Exit the program. -### Showing summary of a game -Statistics of game is shown automatically after a game is finished. - ## Example of usage: >`new` diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index ebc147d9bd..b924e5221d 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -47,14 +47,8 @@ public void startTimeLimitGame() throws InterruptedException { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showSummary( - p.getErrorWordCount(), - p.getErrorPercentage(), - p.getErrorWords(), - p.getWordPerMinute(), - p.getTotalWordTyped(), - p.totalTime - ); + uiBot.showAnimatedSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), + p.getTotalWordTyped(), p.totalTime); } public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException, InterruptedException { @@ -89,7 +83,11 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText("OOPS!!! It's out of range."); } catch (NumberFormatException e) { uiBot.showText("OOPS!!! Number not found. "); - } catch (NoSuchElementException | InvalidStringInputException e) { + } catch (FaultyInputException e) { + uiBot.showText(e.getMessage()); + } catch (NoSuchElementException e) { + e.printStackTrace(); + } catch (InvalidStringInputException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); @@ -97,6 +95,7 @@ public void runCommandLoopUntilExitCommand() { uiBot.showLine(); } } + assert isExit : "isExit should be true"; } public void exit() { diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index f5dc2ab41f..4b6498992c 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -1,30 +1,23 @@ package seedu.typists.game; import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.common.Utils.getWordLineFromStringArray; public class DataProcessor { - private static final Logger logger = Logger.getLogger("Foo"); - private final List checkerWordLines; - private final List userWordLines; + private final ArrayList checkerWordLines; + private final ArrayList userWordLines; public final double totalTime; - private final List errorWords; public DataProcessor(TimeModeGame tg) { this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); this.totalTime = tg.realGameTime; - this.errorWords = getErrorWords(); } - /** Get the list of words that the user made mistakes on. */ - public List getErrorWords() { - List errorWords = new ArrayList<>(); + public int getErrorWordCount() { + int errorWordCount = 0; int i = 0; for (String[] sa : userWordLines) { String[] checker = checkerWordLines.get(i); @@ -32,21 +25,16 @@ public List getErrorWords() { for (String s : checker) { try { if (!s.equals(sa[ii])) { - errorWords.add(s); + errorWordCount++; } } catch (ArrayIndexOutOfBoundsException e) { - logger.log(Level.INFO, "word(s) missed during input."); + errorWordCount++; } ii++; } i++; } - return errorWords; - } - - /** Get the total number of wrong words typed.*/ - public int getErrorWordCount() { - return errorWords.size(); + return errorWordCount; } public int getTotalWordTyped() { @@ -80,6 +68,7 @@ public int getLineWrongKeyStrokes(String checker, String answer) { } public double getErrorPercentage() { - return (double) getErrorWordCount() / (double) getTotalWordTyped(); + double percentage = (double) getErrorWordCount() / (double) getTotalWordTyped(); + return percentage; } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 2727384b00..5a1b54b48b 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -2,14 +2,11 @@ import java.util.ArrayList; import java.util.Scanner; -import java.util.logging.Level; -import java.util.logging.Logger; import seedu.typists.ui.TextUi; import static seedu.typists.common.Utils.getWordLine; public class TimeModeGame extends Game { - private static final Logger logger = Logger.getLogger("Foo"); private final TextUi ui; protected final ArrayList wordLines; @@ -19,10 +16,9 @@ public class TimeModeGame extends Game { protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { - assert targetWordSet != null : "text passed into Time Game should not be null."; - this.ui = new TextUi(); - this.inputLines = new ArrayList<>(); - this.wordLines = getWordLine(targetWordSet, wordsPerLine); + ui = new TextUi(); + inputLines = new ArrayList<>(); + wordLines = getWordLine(targetWordSet, wordsPerLine); this.gameTime = getGameTime(); startGame(); } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index ba166eeb29..d42f416e3c 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -2,11 +2,12 @@ import seedu.typists.common.Error; import seedu.typists.content.Animation; + import java.math.BigDecimal; import java.math.MathContext; -import java.io.IOException; import java.sql.Timestamp; import java.text.SimpleDateFormat; + import static java.lang.System.lineSeparator; import static java.lang.System.out; import static seedu.typists.common.Messages.CLOCK; @@ -17,17 +18,9 @@ import static seedu.typists.common.Messages.MESSAGE_HELP; import static seedu.typists.common.Messages.MESSAGE_WELCOME; import static seedu.typists.common.Messages.SUMMARY; + import java.util.ArrayList; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.List; import java.util.Scanner; -import java.util.logging.Logger; -import java.util.logging.LogManager; -import java.util.logging.Level; -import java.util.logging.SimpleFormatter; -import java.util.logging.FileHandler; -import java.util.logging.ConsoleHandler; /** * Text UI of the application. @@ -35,10 +28,9 @@ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "==========================================================="; + private static final String DIVIDER = "****************************************************************"; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); - private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); //get current timestamp //unused because it interferes with the EXPECTED.TXT in runtest @@ -190,19 +182,12 @@ public void showAnimatedError(ArrayList content, ui.showAnimatedSentenceErrorRateSummary(rounded); } - public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, - int totalWordTyped, double gameTime) { - assert errorWordCount >= 0; - assert errorPercentage >= 0; - assert totalWordTyped >= 0; - assert gameTime > 0; - assert wpm >= 0; + public void showSummary(int errorWordCount, double errorPercentage, double wpm, + int totalWordTyped, double gameTime) { out.print(SUMMARY + '\n'); - out.print("Number of Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage of Wrong Words: " + String.format("%.2f", errorPercentage) + "%\n"); - out.print("Wrong Words:\n"); - printErrorWords(errorWords); + out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } @@ -214,45 +199,5 @@ public void showAnimatedSummary(int errorWordCount, double errorPercentage, doub viewAnimateRight("Error Percentage: " + String.format("%.2f", errorPercentage)); viewAnimateRight("WPM: " + String.format("%.2f", wpm)); viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); - - void printErrorWords(List errorWords) { - setUpLog(); - if (errorWords == null) { - out.print("No words typed wrongly.\n"); - return; - } - for (int i = 0; i < errorWords.size(); i++) { - assert errorWords != null; - if (i != 0 && i % 8 == 0) { - out.print("\n"); - } - out.print(errorWords.get(i)); - if (i != (errorWords.size() - 1)) { - out.print("|"); - } - } - if ((errorWords.size() - 1) % 8 != 0) { - out.print("\n"); - } - } - - void setUpLog() { - LogManager.getLogManager().reset(); - LOGGER.setLevel(Level.ALL); - - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.SEVERE); - LOGGER.addHandler(ch); - - try { - FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); - fh.setFormatter(new SimpleFormatter()); - fh.setLevel(Level.FINE); - LOGGER.addHandler(fh); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); - } - - LOGGER.info("Set up log in TextUi"); } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index e1a83807fa..a9382fc7ed 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -6,8 +6,6 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import java.util.Arrays; -import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.typists.common.Messages.SUMMARY; @@ -26,14 +24,11 @@ public void setUp() { void showSummary() { TextUi textUi = new TextUi(); String expected = SUMMARY + '\n' - + "Number of Wrong Words: 5/10\n" - + "Error Percentage of Wrong Words: 50.00%\n" - + "Wrong Words:\n" - + "foo|bar\n" + + "Wrong Words: 5/10\n" + + "Error Percentage: 50.00%\n" + "WPM: 40.08\n" + "Total Time taken for the game: 10.07 seconds\n"; - - textUi.showSummary(5, 50.00000, java.util.Arrays.asList("foo", "bar"), 40.08, 10, 10.07); + textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); } @@ -42,42 +37,4 @@ void showSummary() { public void tearDown() { System.setOut(standardOut); } - - @Test - void printErrorWords_noErrorWords_noExceptionThrown() { - List errorWords = null; - String expected = "No words typed wrongly.\n"; - TextUi textUi = new TextUi(); - textUi.printErrorWords(errorWords); - String actual = outputStreamCaptor.toString(); - assertEquals(expected, actual); - } - - @Test - void printErrorWords_multipleOfEight() { - List errorWords = Arrays.asList( - "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", - "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7", "bar8" - ); - String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" - + "bar1|bar2|bar3|bar4|bar5|bar6|bar7|bar8\n"; - TextUi textUi = new TextUi(); - textUi.printErrorWords(errorWords); - String actual = outputStreamCaptor.toString(); - assertEquals(expected, actual); - } - - @Test - void printErrorWords_notMultipleOfEight() { - List errorWords = Arrays.asList( - "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", - "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7" - ); - String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" - + "bar1|bar2|bar3|bar4|bar5|bar6|bar7\n"; - TextUi textUi = new TextUi(); - textUi.printErrorWords(errorWords); - String actual = outputStreamCaptor.toString(); - assertEquals(expected, actual); - } } \ No newline at end of file diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 26a71e2579..c761eea04c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,5 +1,5 @@ | Typist - Version 1.0 - | =========================================================== + | **************************************************************** | ______ _ __ | /_ __/_ ______ (_)____/ /_ | / / / / / / __ \/ / ___/ __/ @@ -13,6 +13,6 @@ | new: start a new word game | time: start a new timer game | bye: exit typist - | =========================================================== -=========================================================== + | **************************************************************** +**************************************************************** Bye. Hope to see you again soon! From eac532af7cd1300a61147424b469a95498e73a8c Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:37:17 +0800 Subject: [PATCH 095/272] Fix conflicts --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 17 +++++ src/main/java/seedu/typists/Main.java | 11 ++- .../seedu/typists/game/DataProcessor.java | 31 ++++++--- .../java/seedu/typists/game/TimeModeGame.java | 10 ++- src/main/java/seedu/typists/ui/TextUi.java | 69 +++++++++++++++++-- .../java/seedu/typists/ui/TextUiTest.java | 49 ++++++++++++- text-ui-test/EXPECTED.TXT | 8 +-- 8 files changed, 169 insertions(+), 28 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..aa879ee413 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -3,7 +3,7 @@ ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} - +* https://www.baeldung.com/java-testing-system-out-println ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 137a2ca486..207fb7e491 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,9 +11,23 @@ 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). +## Features ### Usage ### Open Game +### {Feature name}: {`Keyword`} +Description of feature +Format: {format of command} +* Explanation 1 of format +* Explanation 2 of format + +Examples +* command example 1 +* command example 2 + + + + ### `Keyword` - Describe action List of the keywords are shown below: @@ -30,6 +44,9 @@ List of the keywords are shown below: `bye`-Exit the program. +### Showing summary of a game +Statistics of game is shown automatically after a game is finished. + ## Example of usage: >`new` diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b924e5221d..24d2f087c1 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -47,9 +47,14 @@ public void startTimeLimitGame() throws InterruptedException { uiBot.printClock(); TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); DataProcessor p = new DataProcessor(g); - uiBot.showAnimatedSummary(p.getErrorWordCount(), p.getErrorPercentage(), p.getWordPerMinute(), - p.getTotalWordTyped(), p.totalTime); - } + uiBot.showSummary( + p.getErrorWordCount(), + p.getErrorPercentage(), + p.getErrorWords(), + p.getWordPerMinute(), + p.getTotalWordTyped(), + p.totalTime + ); } public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException, InterruptedException { switch (c.getCommand()) { diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index 4b6498992c..2a65ebf91a 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -1,23 +1,30 @@ package seedu.typists.game; import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.common.Utils.getWordLineFromStringArray; public class DataProcessor { - private final ArrayList checkerWordLines; - private final ArrayList userWordLines; + private static final Logger logger = Logger.getLogger("Foo"); + private final List checkerWordLines; + private final List userWordLines; public final double totalTime; + private final List errorWords; public DataProcessor(TimeModeGame tg) { this.checkerWordLines = tg.wordLines; this.userWordLines = getWordLineFromStringArray(tg.inputLines); this.totalTime = tg.realGameTime; + this.errorWords = getErrorWords(); } - public int getErrorWordCount() { - int errorWordCount = 0; + /** Get the list of words that the user made mistakes on. */ + public List getErrorWords() { + List errorWords = new ArrayList<>(); int i = 0; for (String[] sa : userWordLines) { String[] checker = checkerWordLines.get(i); @@ -25,16 +32,21 @@ public int getErrorWordCount() { for (String s : checker) { try { if (!s.equals(sa[ii])) { - errorWordCount++; + errorWords.add(s); } } catch (ArrayIndexOutOfBoundsException e) { - errorWordCount++; + logger.log(Level.INFO, "word(s) missed during input."); } ii++; } i++; } - return errorWordCount; + return errorWords; + } + + /** Get the total number of wrong words typed.*/ + public int getErrorWordCount() { + return errorWords.size(); } public int getTotalWordTyped() { @@ -68,7 +80,6 @@ public int getLineWrongKeyStrokes(String checker, String answer) { } public double getErrorPercentage() { - double percentage = (double) getErrorWordCount() / (double) getTotalWordTyped(); - return percentage; + return (double) getErrorWordCount() / (double) getTotalWordTyped(); } -} +} \ No newline at end of file diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 5a1b54b48b..2727384b00 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -2,11 +2,14 @@ import java.util.ArrayList; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; import seedu.typists.ui.TextUi; import static seedu.typists.common.Utils.getWordLine; public class TimeModeGame extends Game { + private static final Logger logger = Logger.getLogger("Foo"); private final TextUi ui; protected final ArrayList wordLines; @@ -16,9 +19,10 @@ public class TimeModeGame extends Game { protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { - ui = new TextUi(); - inputLines = new ArrayList<>(); - wordLines = getWordLine(targetWordSet, wordsPerLine); + assert targetWordSet != null : "text passed into Time Game should not be null."; + this.ui = new TextUi(); + this.inputLines = new ArrayList<>(); + this.wordLines = getWordLine(targetWordSet, wordsPerLine); this.gameTime = getGameTime(); startGame(); } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index d42f416e3c..1e7c73b182 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,5 +1,6 @@ package seedu.typists.ui; +import java.io.IOException; import seedu.typists.common.Error; import seedu.typists.content.Animation; @@ -19,8 +20,18 @@ import static seedu.typists.common.Messages.MESSAGE_WELCOME; import static seedu.typists.common.Messages.SUMMARY; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.List; import java.util.ArrayList; import java.util.Scanner; +import java.util.logging.Logger; +import java.util.logging.LogManager; +import java.util.logging.Level; +import java.util.logging.SimpleFormatter; +import java.util.logging.FileHandler; +import java.util.logging.ConsoleHandler; /** * Text UI of the application. @@ -28,9 +39,10 @@ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "****************************************************************"; + private static final String DIVIDER = "==========================================================="; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); + private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); //get current timestamp //unused because it interferes with the EXPECTED.TXT in runtest @@ -183,11 +195,19 @@ public void showAnimatedError(ArrayList content, } - public void showSummary(int errorWordCount, double errorPercentage, double wpm, + public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, int totalWordTyped, double gameTime) { + assert errorWordCount >= 0; + assert errorPercentage >= 0; + assert totalWordTyped >= 0; + assert gameTime > 0; + assert wpm >= 0; + out.print(SUMMARY + '\n'); - out.print("Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("Number of Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); + out.print("Error Percentage of Wrong Words: " + String.format("%.2f", errorPercentage) + "%\n"); + out.print("Wrong Words:\n"); + printErrorWords(errorWords); out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); } @@ -200,4 +220,45 @@ public void showAnimatedSummary(int errorWordCount, double errorPercentage, doub viewAnimateRight("WPM: " + String.format("%.2f", wpm)); viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); } + + void printErrorWords(List errorWords) { + setUpLog(); + if (errorWords == null) { + out.print("No words typed wrongly.\n"); + return; + } + for (int i = 0; i < errorWords.size(); i++) { + assert errorWords != null; + if (i != 0 && i % 8 == 0) { + out.print("\n"); + } + out.print(errorWords.get(i)); + if (i != (errorWords.size() - 1)) { + out.print("|"); + } + } + if ((errorWords.size() - 1) % 8 != 0) { + out.print("\n"); + } + } + + void setUpLog() { + LogManager.getLogManager().reset(); + LOGGER.setLevel(Level.ALL); + + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.SEVERE); + LOGGER.addHandler(ch); + + try { + FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); + fh.setFormatter(new SimpleFormatter()); + fh.setLevel(Level.FINE); + LOGGER.addHandler(fh); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); + } + + LOGGER.info("Set up log in TextUi"); + } } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index a9382fc7ed..e1a83807fa 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -6,6 +6,8 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.Arrays; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.typists.common.Messages.SUMMARY; @@ -24,11 +26,14 @@ public void setUp() { void showSummary() { TextUi textUi = new TextUi(); String expected = SUMMARY + '\n' - + "Wrong Words: 5/10\n" - + "Error Percentage: 50.00%\n" + + "Number of Wrong Words: 5/10\n" + + "Error Percentage of Wrong Words: 50.00%\n" + + "Wrong Words:\n" + + "foo|bar\n" + "WPM: 40.08\n" + "Total Time taken for the game: 10.07 seconds\n"; - textUi.showSummary(5, 50.00000, 40.08, 10, 10.07); + + textUi.showSummary(5, 50.00000, java.util.Arrays.asList("foo", "bar"), 40.08, 10, 10.07); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); } @@ -37,4 +42,42 @@ void showSummary() { public void tearDown() { System.setOut(standardOut); } + + @Test + void printErrorWords_noErrorWords_noExceptionThrown() { + List errorWords = null; + String expected = "No words typed wrongly.\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_multipleOfEight() { + List errorWords = Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7", "bar8" + ); + String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7|bar8\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_notMultipleOfEight() { + List errorWords = Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7" + ); + String expected = "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7\n"; + TextUi textUi = new TextUi(); + textUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } } \ No newline at end of file diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index c761eea04c..44a5b01196 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,5 +1,5 @@ | Typist - Version 1.0 - | **************************************************************** + | =========================================================== | ______ _ __ | /_ __/_ ______ (_)____/ /_ | / / / / / / __ \/ / ___/ __/ @@ -13,6 +13,6 @@ | new: start a new word game | time: start a new timer game | bye: exit typist - | **************************************************************** -**************************************************************** -Bye. Hope to see you again soon! + | =========================================================== +=========================================================== +Bye. Hope to see you again soon! \ No newline at end of file From 9ce253dec84be11b3fc663b2730efd42c4903015 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:41:18 +0800 Subject: [PATCH 096/272] Fix conflicts --- src/main/java/seedu/typists/Main.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 24d2f087c1..d40be7fcb1 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -54,7 +54,8 @@ public void startTimeLimitGame() throws InterruptedException { p.getWordPerMinute(), p.getTotalWordTyped(), p.totalTime - ); } + ); + } public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException, InterruptedException { switch (c.getCommand()) { From 1c18032e6ff67f9dc506a045bd4cadc2c4fe248a Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Thu, 21 Oct 2021 19:43:22 +0800 Subject: [PATCH 097/272] Fix conflicts --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 44a5b01196..26a71e2579 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -15,4 +15,4 @@ | bye: exit typist | =========================================================== =========================================================== -Bye. Hope to see you again soon! \ No newline at end of file +Bye. Hope to see you again soon! From 7e51f10848c3fabf22846c3bfe7b820ba095007c Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Sat, 23 Oct 2021 00:50:13 +0800 Subject: [PATCH 098/272] test table of content --- docs/DeveloperGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index aa879ee413..96c578b3b5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,5 +1,7 @@ # Developer Guide +* [Acknoledgements](#acknowledgements) + ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} From 55949169478151edd9f74f6fda138b264f23a4e9 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 23 Oct 2021 00:50:29 +0800 Subject: [PATCH 099/272] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index aa879ee413..ea35e9229b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,9 +1,12 @@ # Developer Guide +* [Acknowledgements](#acknowledgements) +* [Design & Implementation](#design-&-implementation) ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} * https://www.baeldung.com/java-testing-system-out-println +* ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} From 8a2af8650fd12f5efc9f589297dad547da1e382a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sun, 24 Oct 2021 15:06:22 +0800 Subject: [PATCH 100/272] add class for OOP --- seedu.typists.ui.TextUi.log | 2 ++ seedu.typists.ui.TextUi.log.lck | 0 src/main/java/seedu/typists/Main.java | 17 ++-------- src/main/java/seedu/typists/common/Utils.java | 2 +- .../seedu/typists/game/DataProcessor.java | 2 +- .../java/seedu/typists/game/ErrorGame.java | 6 ++-- src/main/java/seedu/typists/game/Game.java | 18 +++++++++- .../java/seedu/typists/game/TimeModeGame.java | 31 +++++++++++------ .../seedu/typists/game/WordLimitGame.java | 9 +++-- .../java/seedu/typists/parser/Command.java | 5 +++ .../seedu/typists/parser/newGameCommand.java | 34 +++++++++++++++++++ src/test/java/seedu/UtilsTest.java | 2 +- 12 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 seedu.typists.ui.TextUi.log create mode 100644 seedu.typists.ui.TextUi.log.lck create mode 100644 src/main/java/seedu/typists/parser/Command.java create mode 100644 src/main/java/seedu/typists/parser/newGameCommand.java diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log new file mode 100644 index 0000000000..76db5a540c --- /dev/null +++ b/seedu.typists.ui.TextUi.log @@ -0,0 +1,2 @@ +Oct 24, 2021 2:03:29 PM seedu.typists.ui.TextUi setUpLog +INFO: Set up log in TextUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index bd944064f4..627979f591 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -40,24 +40,10 @@ public void start() { public void startWordLimitGame() throws InvalidStringInputException { uiBot.printKeyboard(); - this.wordLimitGame = new WordLimitGame(content.getContent()); + this.wordLimitGame = new WordLimitGame(content.getContent(), 5); wordLimitGame.beginNewGame(); } - public void startTimeLimitGame() { - uiBot.printClock(); - TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); - DataProcessor p = new DataProcessor(g); - uiBot.showSummary( - p.getErrorWordCount(), - p.getErrorPercentage(), - p.getErrorWords(), - p.getWordPerMinute(), - p.getTotalWordTyped(), - p.totalTime - ); - } - public void startErrorGame() { ErrorGame a = new ErrorGame(content.getContent(), LINE_LENGTH); } @@ -95,6 +81,7 @@ public void runCommandLoopUntilExitCommand() { uiBot.showText("OOPS!!! The description after this command word cannot be empty."); } catch (IndexOutOfBoundsException e) { uiBot.showText("OOPS!!! It's out of range."); + e.printStackTrace(); } catch (NumberFormatException e) { uiBot.showText("OOPS!!! Number not found. "); } catch (NoSuchElementException | InvalidStringInputException e) { diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index da0a22876a..f691542990 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -14,7 +14,7 @@ public static ArrayList splitStringIntoWordList(String line) { } /** group the word list into groups of x, where x is the number of words per line. */ - public static ArrayList getWordLine(String text, int lineLength) { + public static ArrayList getWordLines(String text, int lineLength) { ArrayList wordList = splitStringIntoWordList(text); ArrayList wordLines = new ArrayList<>(); int j = 0; diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java index f5dc2ab41f..5614107f3c 100644 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ b/src/main/java/seedu/typists/game/DataProcessor.java @@ -17,7 +17,7 @@ public class DataProcessor { public DataProcessor(TimeModeGame tg) { this.checkerWordLines = tg.wordLines; - this.userWordLines = getWordLineFromStringArray(tg.inputLines); + this.userWordLines = tg.userLines; this.totalTime = tg.realGameTime; this.errorWords = getErrorWords(); } diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java index 5da24716e3..2c5f46704f 100644 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Scanner; -import static seedu.typists.common.Utils.getWordLine; +import static seedu.typists.common.Utils.getWordLines; public class ErrorGame extends Game { private final TextUi ui; @@ -15,7 +15,7 @@ public class ErrorGame extends Game { public ErrorGame(String targetWordSet, int wordsPerLine) { ui = new TextUi(); inputLines = new ArrayList<>(); - wordLines = getWordLine(targetWordSet, wordsPerLine); + wordLines = getWordLines(targetWordSet, wordsPerLine); startGame(); } @@ -29,7 +29,7 @@ public boolean readyToStartGame() { return true; } - public void startGame() { + public void runGame() { if (readyToStartGame()) { for (int i = 0; i < wordLines.size(); i++) { ui.printLine(wordLines.get(i)); diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 5a353218d0..9fa051292b 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -1,5 +1,21 @@ package seedu.typists.game; +import seedu.typists.ui.TextUi; + public abstract class Game { - + protected final TextUi ui; + + public Game() { + this.ui = new TextUi(); + } + + public long getTimeNow() { + return System.currentTimeMillis(); + } + + public double duration(long startTime, long endTime) { + return (double) (endTime - startTime) / 1000; + } + + abstract void runGame(); } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 2727384b00..48eb16c24c 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,30 +1,29 @@ package seedu.typists.game; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Scanner; -import java.util.logging.Level; import java.util.logging.Logger; import seedu.typists.ui.TextUi; -import static seedu.typists.common.Utils.getWordLine; +import static seedu.typists.common.Utils.getWordLines; public class TimeModeGame extends Game { private static final Logger logger = Logger.getLogger("Foo"); - private final TextUi ui; protected final ArrayList wordLines; + protected ArrayList userLines; - protected ArrayList inputLines; protected int gameTime; protected double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { + super(); assert targetWordSet != null : "text passed into Time Game should not be null."; - this.ui = new TextUi(); - this.inputLines = new ArrayList<>(); - this.wordLines = getWordLine(targetWordSet, wordsPerLine); + this.wordLines = getWordLines(targetWordSet, wordsPerLine); + this.userLines = new ArrayList<>(); this.gameTime = getGameTime(); - startGame(); } public boolean readyToStartTimer() { @@ -48,7 +47,7 @@ public int getGameTime() { } } - public void startGame() { + public void runGame() { Scanner in = new Scanner(System.in); if (readyToStartTimer()) { @@ -63,12 +62,22 @@ public void startGame() { realGameTime = (double) currTime / 1000; } else { ui.printLine(wordLines.get(i)); - String userInput = in.nextLine(); - inputLines.add(userInput); + userLines.add(getWordLine(in)); i++; } } System.out.println("Game Finished."); } } + + public String[] getWordLine(Scanner in) { + int j = 0; + List words = new ArrayList<>(); + words.add(in.next()); + j++; + + Object[] objArr = words.toArray(); + return Arrays.copyOf(objArr, objArr.length, String[].class); + } } + diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 82761c2081..56eff074ea 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -9,7 +9,6 @@ import static seedu.typists.parser.StringParser.splitString; public class WordLimitGame extends Game { - private final TextUi ui; private ArrayList eachWord; protected int wordLimit; @@ -18,11 +17,11 @@ public class WordLimitGame extends Game { private final String content1; - public WordLimitGame(String targetWordSet) { + public WordLimitGame(String targetWordSet, int wordsPerLine) { + super(); this.eachWord = new ArrayList<>(100); this.gameIndex = 0; - this.numberOfWordsDisplayed = 5; - this.ui = new TextUi(); + this.numberOfWordsDisplayed = wordsPerLine; this.content1 = targetWordSet; this.wordLimit = getWordLimit(); } @@ -48,7 +47,7 @@ public void trimContent(int wordLimit) throws InvalidStringInputException { eachWord = new ArrayList(eachWord.subList(0, wordLimit)); } - public void beginNewGame() throws InvalidStringInputException { + public void runGame() throws InvalidStringInputException { trimContent(wordLimit); boolean isExit = false; int totalError = 0; diff --git a/src/main/java/seedu/typists/parser/Command.java b/src/main/java/seedu/typists/parser/Command.java new file mode 100644 index 0000000000..dac1f89b14 --- /dev/null +++ b/src/main/java/seedu/typists/parser/Command.java @@ -0,0 +1,5 @@ +package seedu.typists.parser; + +public abstract class Command { + public abstract void runCommand(); +} diff --git a/src/main/java/seedu/typists/parser/newGameCommand.java b/src/main/java/seedu/typists/parser/newGameCommand.java new file mode 100644 index 0000000000..96c9bc509d --- /dev/null +++ b/src/main/java/seedu/typists/parser/newGameCommand.java @@ -0,0 +1,34 @@ +package seedu.typists.parser; + + +import seedu.typists.game.DataProcessor; +import seedu.typists.game.Game; +import seedu.typists.game.TimeModeGame; + +import static seedu.typists.Main.LINE_LENGTH; + +public class newGameCommand extends Command { + @Override + public void runCommand() { + + } + + public void newTimeModeGame() { + Game newGame = new TimeModeGame(content,getContent(), LINE_LENGTH); + DataProcessor p = new DataProcessor(newGame); + } + + public void startTimeLimitGame() { + uiBot.printClock(); + TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); + + uiBot.showSummary( + p.getErrorWordCount(), + p.getErrorPercentage(), + p.getErrorWords(), + p.getWordPerMinute(), + p.getTotalWordTyped(), + p.totalTime + ); + } +} diff --git a/src/test/java/seedu/UtilsTest.java b/src/test/java/seedu/UtilsTest.java index 12dbe35c30..f14ae8298e 100644 --- a/src/test/java/seedu/UtilsTest.java +++ b/src/test/java/seedu/UtilsTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import static seedu.typists.common.Utils.getWordLine; +import static seedu.typists.common.Utils.getWordLines; import static seedu.typists.common.Utils.splitStringIntoWordList; import java.util.ArrayList; From 3823e247fc9dfca90646fdd283455b76fb2a62c6 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 02:46:13 +0800 Subject: [PATCH 101/272] add commandfactory --- src/main/java/seedu/typists/Main.java | 81 +++++-------------- src/main/java/seedu/typists/common/Utils.java | 3 +- .../java/seedu/typists/content/Books.java | 16 ++-- .../java/seedu/typists/game/ErrorGame.java | 2 +- src/main/java/seedu/typists/game/Game.java | 2 +- .../java/seedu/typists/game/TimeModeGame.java | 18 ++--- .../seedu/typists/game/WordLimitGame.java | 16 +++- .../java/seedu/typists/parser/Command.java | 4 +- .../seedu/typists/parser/CommandFactory.java | 20 +++++ .../seedu/typists/parser/ContentCommand.java | 13 +++ .../seedu/typists/parser/ErrorCommand.java | 16 ++++ .../java/seedu/typists/parser/Parser.java | 69 ---------------- .../seedu/typists/parser/TimeGameCommand.java | 23 ++++++ .../seedu/typists/parser/WordGameCommand.java | 19 +++++ .../seedu/typists/parser/newGameCommand.java | 34 -------- 15 files changed, 145 insertions(+), 191 deletions(-) create mode 100644 src/main/java/seedu/typists/parser/CommandFactory.java create mode 100644 src/main/java/seedu/typists/parser/ContentCommand.java create mode 100644 src/main/java/seedu/typists/parser/ErrorCommand.java delete mode 100644 src/main/java/seedu/typists/parser/Parser.java create mode 100644 src/main/java/seedu/typists/parser/TimeGameCommand.java create mode 100644 src/main/java/seedu/typists/parser/WordGameCommand.java delete mode 100644 src/main/java/seedu/typists/parser/newGameCommand.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 627979f591..656ee95cba 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,95 +1,54 @@ package seedu.typists; import seedu.typists.content.Content; -import seedu.typists.game.ErrorGame; -import seedu.typists.game.DataProcessor; -import seedu.typists.game.TimeModeGame; -import seedu.typists.parser.Parser; +import seedu.typists.parser.Command; +import seedu.typists.parser.CommandFactory; import seedu.typists.ui.TextUi; import seedu.typists.game.WordLimitGame; -import seedu.typists.exception.FaultyInputException; -import seedu.typists.exception.InvalidStringInputException; import seedu.typists.storage.StorageFile; -import java.util.NoSuchElementException; +import java.util.Scanner; -//solution below adapted from https://github.com/se-edu/addressbook-level2/ public class Main { /** * Version info of the program. */ public static final String VERSION = "Typist - Version 1.0"; public static final int LINE_LENGTH = 10; - TextUi uiBot; + public static Content content; + public static TextUi uiBot; //Parser parseBot; WordLimitGame wordLimitGame; StorageFile storage; - Content content; + public Main() { - this.uiBot = new TextUi(); + uiBot = new TextUi(); this.storage = new StorageFile(); - this.content = new Content(); + content = new Content(); } public void start() { uiBot.showWelcomeMessage(VERSION); } - public void startWordLimitGame() throws InvalidStringInputException { - uiBot.printKeyboard(); - this.wordLimitGame = new WordLimitGame(content.getContent(), 5); - wordLimitGame.beginNewGame(); - } - - public void startErrorGame() { - ErrorGame a = new ErrorGame(content.getContent(), LINE_LENGTH); - } - - public void executeCommand(Parser c, StorageFile storage) throws InvalidStringInputException { - switch (c.getCommand()) { - case "content": - content.setContent(); - break; - case "new": - startWordLimitGame(); - break; - case "time": - startTimeLimitGame(); - break; - case "error": - startErrorGame(); - break; - default: - break; - } - //storage.writeToFile(tasks); + public String read() { + Scanner sc = new Scanner(System.in); + return sc.nextLine(); } public void runCommandLoopUntilExitCommand() { - boolean isExit = false; - while (!isExit) { - try { - String fullCommand = uiBot.readCommand(); - Parser c = new Parser(fullCommand); - c.parse(); - executeCommand(c, storage); - isExit = c.getIsExit(); - } catch (StringIndexOutOfBoundsException e) { - uiBot.showText("OOPS!!! The description after this command word cannot be empty."); - } catch (IndexOutOfBoundsException e) { - uiBot.showText("OOPS!!! It's out of range."); - e.printStackTrace(); - } catch (NumberFormatException e) { - uiBot.showText("OOPS!!! Number not found. "); - } catch (NoSuchElementException | InvalidStringInputException e) { - e.printStackTrace(); - } finally { - uiBot.showLine(); - } - } + CommandFactory cmdFactory = new CommandFactory(); + String command; + do { + String[] input = read().split(" "); + command = input[0]; + Command c = cmdFactory.getCommand(input[0]); + c.run(); + } while (!command.equals("bye")); + } public void exit() { diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index f691542990..4d15285802 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** * Utility methods. @@ -33,7 +34,7 @@ public static ArrayList getWordLines(String text, int lineLength) { } /** same function as getWordLines, but the param is ArrayList not string. */ - public static ArrayList getWordLineFromStringArray(ArrayList stringList) { + public static ArrayList getWordLineFromStringArray(List stringList) { ArrayList wordLines = new ArrayList<>(); for (String s : stringList) { String[] wordLine = s.split(" "); diff --git a/src/main/java/seedu/typists/content/Books.java b/src/main/java/seedu/typists/content/Books.java index 48f54743be..30689d1998 100644 --- a/src/main/java/seedu/typists/content/Books.java +++ b/src/main/java/seedu/typists/content/Books.java @@ -24,7 +24,7 @@ public class Books { + "person’s lack of theology and geometry;" + "it could even cast doubts upon one’s soul.", "Call me Ishmael. " - + "Some years ago — never mind how long precisely — " + + "Some years ago - never mind how long precisely - " + "having little or no money in my purse, " + "and nothing particular to interest me on shore, " + "I thought I would sail about " @@ -38,7 +38,7 @@ public class Books { + "and especially whenever my hypos get such an upper hand of me, " + "that it requires a strong moral principle to prevent me from " + "deliberately stepping into the street, " - + "and methodically knocking people’s hats off — then, " + + "and methodically knocking people’s hats off - then, " + "I account it high time to get to sea as soon as I can. " + "This is my substitute for pistol and ball. " + "With a philosophical flourish Cato throws himself " @@ -68,7 +68,7 @@ public class Books { + "it was the spring of hope, it was the winter of despair, " + "we had everything before us, we had nothing before us, " + "we were all going direct to Heaven, " - + "we were all going direct the other way — " + + "we were all going direct the other way - " + "in short, the period was so far like the present period, " + "that some of its noisiest authorities insisted on its being " + "received, for good or for evil, " @@ -104,7 +104,7 @@ public class Books { + "three hours, that they meant to murder him. " + "With his inky fingers and his bitten nails, " + "his manner cynical and nervous, " - + "anybody could tell he didn’t belong – " + + "anybody could tell he didn’t belong - " + "belong to the early summer sun, the cool " + "Whitsun wind off the sea, the holiday crowd. " + "They came in by train from Victoria every five minutes, " @@ -153,7 +153,7 @@ public class Books { + "without movement, so lone and cold that the spirit of " + "it was not even that of sadness. " + "There was a hint in it of laughter, " - + "but of a laughter more terrible than any sadness — " + + "but of a laughter more terrible than any sadness - " + "a laughter that was mirthless as the smile of the Sphinx, " + "a laughter cold as the frost and partaking of the " + "grimness of infallibility. " @@ -205,7 +205,7 @@ public class Books { + "Within, walls continued upright, bricks met neatly, " + "floors were firm, and doors were sensibly shut; " + "silence lay steadily against the wood and " - + "stone of Hill House, and whatever walked there, walked alone…", + + "stone of Hill House, and whatever walked there, walked alone...", "As Gregor Samsa awoke one " + "morning from uneasy dreams he found himself transformed " + "in his bed into a gigantic insect. " @@ -222,13 +222,13 @@ public class Books { + "No, I am not a spook like those who haunted Edgar Allan Poe; " + "nor am I one of your Hollywood-movie ectoplasms. " + "I am a man of substance, of flesh and bone, fiber " - + "and liquids—and I might even be said to possess a mind. " + + "and liquids-and I might even be said to possess a mind. " + "I am invisible, understand, simply because people " + "refuse to see me. Like the bodiless heads you see " + "sometimes in circus sideshows, it is as though " + "I have been surrounded by mirrors of hard, distorting glass. " + "When they approach me they see only my surroundings, " - + "themselves, or figments of their imagination—" + + "themselves, or figments of their imagination-" + "indeed, everything and anything except me.", "You don't know " + "about me without you have read a book by the " diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java index 2c5f46704f..44884e5632 100644 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -16,7 +16,7 @@ public ErrorGame(String targetWordSet, int wordsPerLine) { ui = new TextUi(); inputLines = new ArrayList<>(); wordLines = getWordLines(targetWordSet, wordsPerLine); - startGame(); + runGame(); } public boolean readyToStartGame() { diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 9fa051292b..9240ef01a8 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -17,5 +17,5 @@ public double duration(long startTime, long endTime) { return (double) (endTime - startTime) / 1000; } - abstract void runGame(); + public abstract void runGame(); } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 48eb16c24c..4c01b6946d 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,12 +1,12 @@ package seedu.typists.game; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Scanner; import java.util.logging.Logger; -import seedu.typists.ui.TextUi; + +import static seedu.typists.common.Utils.getWordLineFromStringArray; import static seedu.typists.common.Utils.getWordLines; public class TimeModeGame extends Game { @@ -49,6 +49,7 @@ public int getGameTime() { public void runGame() { Scanner in = new Scanner(System.in); + List inputs = new ArrayList<>(); if (readyToStartTimer()) { int i = 0; @@ -62,22 +63,17 @@ public void runGame() { realGameTime = (double) currTime / 1000; } else { ui.printLine(wordLines.get(i)); - userLines.add(getWordLine(in)); + inputs.add(in.nextLine()); i++; } } + updateUserLines(inputs); System.out.println("Game Finished."); } } - public String[] getWordLine(Scanner in) { - int j = 0; - List words = new ArrayList<>(); - words.add(in.next()); - j++; - - Object[] objArr = words.toArray(); - return Arrays.copyOf(objArr, objArr.length, String[].class); + public void updateUserLines(List stringArray) { + userLines = getWordLineFromStringArray(stringArray); } } diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 56eff074ea..6f58b4111a 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -47,8 +47,13 @@ public void trimContent(int wordLimit) throws InvalidStringInputException { eachWord = new ArrayList(eachWord.subList(0, wordLimit)); } - public void runGame() throws InvalidStringInputException { - trimContent(wordLimit); + public void runGame() { + try { + trimContent(wordLimit); + } catch (InvalidStringInputException e) { + e.printStackTrace(); + //do something + } boolean isExit = false; int totalError = 0; while (!isExit) { @@ -71,7 +76,12 @@ public void runGame() throws InvalidStringInputException { break; } WordLimitDataProcessor recordError = new WordLimitDataProcessor(fullCommand, temp); - totalError += recordError.getError(); + try { + totalError += recordError.getError(); + } catch (InvalidStringInputException e) { + e.printStackTrace(); + //do something + } //isExit = recordError.getIsExit(); ui.printGameMode1Progress(gameIndex,getTotalSentence()); if (gameIndex >= getTotalSentence()) { diff --git a/src/main/java/seedu/typists/parser/Command.java b/src/main/java/seedu/typists/parser/Command.java index dac1f89b14..36bb82eb76 100644 --- a/src/main/java/seedu/typists/parser/Command.java +++ b/src/main/java/seedu/typists/parser/Command.java @@ -1,5 +1,5 @@ package seedu.typists.parser; -public abstract class Command { - public abstract void runCommand(); +public interface Command { + void run(); } diff --git a/src/main/java/seedu/typists/parser/CommandFactory.java b/src/main/java/seedu/typists/parser/CommandFactory.java new file mode 100644 index 0000000000..0c0f061871 --- /dev/null +++ b/src/main/java/seedu/typists/parser/CommandFactory.java @@ -0,0 +1,20 @@ +package seedu.typists.parser; + +public class CommandFactory { + + public Command getCommand(String commandType) { + switch (commandType) { + case "time": + return new TimeGameCommand(); + case "word": + return new WordGameCommand(); + case "content": + // return something + return null; + case "error": + //something + default: + return null; + } + } +} diff --git a/src/main/java/seedu/typists/parser/ContentCommand.java b/src/main/java/seedu/typists/parser/ContentCommand.java new file mode 100644 index 0000000000..de81f0defb --- /dev/null +++ b/src/main/java/seedu/typists/parser/ContentCommand.java @@ -0,0 +1,13 @@ +package seedu.typists.parser; + +import seedu.typists.content.Content; + +import static seedu.typists.Main.content; + +public class ContentCommand implements Command{ + @Override + public void run() { + content.setContent(); + } + +} diff --git a/src/main/java/seedu/typists/parser/ErrorCommand.java b/src/main/java/seedu/typists/parser/ErrorCommand.java new file mode 100644 index 0000000000..4cb9427bf6 --- /dev/null +++ b/src/main/java/seedu/typists/parser/ErrorCommand.java @@ -0,0 +1,16 @@ +package seedu.typists.parser; + +import seedu.typists.game.ErrorGame; + +import static seedu.typists.Main.LINE_LENGTH; +import static seedu.typists.Main.content; + +public class ErrorCommand implements Command{ + @Override + public void run() { + startErrorGame(); + } + public void startErrorGame() { + new ErrorGame(content.getContent(), LINE_LENGTH); + } +} diff --git a/src/main/java/seedu/typists/parser/Parser.java b/src/main/java/seedu/typists/parser/Parser.java deleted file mode 100644 index 0c0dd0f0a6..0000000000 --- a/src/main/java/seedu/typists/parser/Parser.java +++ /dev/null @@ -1,69 +0,0 @@ -package seedu.typists.parser; - - -import seedu.typists.exception.FaultyInputException; - -/** - * Parses user input. - */ -public class Parser { - protected String input; - protected String command; - protected String description; - protected Boolean isExit; - - /** - * Parser with input and a boolean. - * command by default = "default" - * @param input takes user input - */ - public Parser(String input) { - this.input = input; - this.isExit = false; - this.command = "default"; - } - - /** - *Get exit. - * @return obtain the Exit status - */ - public Boolean getIsExit() { - return isExit; - } - - - public void parse() { - switch (input) { - case "bye": - isExit = true; - command = "bye"; - break; - case "new": - command = "new"; - break; - case "time": - command = "time"; - break; - case "error": - command = "error"; - break; - case "content": - command = "content"; - break; - default: - System.out.println("invalid command."); - break; - } - } - - public String getCommand() { - return command; - } - - public String getDescription() throws FaultyInputException { - if (description.isEmpty()) { - throw new FaultyInputException("OOPS!!! The description cannot be empty."); - } - return description; - } -} diff --git a/src/main/java/seedu/typists/parser/TimeGameCommand.java b/src/main/java/seedu/typists/parser/TimeGameCommand.java new file mode 100644 index 0000000000..2b3eb92a1e --- /dev/null +++ b/src/main/java/seedu/typists/parser/TimeGameCommand.java @@ -0,0 +1,23 @@ +package seedu.typists.parser; + +import seedu.typists.game.DataProcessor; +import seedu.typists.game.Game; +import seedu.typists.game.TimeModeGame; + +import static seedu.typists.Main.LINE_LENGTH; +import static seedu.typists.Main.content; + +public class TimeGameCommand implements Command { + + @Override + public void run() { + startTimeLimitGame(); + } + + public void startTimeLimitGame() { + Game newGame = new TimeModeGame(content.getContent(), LINE_LENGTH); + newGame.runGame(); + //need to be modified with data processor + DataProcessor p = new DataProcessor((TimeModeGame) newGame); + } +} diff --git a/src/main/java/seedu/typists/parser/WordGameCommand.java b/src/main/java/seedu/typists/parser/WordGameCommand.java new file mode 100644 index 0000000000..2c2701fbe1 --- /dev/null +++ b/src/main/java/seedu/typists/parser/WordGameCommand.java @@ -0,0 +1,19 @@ +package seedu.typists.parser; + +import seedu.typists.game.Game; +import seedu.typists.game.WordLimitGame; + +import static seedu.typists.Main.content; +import static seedu.typists.Main.uiBot; + +public class WordGameCommand implements Command { + @Override + public void run() { + startWordLimitGame(); + } + + public void startWordLimitGame() { + uiBot.printKeyboard(); + new WordLimitGame(content.getContent(), 5).runGame(); + } +} diff --git a/src/main/java/seedu/typists/parser/newGameCommand.java b/src/main/java/seedu/typists/parser/newGameCommand.java deleted file mode 100644 index 96c9bc509d..0000000000 --- a/src/main/java/seedu/typists/parser/newGameCommand.java +++ /dev/null @@ -1,34 +0,0 @@ -package seedu.typists.parser; - - -import seedu.typists.game.DataProcessor; -import seedu.typists.game.Game; -import seedu.typists.game.TimeModeGame; - -import static seedu.typists.Main.LINE_LENGTH; - -public class newGameCommand extends Command { - @Override - public void runCommand() { - - } - - public void newTimeModeGame() { - Game newGame = new TimeModeGame(content,getContent(), LINE_LENGTH); - DataProcessor p = new DataProcessor(newGame); - } - - public void startTimeLimitGame() { - uiBot.printClock(); - TimeModeGame g = new TimeModeGame(content.getContent(), LINE_LENGTH); - - uiBot.showSummary( - p.getErrorWordCount(), - p.getErrorPercentage(), - p.getErrorWords(), - p.getWordPerMinute(), - p.getTotalWordTyped(), - p.totalTime - ); - } -} From 974a5df538083d2bdcdb7eab6ca96aa339c15ee1 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 02:56:20 +0800 Subject: [PATCH 102/272] Update Main.java --- src/main/java/seedu/typists/Main.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 656ee95cba..3f785d2e40 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -19,8 +19,6 @@ public class Main { public static final int LINE_LENGTH = 10; public static Content content; public static TextUi uiBot; - //Parser parseBot; - WordLimitGame wordLimitGame; StorageFile storage; From 145054fb1b7422cec976046850bd1aaa76e25c71 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 15:33:19 +0800 Subject: [PATCH 103/272] update to pass test --- seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.lck | 0 src/main/java/seedu/typists/Main.java | 1 - .../seedu/typists/game/WordLimitGame.java | 26 ++++++++++++------- .../seedu/typists/parser/ContentCommand.java | 2 +- .../seedu/typists/parser/ErrorCommand.java | 3 ++- 6 files changed, 21 insertions(+), 13 deletions(-) delete mode 100644 seedu.typists.ui.TextUi.log.lck diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 76db5a540c..5c5b029c23 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 24, 2021 2:03:29 PM seedu.typists.ui.TextUi setUpLog +Oct 25, 2021 3:33:04 PM seedu.typists.ui.TextUi setUpLog INFO: Set up log in TextUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index b777882bec..ed424720c5 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -5,7 +5,6 @@ import seedu.typists.parser.CommandFactory; import seedu.typists.ui.TextUi; -import seedu.typists.game.WordLimitGame; import seedu.typists.storage.StorageFile; import java.util.Scanner; diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index ca68e23622..31d43ea14f 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -25,6 +25,19 @@ public WordLimitGame(String targetWordSet, int wordsPerLine) { this.wordLimit = getWordLimit(); } + @Override + public void runGame() { + try { + game(); + } catch (InvalidStringInputException e) { + e.printStackTrace(); + //needs update + } catch (InterruptedException e) { + e.printStackTrace(); + //needs update + } + } + public int getTotalSentence() { return eachWord.size(); } @@ -42,17 +55,12 @@ public int getWordLimit() { } public void trimContent(int wordLimit) throws InvalidStringInputException { - eachWord = splitString(content1," "); - eachWord = new ArrayList(eachWord.subList(0, wordLimit)); + eachWord = splitString(content1, " "); + eachWord = new ArrayList<>(eachWord.subList(0, wordLimit)); } - public void runGame() { - try { - trimContent(wordLimit); - } catch (InvalidStringInputException e) { - e.printStackTrace(); - //do something - } + public void game() throws InterruptedException, InvalidStringInputException { + trimContent(wordLimit); boolean isExit = false; int totalError = 0; diff --git a/src/main/java/seedu/typists/parser/ContentCommand.java b/src/main/java/seedu/typists/parser/ContentCommand.java index de81f0defb..808db2d1bf 100644 --- a/src/main/java/seedu/typists/parser/ContentCommand.java +++ b/src/main/java/seedu/typists/parser/ContentCommand.java @@ -4,7 +4,7 @@ import static seedu.typists.Main.content; -public class ContentCommand implements Command{ +public class ContentCommand implements Command { @Override public void run() { content.setContent(); diff --git a/src/main/java/seedu/typists/parser/ErrorCommand.java b/src/main/java/seedu/typists/parser/ErrorCommand.java index 4cb9427bf6..1385e4c95a 100644 --- a/src/main/java/seedu/typists/parser/ErrorCommand.java +++ b/src/main/java/seedu/typists/parser/ErrorCommand.java @@ -5,11 +5,12 @@ import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.Main.content; -public class ErrorCommand implements Command{ +public class ErrorCommand implements Command { @Override public void run() { startErrorGame(); } + public void startErrorGame() { new ErrorGame(content.getContent(), LINE_LENGTH); } From d86212fcf4e0dee3880fbbec2fa601615a1409fa Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 16:02:45 +0800 Subject: [PATCH 104/272] add exitcommand --- src/main/java/seedu/typists/Main.java | 11 +++++------ .../java/seedu/typists/parser/CommandFactory.java | 3 +++ src/main/java/seedu/typists/parser/ExitCommand.java | 10 ++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 src/main/java/seedu/typists/parser/ExitCommand.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index ed424720c5..7a0b71f187 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -36,20 +36,20 @@ public String read() { return sc.nextLine(); } - public void runCommandLoopUntilExitCommand() { + public void runCommandLoop() { CommandFactory cmdFactory = new CommandFactory(); String command; do { String[] input = read().split(" "); command = input[0]; Command c = cmdFactory.getCommand(input[0]); - c.run(); + if (c != null) { + c.run(); + } } while (!command.equals("bye")); - } public void exit() { - uiBot.showBye(); } /** @@ -57,8 +57,7 @@ public void exit() { */ public void run() { start(); - runCommandLoopUntilExitCommand(); - exit(); + runCommandLoop(); } /** diff --git a/src/main/java/seedu/typists/parser/CommandFactory.java b/src/main/java/seedu/typists/parser/CommandFactory.java index 0c0f061871..2ba6b02120 100644 --- a/src/main/java/seedu/typists/parser/CommandFactory.java +++ b/src/main/java/seedu/typists/parser/CommandFactory.java @@ -13,7 +13,10 @@ public Command getCommand(String commandType) { return null; case "error": //something + case "bye": + return new ExitCommand(); default: + System.out.println("invalid command"); return null; } } diff --git a/src/main/java/seedu/typists/parser/ExitCommand.java b/src/main/java/seedu/typists/parser/ExitCommand.java new file mode 100644 index 0000000000..439bd01c6c --- /dev/null +++ b/src/main/java/seedu/typists/parser/ExitCommand.java @@ -0,0 +1,10 @@ +package seedu.typists.parser; + +import static seedu.typists.Main.uiBot; + +public class ExitCommand implements Command { + @Override + public void run() { + uiBot.showBye(); + } +} From b224c5cf3d94b11f4916a967992d93d8ab2f9d03 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 16:08:39 +0800 Subject: [PATCH 105/272] Update EXPECTED.TXT --- text-ui-test/EXPECTED.TXT | 1 - 1 file changed, 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 26a71e2579..d232ef1b98 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -14,5 +14,4 @@ | time: start a new timer game | bye: exit typist | =========================================================== -=========================================================== Bye. Hope to see you again soon! From 8bcb483ad4d7bd09b04e0ebb75e451509f16661c Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 19:45:41 +0800 Subject: [PATCH 106/272] modifications and printout userInput prints out the userInput for timeModeGame as per request by JiaJing --- .../java/seedu/typists/common/Messages.java | 2 +- .../java/seedu/typists/game/TimeModeGame.java | 11 +++++-- .../seedu/typists/parser/CommandFactory.java | 10 ++++--- .../seedu/typists/parser/ContentCommand.java | 3 +- .../seedu/typists/parser/TimeGameCommand.java | 29 +++++++++++++------ src/main/java/seedu/typists/ui/TextUi.java | 6 ++-- 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 923384f19e..202d174e2c 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -55,7 +55,7 @@ public class Messages { public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" + "content: set the content\n" - + "new: start a new word game\n" + + "word: start a new word game\n" + "time: start a new timer game\n" + "bye: exit typist"; diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 4c01b6946d..c3e68dd457 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Scanner; +import java.util.logging.Level; import java.util.logging.Logger; @@ -13,7 +14,7 @@ public class TimeModeGame extends Game { private static final Logger logger = Logger.getLogger("Foo"); protected final ArrayList wordLines; - protected ArrayList userLines; + public ArrayList userLines; protected int gameTime; protected double realGameTime; @@ -62,13 +63,17 @@ public void runGame() { timeOver = true; realGameTime = (double) currTime / 1000; } else { - ui.printLine(wordLines.get(i)); + try { + ui.printLine(wordLines.get(i)); + } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "no more content."); + } inputs.add(in.nextLine()); i++; } } updateUserLines(inputs); - System.out.println("Game Finished."); + ui.printScreen("Game Finished."); } } diff --git a/src/main/java/seedu/typists/parser/CommandFactory.java b/src/main/java/seedu/typists/parser/CommandFactory.java index 2ba6b02120..2f0503f224 100644 --- a/src/main/java/seedu/typists/parser/CommandFactory.java +++ b/src/main/java/seedu/typists/parser/CommandFactory.java @@ -1,6 +1,9 @@ package seedu.typists.parser; +import seedu.typists.ui.TextUi; + public class CommandFactory { + TextUi ui = new TextUi(); public Command getCommand(String commandType) { switch (commandType) { @@ -9,14 +12,13 @@ public Command getCommand(String commandType) { case "word": return new WordGameCommand(); case "content": - // return something - return null; + return new ContentCommand(); case "error": - //something + return new ErrorCommand(); case "bye": return new ExitCommand(); default: - System.out.println("invalid command"); + ui.printScreen("invalid command"); return null; } } diff --git a/src/main/java/seedu/typists/parser/ContentCommand.java b/src/main/java/seedu/typists/parser/ContentCommand.java index 808db2d1bf..09e23f08d6 100644 --- a/src/main/java/seedu/typists/parser/ContentCommand.java +++ b/src/main/java/seedu/typists/parser/ContentCommand.java @@ -1,10 +1,9 @@ package seedu.typists.parser; -import seedu.typists.content.Content; - import static seedu.typists.Main.content; public class ContentCommand implements Command { + @Override public void run() { content.setContent(); diff --git a/src/main/java/seedu/typists/parser/TimeGameCommand.java b/src/main/java/seedu/typists/parser/TimeGameCommand.java index 2b3eb92a1e..197625033f 100644 --- a/src/main/java/seedu/typists/parser/TimeGameCommand.java +++ b/src/main/java/seedu/typists/parser/TimeGameCommand.java @@ -1,23 +1,34 @@ package seedu.typists.parser; import seedu.typists.game.DataProcessor; -import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; -import static seedu.typists.Main.LINE_LENGTH; -import static seedu.typists.Main.content; +import java.util.Arrays; + +import static seedu.typists.Main.*; public class TimeGameCommand implements Command { @Override public void run() { - startTimeLimitGame(); + TimeModeGame game = createGame(); + game.runGame(); + process(game); + printUserInput(game); + } + + public TimeModeGame createGame() { + return new TimeModeGame(content.getContent(), LINE_LENGTH); + } + + public void process(TimeModeGame tg) { + DataProcessor dp = new DataProcessor(tg); } - public void startTimeLimitGame() { - Game newGame = new TimeModeGame(content.getContent(), LINE_LENGTH); - newGame.runGame(); - //need to be modified with data processor - DataProcessor p = new DataProcessor((TimeModeGame) newGame); + public void printUserInput(TimeModeGame tg) { + uiBot.printScreen("user input is: "); + for (String[] sa: tg.userLines) { + uiBot.printScreen(Arrays.toString(sa)); + } } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 1e7c73b182..dfd368fdb4 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -85,8 +85,8 @@ public String readCommand() { return sc.nextLine(); } - public void showLine() { - System.out.println(DIVIDER); + public void line() { + printScreen(DIVIDER); } /** @@ -103,7 +103,7 @@ public void showNumber(int i) { } public void showBye() { - System.out.println("Bye. Hope to see you again soon!"); + printScreen("Bye. Hope to see you again soon!"); } public void printGameMode1Progress(int a, int b) throws InterruptedException { From 5c976b8986b3991d3be313cd78ed30af83bb4487 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 19:49:51 +0800 Subject: [PATCH 107/272] checkstyle update --- seedu.typists.ui.TextUi.log | 2 +- src/main/java/seedu/typists/parser/TimeGameCommand.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 5c5b029c23..8f340113de 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 25, 2021 3:33:04 PM seedu.typists.ui.TextUi setUpLog +Oct 25, 2021 7:49:39 PM seedu.typists.ui.TextUi setUpLog INFO: Set up log in TextUi diff --git a/src/main/java/seedu/typists/parser/TimeGameCommand.java b/src/main/java/seedu/typists/parser/TimeGameCommand.java index 197625033f..b636a0816d 100644 --- a/src/main/java/seedu/typists/parser/TimeGameCommand.java +++ b/src/main/java/seedu/typists/parser/TimeGameCommand.java @@ -5,7 +5,10 @@ import java.util.Arrays; -import static seedu.typists.Main.*; +import static seedu.typists.Main.content; +import static seedu.typists.Main.uiBot; +import static seedu.typists.Main.LINE_LENGTH; + public class TimeGameCommand implements Command { From e11f786fa2daffded13b1bde507f130322361963 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 19:56:01 +0800 Subject: [PATCH 108/272] Update EXPECTED.TXT --- text-ui-test/EXPECTED.TXT | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index d232ef1b98..da9337bae3 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -10,8 +10,8 @@ | Brought to you by -- AY2122S1-CS2113-T13-4. | Manual: | content: set the content - | new: start a new word game + | word: start a new word game | time: start a new timer game | bye: exit typist | =========================================================== -Bye. Hope to see you again soon! + | Bye. Hope to see you again soon! From 6bdde74e9ec47c7dc1e4234c75ba6e5066d15d20 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 25 Oct 2021 21:11:24 +0800 Subject: [PATCH 109/272] Initial change for revamp for summary feature --- src/main/java/seedu/typists/Main.java | 4 +- .../typists/{parser => command}/Command.java | 2 +- .../{parser => command}/CommandFactory.java | 2 +- .../{parser => command}/ContentCommand.java | 4 +- .../{parser => command}/ErrorCommand.java | 2 +- .../{parser => command}/ExitCommand.java | 2 +- .../{parser => command}/TimeGameCommand.java | 3 +- .../{parser => command}/WordGameCommand.java | 4 +- .../seedu/typists/game/SummaryManager.java | 109 +++++++++++++++++ src/main/java/seedu/typists/ui/SummaryUI.java | 111 ++++++++++++++++++ src/main/java/seedu/typists/ui/TextUi.java | 48 +------- 11 files changed, 234 insertions(+), 57 deletions(-) rename src/main/java/seedu/typists/{parser => command}/Command.java (59%) rename src/main/java/seedu/typists/{parser => command}/CommandFactory.java (94%) rename src/main/java/seedu/typists/{parser => command}/ContentCommand.java (71%) rename src/main/java/seedu/typists/{parser => command}/ErrorCommand.java (91%) rename src/main/java/seedu/typists/{parser => command}/ExitCommand.java (83%) rename src/main/java/seedu/typists/{parser => command}/TimeGameCommand.java (89%) rename src/main/java/seedu/typists/{parser => command}/WordGameCommand.java (85%) create mode 100644 src/main/java/seedu/typists/game/SummaryManager.java create mode 100644 src/main/java/seedu/typists/ui/SummaryUI.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 7a0b71f187..d8e4f98fb9 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,8 +1,8 @@ package seedu.typists; import seedu.typists.content.Content; -import seedu.typists.parser.Command; -import seedu.typists.parser.CommandFactory; +import seedu.typists.command.Command; +import seedu.typists.command.CommandFactory; import seedu.typists.ui.TextUi; import seedu.typists.storage.StorageFile; diff --git a/src/main/java/seedu/typists/parser/Command.java b/src/main/java/seedu/typists/command/Command.java similarity index 59% rename from src/main/java/seedu/typists/parser/Command.java rename to src/main/java/seedu/typists/command/Command.java index 36bb82eb76..602a275949 100644 --- a/src/main/java/seedu/typists/parser/Command.java +++ b/src/main/java/seedu/typists/command/Command.java @@ -1,4 +1,4 @@ -package seedu.typists.parser; +package seedu.typists.command; public interface Command { void run(); diff --git a/src/main/java/seedu/typists/parser/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java similarity index 94% rename from src/main/java/seedu/typists/parser/CommandFactory.java rename to src/main/java/seedu/typists/command/CommandFactory.java index 2ba6b02120..da9e980998 100644 --- a/src/main/java/seedu/typists/parser/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -1,4 +1,4 @@ -package seedu.typists.parser; +package seedu.typists.command; public class CommandFactory { diff --git a/src/main/java/seedu/typists/parser/ContentCommand.java b/src/main/java/seedu/typists/command/ContentCommand.java similarity index 71% rename from src/main/java/seedu/typists/parser/ContentCommand.java rename to src/main/java/seedu/typists/command/ContentCommand.java index 808db2d1bf..834ab3c838 100644 --- a/src/main/java/seedu/typists/parser/ContentCommand.java +++ b/src/main/java/seedu/typists/command/ContentCommand.java @@ -1,6 +1,4 @@ -package seedu.typists.parser; - -import seedu.typists.content.Content; +package seedu.typists.command; import static seedu.typists.Main.content; diff --git a/src/main/java/seedu/typists/parser/ErrorCommand.java b/src/main/java/seedu/typists/command/ErrorCommand.java similarity index 91% rename from src/main/java/seedu/typists/parser/ErrorCommand.java rename to src/main/java/seedu/typists/command/ErrorCommand.java index 1385e4c95a..211a83bb2c 100644 --- a/src/main/java/seedu/typists/parser/ErrorCommand.java +++ b/src/main/java/seedu/typists/command/ErrorCommand.java @@ -1,4 +1,4 @@ -package seedu.typists.parser; +package seedu.typists.command; import seedu.typists.game.ErrorGame; diff --git a/src/main/java/seedu/typists/parser/ExitCommand.java b/src/main/java/seedu/typists/command/ExitCommand.java similarity index 83% rename from src/main/java/seedu/typists/parser/ExitCommand.java rename to src/main/java/seedu/typists/command/ExitCommand.java index 439bd01c6c..26a708fb61 100644 --- a/src/main/java/seedu/typists/parser/ExitCommand.java +++ b/src/main/java/seedu/typists/command/ExitCommand.java @@ -1,4 +1,4 @@ -package seedu.typists.parser; +package seedu.typists.command; import static seedu.typists.Main.uiBot; diff --git a/src/main/java/seedu/typists/parser/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java similarity index 89% rename from src/main/java/seedu/typists/parser/TimeGameCommand.java rename to src/main/java/seedu/typists/command/TimeGameCommand.java index 2b3eb92a1e..4153ed8606 100644 --- a/src/main/java/seedu/typists/parser/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -1,5 +1,6 @@ -package seedu.typists.parser; +package seedu.typists.command; +import seedu.typists.command.Command; import seedu.typists.game.DataProcessor; import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; diff --git a/src/main/java/seedu/typists/parser/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java similarity index 85% rename from src/main/java/seedu/typists/parser/WordGameCommand.java rename to src/main/java/seedu/typists/command/WordGameCommand.java index 2c2701fbe1..cd3680895d 100644 --- a/src/main/java/seedu/typists/parser/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -1,6 +1,6 @@ -package seedu.typists.parser; +package seedu.typists.command; -import seedu.typists.game.Game; +import seedu.typists.command.Command; import seedu.typists.game.WordLimitGame; import static seedu.typists.Main.content; diff --git a/src/main/java/seedu/typists/game/SummaryManager.java b/src/main/java/seedu/typists/game/SummaryManager.java new file mode 100644 index 0000000000..917363fb14 --- /dev/null +++ b/src/main/java/seedu/typists/game/SummaryManager.java @@ -0,0 +1,109 @@ +package seedu.typists.game; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class SummaryManager { + + public static HashMap generateSummary( + List expectedInput, List actualInput, double timeElapsed, String gameMode) { + + HashMap summary = new HashMap<>(); + summary.put("timeElapsed", timeElapsed); + summary.put("gameMode", gameMode); + summary.put("errorWordCount", calculateErrorWordCount(actualInput, expectedInput)); + summary.put("correctWordCount", calculateCorrectWordCount(actualInput, expectedInput)); + summary.put("totalWordCount", calculateTotalWordCount(expectedInput)); + summary.put("errorWordPercentage", calculateErrorWordsPercentage(actualInput, expectedInput)); + summary.put("correctWordPercentage", calculateCorrectWordsPercentage(actualInput, expectedInput)); + summary.put("wordPerMinute", calculateWPM(timeElapsed, actualInput, expectedInput)); + summary.put("errorWords", getErrorWords(actualInput,expectedInput)); + return summary; + } + + private static List getErrorWords(List actualInput, List expectedInput) { + List errorWords= new ArrayList(); + + for (String userWord : actualInput) { + + if (expectedInput.isEmpty()) { + break; + } + + int result = expectedInput.indexOf(userWord); + + if (result == -1) { + String errorWord = userWord; + errorWords.add(userWord); + } else { + expectedInput.remove(result); + } + + } + + return errorWords; + } + + private static Double calculateCorrectWordsPercentage( + List actualInput, List expectedInput) { + int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); + int totalWordCount = calculateTotalWordCount(expectedInput); + double correctWordsPercentage = ((double)correctWordCount / (double)totalWordCount) * 100; + return correctWordsPercentage; + } + + private static Double calculateWPM(Double timeElapsed, List actualInput, List expectedInput) { + int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); + double wordPerMinute = (double)correctWordCount / timeElapsed; + return wordPerMinute; + } + + private static int calculateCorrectWordCount(List actualInput, List expectedInput) { + int correctWordCount = 0; + + for (String userWord : actualInput) { + + if (expectedInput.isEmpty()) { + break; + } + + int result = expectedInput.indexOf(userWord); + + if (result == -1) { + continue; + } else { + expectedInput.remove(result); + correctWordCount++; + } + + } + + return correctWordCount; + + } + + private static int calculateErrorWordCount(List actualInput, List expectedInput) { + int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); + assert correctWordCount >= 0; + int totalWordCount = calculateTotalWordCount(expectedInput); + assert correctWordCount >= 0; + assert totalWordCount >= correctWordCount; + int errorWordCount = totalWordCount - correctWordCount; + return errorWordCount; + } + + private static Double calculateErrorWordsPercentage(List actualInput, List expectedInput) { + int errorWordCount = calculateErrorWordCount(actualInput, expectedInput); + int totalWordCount = calculateTotalWordCount(expectedInput); + double errorWordsPercentage = ((double)errorWordCount / (double)totalWordCount) * 100; + return errorWordsPercentage; + } + + private static int calculateTotalWordCount(List expectedInput) { + int totalWordCount = expectedInput.size(); + return totalWordCount; + } + + +} diff --git a/src/main/java/seedu/typists/ui/SummaryUI.java b/src/main/java/seedu/typists/ui/SummaryUI.java new file mode 100644 index 0000000000..7885ffd39a --- /dev/null +++ b/src/main/java/seedu/typists/ui/SummaryUI.java @@ -0,0 +1,111 @@ +package seedu.typists.ui; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Logger; +import java.util.logging.LogManager; +import java.util.logging.Level; +import java.util.logging.SimpleFormatter; +import java.util.logging.FileHandler; +import java.util.logging.ConsoleHandler; + +import static java.lang.System.out; +import static seedu.typists.common.Messages.SUMMARY; + +public class SummaryUI { + + private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); + + public static void displaySummary(HashMap summary) { + assert summary.containsKey("timeElapsed"); + assert summary.containsKey("gameMode"); + assert summary.containsKey("WPM"); + assert summary.containsKey("errorWordCount"); + assert summary.containsKey("correctWordCount"); + assert summary.containsKey("totalWordCount"); + assert summary.containsKey("errorWordPercentage"); + assert summary.containsKey("correctWordPercentage"); + assert summary.containsKey("errorWords"); + + + assert summary.get("timeElapsed") instanceof Double; + assert summary.get("gameMode") instanceof String; + assert summary.get("WPM") instanceof Double; + printOverview((Double) summary.get("timeElapsed"), (String) summary.get("gameMode"), (Double) summary.get("WPM")); + assert summary.get("errorWordCount") instanceof Integer; + assert summary.get("errorWordPercentage") instanceof Double; + printErrorStatistics((Integer) summary.get("errorWordCount"), (Double) summary.get("errorWordPercentage"), (Integer) summary.get("totalWordCount")); + assert summary.get("correctWordCount") instanceof Integer; + assert summary.get("correctWordPercentage") instanceof Double; + printSuccessStatistics((Integer) summary.get("correctWordCount"), (Double) summary.get("correctWordPercentage"), (Integer) summary.get("totalWordCount")); + assert summary.get("errorWords") instanceof List; + printErrorWords((List) summary.get("errorWords")); + } + + private static void printErrorStatistics(int errorWordCount, double errorWordPercentage, int totalWordCount) { + System.out.print("Number of Wrong Words: " + + errorWordCount + + "/" + + totalWordCount + + "|" + String.format("%.2f", errorWordPercentage) + "%"); + } + + private static void printSuccessStatistics(int correctWordCount, double correctWordPercentage, int totalWordCount) { + System.out.print("Number of Correct Words: " + + correctWordCount + + "/" + + totalWordCount + + "|" + String.format("%.2f", correctWordPercentage) + "%"); + } + + private static void printErrorWords(List errorWords) { + setUpLog(); + if (errorWords == null) { + out.print("No words typed wrongly.\n"); + return; + } + for (int i = 0; i < errorWords.size(); i++) { + assert errorWords != null; + if (i != 0 && i % 8 == 0) { + out.print("\n"); + } + out.print(errorWords.get(i)); + if (i != (errorWords.size() - 1)) { + out.print("|"); + } + } + if ((errorWords.size() - 1) % 8 != 0) { + out.print("\n"); + } + } + + private static void printOverview(double timeElapsed, String gameMode, double wpm) { + System.out.print(SUMMARY + '\n'); + System.out.println("Game Mode: " + gameMode); + System.out.print("WPM: " + String.format("%.2f", wpm) + '\n'); + System.out.print("Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n"); + } + + private static void setUpLog() { + LogManager.getLogManager().reset(); + LOGGER.setLevel(Level.ALL); + + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.SEVERE); + LOGGER.addHandler(ch); + + try { + FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); + fh.setFormatter(new SimpleFormatter()); + fh.setLevel(Level.FINE); + LOGGER.addHandler(fh); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); + } + + LOGGER.info("Set up log in TextUi"); + } + + +} diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 1e7c73b182..6f2d5e6136 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -26,12 +26,7 @@ import java.util.List; import java.util.ArrayList; import java.util.Scanner; -import java.util.logging.Logger; -import java.util.logging.LogManager; -import java.util.logging.Level; -import java.util.logging.SimpleFormatter; -import java.util.logging.FileHandler; -import java.util.logging.ConsoleHandler; + /** * Text UI of the application. @@ -42,7 +37,7 @@ public class TextUi { private static final String DIVIDER = "==========================================================="; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); - private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); + //get current timestamp //unused because it interferes with the EXPECTED.TXT in runtest @@ -221,44 +216,7 @@ public void showAnimatedSummary(int errorWordCount, double errorPercentage, doub viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); } - void printErrorWords(List errorWords) { - setUpLog(); - if (errorWords == null) { - out.print("No words typed wrongly.\n"); - return; - } - for (int i = 0; i < errorWords.size(); i++) { - assert errorWords != null; - if (i != 0 && i % 8 == 0) { - out.print("\n"); - } - out.print(errorWords.get(i)); - if (i != (errorWords.size() - 1)) { - out.print("|"); - } - } - if ((errorWords.size() - 1) % 8 != 0) { - out.print("\n"); - } - } - void setUpLog() { - LogManager.getLogManager().reset(); - LOGGER.setLevel(Level.ALL); - - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(Level.SEVERE); - LOGGER.addHandler(ch); - - try { - FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); - fh.setFormatter(new SimpleFormatter()); - fh.setLevel(Level.FINE); - LOGGER.addHandler(fh); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); - } - LOGGER.info("Set up log in TextUi"); - } + } From abdca6417e31ce7ae3bdef7d269c78e4962fc89d Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 25 Oct 2021 21:36:38 +0800 Subject: [PATCH 110/272] Change signature of some methods in SummaryManager and SummaryUI. --- .../typists/command/TimeGameCommand.java | 3 +- src/main/java/seedu/typists/game/Game.java | 14 ++++ .../seedu/typists/game/SummaryManager.java | 75 ++++++++++--------- .../typists/game/WordLimitDataProcessor.java | 8 +- .../seedu/typists/game/WordLimitGame.java | 11 +-- .../seedu/typists/parser/StringParser.java | 4 +- src/main/java/seedu/typists/ui/TextUi.java | 9 +-- .../java/seedu/typists/ui/TextUiTest.java | 4 +- 8 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index f84f2a77da..5db90cba03 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -31,8 +31,9 @@ public void process(TimeModeGame tg) { public void printUserInput(TimeModeGame tg) { uiBot.printScreen("user input is: "); - for (String[] sa: tg.userLines) { + for (String[] sa : tg.userLines) { uiBot.printScreen(Arrays.toString(sa)); } } + } diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 9240ef01a8..e3c3134b58 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -1,7 +1,12 @@ package seedu.typists.game; +import seedu.typists.ui.SummaryUI; import seedu.typists.ui.TextUi; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + public abstract class Game { protected final TextUi ui; @@ -18,4 +23,13 @@ public double duration(long startTime, long endTime) { } public abstract void runGame(); + + public void handleSummary(ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode) { + HashMap summary = SummaryManager.generateSummary(expectedInput, actualInput, timeElapsed, gameMode); + SummaryUI.displaySummary(summary); + } + + public void handleStorage() { + + } } diff --git a/src/main/java/seedu/typists/game/SummaryManager.java b/src/main/java/seedu/typists/game/SummaryManager.java index 917363fb14..daf2cca5c5 100644 --- a/src/main/java/seedu/typists/game/SummaryManager.java +++ b/src/main/java/seedu/typists/game/SummaryManager.java @@ -7,7 +7,7 @@ public class SummaryManager { public static HashMap generateSummary( - List expectedInput, List actualInput, double timeElapsed, String gameMode) { + ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode) { HashMap summary = new HashMap<>(); summary.put("timeElapsed", timeElapsed); @@ -18,72 +18,75 @@ public static HashMap generateSummary( summary.put("errorWordPercentage", calculateErrorWordsPercentage(actualInput, expectedInput)); summary.put("correctWordPercentage", calculateCorrectWordsPercentage(actualInput, expectedInput)); summary.put("wordPerMinute", calculateWPM(timeElapsed, actualInput, expectedInput)); - summary.put("errorWords", getErrorWords(actualInput,expectedInput)); + summary.put("errorWords", getErrorWords(actualInput, expectedInput)); return summary; } - private static List getErrorWords(List actualInput, List expectedInput) { - List errorWords= new ArrayList(); + private static List getErrorWords(ArrayList actualInput, ArrayList expectedInput) { + List errorWords = new ArrayList(); - for (String userWord : actualInput) { + for (String[] userLine : actualInput) + for (String userWord : userLine) { - if (expectedInput.isEmpty()) { - break; - } + if (expectedInput.isEmpty()) { + break; + } - int result = expectedInput.indexOf(userWord); + int result = expectedInput.indexOf(userWord); - if (result == -1) { - String errorWord = userWord; - errorWords.add(userWord); - } else { - expectedInput.remove(result); - } + if (result == -1) { + String errorWord = userWord; + errorWords.add(userWord); + } else { + expectedInput.remove(result); + } - } + } return errorWords; } private static Double calculateCorrectWordsPercentage( - List actualInput, List expectedInput) { + ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); int totalWordCount = calculateTotalWordCount(expectedInput); - double correctWordsPercentage = ((double)correctWordCount / (double)totalWordCount) * 100; + double correctWordsPercentage = ((double) correctWordCount / (double) totalWordCount) * 100; return correctWordsPercentage; } - private static Double calculateWPM(Double timeElapsed, List actualInput, List expectedInput) { + private static Double calculateWPM(Double timeElapsed, ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); - double wordPerMinute = (double)correctWordCount / timeElapsed; + double wordPerMinute = (double) correctWordCount / timeElapsed; return wordPerMinute; } - private static int calculateCorrectWordCount(List actualInput, List expectedInput) { + private static int calculateCorrectWordCount(ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = 0; - for (String userWord : actualInput) { + for (String[] userLine : actualInput) { + for (String userWord : userLine) { - if (expectedInput.isEmpty()) { - break; - } + if (expectedInput.isEmpty()) { + break; + } - int result = expectedInput.indexOf(userWord); + int result = expectedInput.indexOf(userWord); - if (result == -1) { - continue; - } else { - expectedInput.remove(result); - correctWordCount++; - } + if (result == -1) { + continue; + } else { + expectedInput.remove(result); + correctWordCount++; + } + } } return correctWordCount; } - private static int calculateErrorWordCount(List actualInput, List expectedInput) { + private static int calculateErrorWordCount(ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); assert correctWordCount >= 0; int totalWordCount = calculateTotalWordCount(expectedInput); @@ -93,14 +96,14 @@ private static int calculateErrorWordCount(List actualInput, List actualInput, List expectedInput) { + private static Double calculateErrorWordsPercentage(ArrayList actualInput, ArrayList expectedInput) { int errorWordCount = calculateErrorWordCount(actualInput, expectedInput); int totalWordCount = calculateTotalWordCount(expectedInput); - double errorWordsPercentage = ((double)errorWordCount / (double)totalWordCount) * 100; + double errorWordsPercentage = ((double) errorWordCount / (double) totalWordCount) * 100; return errorWordsPercentage; } - private static int calculateTotalWordCount(List expectedInput) { + private static int calculateTotalWordCount(ArrayList expectedInput) { int totalWordCount = expectedInput.size(); return totalWordCount; } diff --git a/src/main/java/seedu/typists/game/WordLimitDataProcessor.java b/src/main/java/seedu/typists/game/WordLimitDataProcessor.java index 1efd18b866..3351d1e282 100644 --- a/src/main/java/seedu/typists/game/WordLimitDataProcessor.java +++ b/src/main/java/seedu/typists/game/WordLimitDataProcessor.java @@ -13,8 +13,9 @@ public class WordLimitDataProcessor { /** * Ture if the 2 inputs are different. + * * @param input one of inputs - * @param text another input + * @param text another input */ public WordLimitDataProcessor(String input, String text) { this.userInput = input; @@ -24,6 +25,7 @@ public WordLimitDataProcessor(String input, String text) { /** * Get exit. + * * @return obtain the Exit status */ public Boolean getIsExit() { @@ -31,8 +33,8 @@ public Boolean getIsExit() { } public int getError() throws InvalidStringInputException { - ArrayList userInput0 = splitString(userInput," "); - ArrayList contentWords0 = splitString(contentWords," "); + ArrayList userInput0 = splitString(userInput, " "); + ArrayList contentWords0 = splitString(contentWords, " "); ArrayList list3 = new ArrayList(); for (int i = 0; i < contentWords0.size(); i++) { diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 31d43ea14f..a828c51640 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -2,6 +2,7 @@ import seedu.typists.exception.InvalidStringInputException; import seedu.typists.ui.TextUi; + import java.util.ArrayList; import java.util.Scanner; @@ -92,7 +93,7 @@ public void game() throws InterruptedException, InvalidStringInputException { break; } - WordLimitDataProcessor recordError = new WordLimitDataProcessor(fullCommand, temp); + WordLimitDataProcessor recordError = new WordLimitDataProcessor(fullCommand, temp); try { totalError += recordError.getError(); } catch (InvalidStringInputException e) { @@ -100,13 +101,13 @@ public void game() throws InterruptedException, InvalidStringInputException { //do something } //isExit = recordError.getIsExit(); - ui.printGameMode1Progress(gameIndex,getTotalSentence()); + ui.printGameMode1Progress(gameIndex, getTotalSentence()); if (gameIndex >= getTotalSentence()) { ui.showAnimatedError( - splitString(actualWord.trim()," "), - splitString(inputWord.trim()," "), - getTotalSentence() + splitString(actualWord.trim(), " "), + splitString(inputWord.trim(), " "), + getTotalSentence() ); break; } diff --git a/src/main/java/seedu/typists/parser/StringParser.java b/src/main/java/seedu/typists/parser/StringParser.java index 085e71fe77..da1d606c39 100644 --- a/src/main/java/seedu/typists/parser/StringParser.java +++ b/src/main/java/seedu/typists/parser/StringParser.java @@ -10,8 +10,8 @@ public class StringParser { /** * Splits the string based on the separator provided as parameter. * - * @param s the string to be split - * @param separator a string representing the separator that you want to split the string on + * @param s the string to be split + * @param separator a string representing the separator that you want to split the string on * @return ArrayList of strings */ public static ArrayList splitString(String s, String separator) throws InvalidStringInputException { diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index cdfd9a3a00..3669e4636a 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,6 +1,7 @@ package seedu.typists.ui; import java.io.IOException; + import seedu.typists.common.Error; import seedu.typists.content.Animation; @@ -190,7 +191,7 @@ public void showAnimatedError(ArrayList content, } - public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, + /*public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, int totalWordTyped, double gameTime) { assert errorWordCount >= 0; assert errorPercentage >= 0; @@ -205,10 +206,10 @@ public void showSummary(int errorWordCount, double errorPercentage, List printErrorWords(errorWords); out.print("WPM: " + String.format("%.2f", wpm) + '\n'); out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); - } + }*/ public void showAnimatedSummary(int errorWordCount, double errorPercentage, double wpm, - int totalWordTyped, double gameTime) throws InterruptedException { + int totalWordTyped, double gameTime) throws InterruptedException { out.print(SUMMARY + '\n'); viewAnimateRight("Wrong Words: " + errorWordCount + "/" + totalWordTyped); viewAnimateRight("Error Percentage: " + String.format("%.2f", errorPercentage)); @@ -217,6 +218,4 @@ public void showAnimatedSummary(int errorWordCount, double errorPercentage, doub } - - } diff --git a/src/test/java/seedu/typists/ui/TextUiTest.java b/src/test/java/seedu/typists/ui/TextUiTest.java index e1a83807fa..7909b54573 100644 --- a/src/test/java/seedu/typists/ui/TextUiTest.java +++ b/src/test/java/seedu/typists/ui/TextUiTest.java @@ -14,7 +14,7 @@ class TextUiTest { //This code (lines 15 to 38) was referenced from https://www.baeldung.com/java-testing-system-out-println - private final PrintStream standardOut = System.out; + /*private final PrintStream standardOut = System.out; private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); @BeforeEach @@ -79,5 +79,5 @@ void printErrorWords_notMultipleOfEight() { textUi.printErrorWords(errorWords); String actual = outputStreamCaptor.toString(); assertEquals(expected, actual); - } + }*/ } \ No newline at end of file From 1f78765fdcbb4157d75d77f0978991abc10cc177 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 25 Oct 2021 22:11:05 +0800 Subject: [PATCH 111/272] more OOP for game class --- src/main/java/seedu/typists/game/Game.java | 7 ++++++ .../java/seedu/typists/game/TimeModeGame.java | 25 +++++++++++++------ .../seedu/typists/game/WordLimitGame.java | 10 ++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 9240ef01a8..47c105f5b1 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -2,9 +2,14 @@ import seedu.typists.ui.TextUi; +import java.util.ArrayList; + public abstract class Game { protected final TextUi ui; + public ArrayList displayedLines; + public ArrayList userLines; + public Game() { this.ui = new TextUi(); } @@ -18,4 +23,6 @@ public double duration(long startTime, long endTime) { } public abstract void runGame(); + public abstract void store(); + public abstract void getSummary(); } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index c3e68dd457..a4e2e47ed4 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -6,24 +6,23 @@ import java.util.logging.Level; import java.util.logging.Logger; - import static seedu.typists.common.Utils.getWordLineFromStringArray; import static seedu.typists.common.Utils.getWordLines; public class TimeModeGame extends Game { - private static final Logger logger = Logger.getLogger("Foo"); - + protected static final Logger logger = Logger.getLogger("Foo"); + protected int gameTime; protected final ArrayList wordLines; - public ArrayList userLines; - protected int gameTime; - protected double realGameTime; + + public double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { super(); assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLines = getWordLines(targetWordSet, wordsPerLine); this.userLines = new ArrayList<>(); + this.displayedLines = new ArrayList<>(); this.gameTime = getGameTime(); } @@ -64,7 +63,9 @@ public void runGame() { realGameTime = (double) currTime / 1000; } else { try { - ui.printLine(wordLines.get(i)); + String[] display = wordLines.get(i); + ui.printLine(display); + displayedLines.add(display); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "no more content."); } @@ -77,6 +78,16 @@ public void runGame() { } } + @Override + public void store() { + + } + + @Override + public void getSummary() { + + } + public void updateUserLines(List stringArray) { userLines = getWordLineFromStringArray(stringArray); } diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 31d43ea14f..8074d841ef 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -38,6 +38,16 @@ public void runGame() { } } + @Override + public void store() { + + } + + @Override + public void getSummary() { + + } + public int getTotalSentence() { return eachWord.size(); } From 29e07fda8b1899f45c662962e22dd80c44f7f099 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 01:01:39 +0800 Subject: [PATCH 112/272] Debug summary feature, Link summary feature to game, create some classes for future use. Create GameRecordManager and GameRecord for storage feature. --- .../java/seedu/typists/game/GameRecord.java | 36 +++++ .../typists/game/GameRecordsManager.java | 53 ++++++++ .../seedu/typists/game/SummaryManager.java | 126 ++++++++++++------ .../java/seedu/typists/game/TimeModeGame.java | 1 + src/main/java/seedu/typists/ui/SummaryUI.java | 6 +- 5 files changed, 176 insertions(+), 46 deletions(-) create mode 100644 src/main/java/seedu/typists/game/GameRecord.java create mode 100644 src/main/java/seedu/typists/game/GameRecordsManager.java diff --git a/src/main/java/seedu/typists/game/GameRecord.java b/src/main/java/seedu/typists/game/GameRecord.java new file mode 100644 index 0000000000..98684570f1 --- /dev/null +++ b/src/main/java/seedu/typists/game/GameRecord.java @@ -0,0 +1,36 @@ +package seedu.typists.game; + +import java.util.ArrayList; + +public class GameRecord { + + private String gameMode; + private double timeElapsed; + private int errorWordCount; + private int correctWordCount; + private int totalWordCount; + private double errorWordPercentage; + private double correctWordPercentage; + private double wpm; + private ArrayList errorWords; + + public GameRecord(String gameMode, double timeElapsed, int errorWordCount, int correctWordCount, int totalWordCount, + double errorWordPercentage, double correctWordPercentage, double wpm, ArrayList errorWords) { + + this.gameMode = gameMode; + this.timeElapsed = timeElapsed; + this.errorWordCount = errorWordCount; + this.correctWordCount = correctWordCount; + this.totalWordCount = totalWordCount; + this.errorWordPercentage = errorWordPercentage; + this.correctWordPercentage = correctWordPercentage; + this.wpm = wpm; + this.errorWords = errorWords; + } + + public String getGameMode() { + return gameMode; + } + + +} diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java new file mode 100644 index 0000000000..fec8e86da0 --- /dev/null +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -0,0 +1,53 @@ +package seedu.typists.game; + +import java.util.ArrayList; +import java.util.HashMap; + +public class GameRecordsManager { + + private static GameRecordsManager instance = null; + private ArrayList timeLimitedGameRecords = null; + private ArrayList wordLimitedGameRecords = null; + + private GameRecordsManager() { + // get gameRecords using some file reader. + } + + public static GameRecordsManager getGameRecordsManager() { + if (instance == null) { + instance = new GameRecordsManager(); + } + return instance; + } + + public void addGameRecord(HashMap gameSummary) { + GameRecord newGameRecord = createGameRecord(gameSummary); + addRecordToArray(newGameRecord); + } + + private GameRecord createGameRecord(HashMap gameSummary) { + String gameMode = (String) gameSummary.get("gameMode"); + double timeElapsed = (Double) gameSummary.get("timeElapsed"); + double wpm = (Double) gameSummary.get("wordsPerMinute"); + int errorWordCount = (Integer) gameSummary.get("errorWordCount"); + int correctWordCount = (Integer) gameSummary.get("correctWordCount"); + int totalWordCount = (Integer) gameSummary.get("totalWordCount"); + double errorWordPercentage = (Double) gameSummary.get("errorWordPercentage"); + double correctWordPercentage = (Double) gameSummary.get("correctWordPercentage"); + ArrayList errorWords = (ArrayList) gameSummary.get("errorWords"); + + GameRecord newGameRecord = new GameRecord(gameMode, timeElapsed, errorWordCount, correctWordCount, totalWordCount, + errorWordPercentage, correctWordPercentage, wpm, errorWords); + return newGameRecord; + } + + private void addRecordToArray(GameRecord gameRecord) { + String gameMode = gameRecord.getGameMode(); + if (gameMode == "Word Limited") { + wordLimitedGameRecords.add(gameRecord); + } else { + timeLimitedGameRecords.add(gameRecord); + } + } + +} diff --git a/src/main/java/seedu/typists/game/SummaryManager.java b/src/main/java/seedu/typists/game/SummaryManager.java index daf2cca5c5..641aec2390 100644 --- a/src/main/java/seedu/typists/game/SummaryManager.java +++ b/src/main/java/seedu/typists/game/SummaryManager.java @@ -1,14 +1,20 @@ package seedu.typists.game; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; -import java.util.List; + public class SummaryManager { public static HashMap generateSummary( ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode) { + assert timeElapsed >= 0; + assert expectedInput != null; + assert actualInput != null; + assert ((gameMode.equals("Word-limited")) || (gameMode.equals("Time-limited"))); + HashMap summary = new HashMap<>(); summary.put("timeElapsed", timeElapsed); summary.put("gameMode", gameMode); @@ -17,86 +23,109 @@ public static HashMap generateSummary( summary.put("totalWordCount", calculateTotalWordCount(expectedInput)); summary.put("errorWordPercentage", calculateErrorWordsPercentage(actualInput, expectedInput)); summary.put("correctWordPercentage", calculateCorrectWordsPercentage(actualInput, expectedInput)); - summary.put("wordPerMinute", calculateWPM(timeElapsed, actualInput, expectedInput)); + summary.put("wordsPerMinute", calculateWPM(timeElapsed, actualInput, expectedInput)); summary.put("errorWords", getErrorWords(actualInput, expectedInput)); return summary; } - private static List getErrorWords(ArrayList actualInput, ArrayList expectedInput) { - List errorWords = new ArrayList(); + private static ArrayList getErrorWords( + ArrayList actualInput, ArrayList expectedInput) { - for (String[] userLine : actualInput) - for (String userWord : userLine) { + ArrayList errorWords = new ArrayList<>(); + ArrayList mergedExpectedInput = mergeArrays(expectedInput); - if (expectedInput.isEmpty()) { - break; - } + if (actualInput.isEmpty()) { + return mergedExpectedInput; + } - int result = expectedInput.indexOf(userWord); + ArrayList mergedActualInput = mergeArrays(actualInput); - if (result == -1) { - String errorWord = userWord; - errorWords.add(userWord); - } else { - expectedInput.remove(result); - } + int count = 0; + for (String expectedWord : mergedExpectedInput) { + if (mergedActualInput.isEmpty()) { + break; } - return errorWords; - } + int result = mergedActualInput.indexOf(expectedWord); - private static Double calculateCorrectWordsPercentage( - ArrayList actualInput, ArrayList expectedInput) { - int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); - int totalWordCount = calculateTotalWordCount(expectedInput); - double correctWordsPercentage = ((double) correctWordCount / (double) totalWordCount) * 100; - return correctWordsPercentage; - } + if (result == -1) { + String errorWord = expectedWord; + errorWords.add(errorWord); + } else { + mergedActualInput.remove(result); + } + count++; + } - private static Double calculateWPM(Double timeElapsed, ArrayList actualInput, ArrayList expectedInput) { - int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); - double wordPerMinute = (double) correctWordCount / timeElapsed; - return wordPerMinute; + if (count != calculateTotalWordCount(expectedInput)) { + for (int i = count; i < calculateTotalWordCount(expectedInput); i++) { + errorWords.add(mergedExpectedInput.get(i)); + } + } + + return errorWords; } private static int calculateCorrectWordCount(ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = 0; - for (String[] userLine : actualInput) { - for (String userWord : userLine) { + ArrayList mergedExpectedInput = mergeArrays(expectedInput); + if (actualInput.isEmpty()) { + return correctWordCount; + } + ArrayList mergedActualInput = mergeArrays(actualInput); - if (expectedInput.isEmpty()) { - break; - } + for (String userWord : mergedActualInput) { - int result = expectedInput.indexOf(userWord); + if (mergedExpectedInput.isEmpty()) { + break; + } - if (result == -1) { - continue; - } else { - expectedInput.remove(result); - correctWordCount++; - } + int result = mergedExpectedInput.indexOf(userWord); + if (result == -1) { + continue; + } else { + mergedExpectedInput.remove(result); + correctWordCount++; } + } return correctWordCount; + } + private static Double calculateCorrectWordsPercentage( + ArrayList actualInput, ArrayList expectedInput) { + int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); + int totalWordCount = calculateTotalWordCount(expectedInput); + double correctWordsPercentage = ((double) correctWordCount / (double) totalWordCount) * 100; + return correctWordsPercentage; } + private static Double calculateWPM( + Double timeElapsed, ArrayList actualInput, ArrayList expectedInput) { + int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); + double wordPerMinute = ((double) correctWordCount / timeElapsed) * 60; + return wordPerMinute; + } + + private static int calculateErrorWordCount(ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); assert correctWordCount >= 0; + int totalWordCount = calculateTotalWordCount(expectedInput); assert correctWordCount >= 0; + assert totalWordCount >= correctWordCount; int errorWordCount = totalWordCount - correctWordCount; return errorWordCount; } - private static Double calculateErrorWordsPercentage(ArrayList actualInput, ArrayList expectedInput) { + private static Double calculateErrorWordsPercentage( + ArrayList actualInput, ArrayList expectedInput) { int errorWordCount = calculateErrorWordCount(actualInput, expectedInput); int totalWordCount = calculateTotalWordCount(expectedInput); double errorWordsPercentage = ((double) errorWordCount / (double) totalWordCount) * 100; @@ -104,9 +133,20 @@ private static Double calculateErrorWordsPercentage(ArrayList actualIn } private static int calculateTotalWordCount(ArrayList expectedInput) { - int totalWordCount = expectedInput.size(); + ArrayList mergedExpectedInput = mergeArrays(expectedInput); + int totalWordCount = mergedExpectedInput.size(); return totalWordCount; } + private static ArrayList mergeArrays(ArrayList arrayToMerge) { + ArrayList mergedArr = new ArrayList<>(); + + for (String[] array : arrayToMerge) { + ArrayList tempArr = new ArrayList<>(Arrays.asList(array)); + mergedArr.addAll(tempArr); + } + + return mergedArr; + } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index c3e68dd457..cf92dd2403 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -74,6 +74,7 @@ public void runGame() { } updateUserLines(inputs); ui.printScreen("Game Finished."); + handleSummary(wordLines, userLines, realGameTime, "Word-limited"); } } diff --git a/src/main/java/seedu/typists/ui/SummaryUI.java b/src/main/java/seedu/typists/ui/SummaryUI.java index 7885ffd39a..e1a2ac4925 100644 --- a/src/main/java/seedu/typists/ui/SummaryUI.java +++ b/src/main/java/seedu/typists/ui/SummaryUI.java @@ -20,7 +20,7 @@ public class SummaryUI { public static void displaySummary(HashMap summary) { assert summary.containsKey("timeElapsed"); assert summary.containsKey("gameMode"); - assert summary.containsKey("WPM"); + assert summary.containsKey("wordsPerMinute"); assert summary.containsKey("errorWordCount"); assert summary.containsKey("correctWordCount"); assert summary.containsKey("totalWordCount"); @@ -31,8 +31,8 @@ public static void displaySummary(HashMap summary) { assert summary.get("timeElapsed") instanceof Double; assert summary.get("gameMode") instanceof String; - assert summary.get("WPM") instanceof Double; - printOverview((Double) summary.get("timeElapsed"), (String) summary.get("gameMode"), (Double) summary.get("WPM")); + assert summary.get("wordsPerMinute") instanceof Double; + printOverview((Double) summary.get("timeElapsed"), (String) summary.get("gameMode"), (Double) summary.get("wordsPerMinute")); assert summary.get("errorWordCount") instanceof Integer; assert summary.get("errorWordPercentage") instanceof Double; printErrorStatistics((Integer) summary.get("errorWordCount"), (Double) summary.get("errorWordPercentage"), (Integer) summary.get("totalWordCount")); From d5f493c4b6c660046df565190fc7edb5ae7d7fb6 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 12:38:56 +0800 Subject: [PATCH 113/272] Redo logic of calculating error words, error word counts, and correct word counts in SummaryManager --- src/main/java/seedu/typists/game/Game.java | 13 ++- .../java/seedu/typists/game/GameRecord.java | 6 +- .../typists/game/GameRecordsManager.java | 6 +- .../seedu/typists/game/SummaryManager.java | 97 ++++++++----------- .../ui/{SummaryUI.java => SummaryUi.java} | 24 +++-- 5 files changed, 76 insertions(+), 70 deletions(-) rename src/main/java/seedu/typists/ui/{SummaryUI.java => SummaryUi.java} (83%) diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index e3c3134b58..95899dc387 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -1,11 +1,10 @@ package seedu.typists.game; -import seedu.typists.ui.SummaryUI; +import seedu.typists.ui.SummaryUi; import seedu.typists.ui.TextUi; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; public abstract class Game { protected final TextUi ui; @@ -24,9 +23,13 @@ public double duration(long startTime, long endTime) { public abstract void runGame(); - public void handleSummary(ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode) { - HashMap summary = SummaryManager.generateSummary(expectedInput, actualInput, timeElapsed, gameMode); - SummaryUI.displaySummary(summary); + public void handleSummary( + ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode + ) { + HashMap summary = SummaryManager.generateSummary( + expectedInput, actualInput, timeElapsed, gameMode + ); + SummaryUi.displaySummary(summary); } public void handleStorage() { diff --git a/src/main/java/seedu/typists/game/GameRecord.java b/src/main/java/seedu/typists/game/GameRecord.java index 98684570f1..c63ca3523b 100644 --- a/src/main/java/seedu/typists/game/GameRecord.java +++ b/src/main/java/seedu/typists/game/GameRecord.java @@ -14,8 +14,10 @@ public class GameRecord { private double wpm; private ArrayList errorWords; - public GameRecord(String gameMode, double timeElapsed, int errorWordCount, int correctWordCount, int totalWordCount, - double errorWordPercentage, double correctWordPercentage, double wpm, ArrayList errorWords) { + public GameRecord( + String gameMode, double timeElapsed, int errorWordCount, int correctWordCount, int totalWordCount, + double errorWordPercentage, double correctWordPercentage, double wpm, ArrayList errorWords + ) { this.gameMode = gameMode; this.timeElapsed = timeElapsed; diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index fec8e86da0..7e882a54a4 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -36,8 +36,10 @@ private GameRecord createGameRecord(HashMap gameSummary) { double correctWordPercentage = (Double) gameSummary.get("correctWordPercentage"); ArrayList errorWords = (ArrayList) gameSummary.get("errorWords"); - GameRecord newGameRecord = new GameRecord(gameMode, timeElapsed, errorWordCount, correctWordCount, totalWordCount, - errorWordPercentage, correctWordPercentage, wpm, errorWords); + GameRecord newGameRecord = new GameRecord( + gameMode, timeElapsed, errorWordCount, correctWordCount, totalWordCount, + errorWordPercentage, correctWordPercentage, wpm, errorWords + ); return newGameRecord; } diff --git a/src/main/java/seedu/typists/game/SummaryManager.java b/src/main/java/seedu/typists/game/SummaryManager.java index 641aec2390..7fd363afd7 100644 --- a/src/main/java/seedu/typists/game/SummaryManager.java +++ b/src/main/java/seedu/typists/game/SummaryManager.java @@ -11,7 +11,7 @@ public static HashMap generateSummary( ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode) { assert timeElapsed >= 0; - assert expectedInput != null; + assert expectedInput.size() > 0; assert actualInput != null; assert ((gameMode.equals("Word-limited")) || (gameMode.equals("Time-limited"))); @@ -23,7 +23,7 @@ public static HashMap generateSummary( summary.put("totalWordCount", calculateTotalWordCount(expectedInput)); summary.put("errorWordPercentage", calculateErrorWordsPercentage(actualInput, expectedInput)); summary.put("correctWordPercentage", calculateCorrectWordsPercentage(actualInput, expectedInput)); - summary.put("wordsPerMinute", calculateWPM(timeElapsed, actualInput, expectedInput)); + summary.put("wordsPerMinute", calculateWpm(timeElapsed, actualInput, expectedInput)); summary.put("errorWords", getErrorWords(actualInput, expectedInput)); return summary; } @@ -32,68 +32,64 @@ private static ArrayList getErrorWords( ArrayList actualInput, ArrayList expectedInput) { ArrayList errorWords = new ArrayList<>(); - ArrayList mergedExpectedInput = mergeArrays(expectedInput); if (actualInput.isEmpty()) { + ArrayList mergedExpectedInput = mergeArrays(expectedInput); return mergedExpectedInput; } - ArrayList mergedActualInput = mergeArrays(actualInput); - - int count = 0; - for (String expectedWord : mergedExpectedInput) { + int totalExpectedLines = expectedInput.size(); + int outerLoopCount; + for (outerLoopCount = 0; outerLoopCount < totalExpectedLines; outerLoopCount++) { - if (mergedActualInput.isEmpty()) { + if (actualInput.size() == outerLoopCount) { + ArrayList remainingLines = new ArrayList<>( + expectedInput.subList(outerLoopCount, totalExpectedLines) + ); + ArrayList mergedRemainingLines = mergeArrays(remainingLines); + errorWords.addAll(mergedRemainingLines); break; } - int result = mergedActualInput.indexOf(expectedWord); - - if (result == -1) { - String errorWord = expectedWord; - errorWords.add(errorWord); - } else { - mergedActualInput.remove(result); - } - count++; - } - - if (count != calculateTotalWordCount(expectedInput)) { - for (int i = count; i < calculateTotalWordCount(expectedInput); i++) { - errorWords.add(mergedExpectedInput.get(i)); - } - } - - return errorWords; - } + ArrayList expectedLine = new ArrayList<>(Arrays.asList(expectedInput.get(outerLoopCount))); + assert expectedLine.size() > 0; + ArrayList actualLine = new ArrayList<>(Arrays.asList(actualInput.get(outerLoopCount))); - private static int calculateCorrectWordCount(ArrayList actualInput, ArrayList expectedInput) { - int correctWordCount = 0; - - ArrayList mergedExpectedInput = mergeArrays(expectedInput); - if (actualInput.isEmpty()) { - return correctWordCount; - } - ArrayList mergedActualInput = mergeArrays(actualInput); + for (String expectedWord : expectedLine) { - for (String userWord : mergedActualInput) { + int innerLoopCount = 0; + if (actualLine.size() == 0) { + ArrayList remainingWords = new ArrayList<>( + expectedLine.subList(innerLoopCount, expectedLine.size()) + ); + errorWords.addAll(remainingWords); + break; + } - if (mergedExpectedInput.isEmpty()) { - break; - } + int result = actualLine.indexOf(expectedWord); - int result = mergedExpectedInput.indexOf(userWord); + if (result == -1) { + String errorWord = expectedWord; + errorWords.add(errorWord); + } else { + actualLine.remove(result); + } - if (result == -1) { - continue; - } else { - mergedExpectedInput.remove(result); - correctWordCount++; + innerLoopCount++; } } + return errorWords; + } + private static int calculateCorrectWordCount(ArrayList actualInput, ArrayList expectedInput) { + int errorWordCount = calculateErrorWordCount(actualInput, expectedInput); + assert errorWordCount >= 0; + int totalWordCount = calculateTotalWordCount(expectedInput); + assert totalWordCount >= errorWordCount; + int correctWordCount = totalWordCount - errorWordCount; return correctWordCount; + } private static Double calculateCorrectWordsPercentage( @@ -104,7 +100,7 @@ private static Double calculateCorrectWordsPercentage( return correctWordsPercentage; } - private static Double calculateWPM( + private static Double calculateWpm( Double timeElapsed, ArrayList actualInput, ArrayList expectedInput) { int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); double wordPerMinute = ((double) correctWordCount / timeElapsed) * 60; @@ -113,14 +109,7 @@ private static Double calculateWPM( private static int calculateErrorWordCount(ArrayList actualInput, ArrayList expectedInput) { - int correctWordCount = calculateCorrectWordCount(actualInput, expectedInput); - assert correctWordCount >= 0; - - int totalWordCount = calculateTotalWordCount(expectedInput); - assert correctWordCount >= 0; - - assert totalWordCount >= correctWordCount; - int errorWordCount = totalWordCount - correctWordCount; + int errorWordCount = getErrorWords(actualInput, expectedInput).size(); return errorWordCount; } diff --git a/src/main/java/seedu/typists/ui/SummaryUI.java b/src/main/java/seedu/typists/ui/SummaryUi.java similarity index 83% rename from src/main/java/seedu/typists/ui/SummaryUI.java rename to src/main/java/seedu/typists/ui/SummaryUi.java index e1a2ac4925..0485ace883 100644 --- a/src/main/java/seedu/typists/ui/SummaryUI.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -13,7 +13,7 @@ import static java.lang.System.out; import static seedu.typists.common.Messages.SUMMARY; -public class SummaryUI { +public class SummaryUi { private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); @@ -32,13 +32,22 @@ public static void displaySummary(HashMap summary) { assert summary.get("timeElapsed") instanceof Double; assert summary.get("gameMode") instanceof String; assert summary.get("wordsPerMinute") instanceof Double; - printOverview((Double) summary.get("timeElapsed"), (String) summary.get("gameMode"), (Double) summary.get("wordsPerMinute")); + printOverview( + (Double) summary.get("timeElapsed"), + (String) summary.get("gameMode"), + (Double) summary.get("wordsPerMinute")); assert summary.get("errorWordCount") instanceof Integer; assert summary.get("errorWordPercentage") instanceof Double; - printErrorStatistics((Integer) summary.get("errorWordCount"), (Double) summary.get("errorWordPercentage"), (Integer) summary.get("totalWordCount")); + printErrorStatistics( + (Integer) summary.get("errorWordCount"), + (Double) summary.get("errorWordPercentage"), + (Integer) summary.get("totalWordCount")); assert summary.get("correctWordCount") instanceof Integer; assert summary.get("correctWordPercentage") instanceof Double; - printSuccessStatistics((Integer) summary.get("correctWordCount"), (Double) summary.get("correctWordPercentage"), (Integer) summary.get("totalWordCount")); + printSuccessStatistics( + (Integer) summary.get("correctWordCount"), + (Double) summary.get("correctWordPercentage"), + (Integer) summary.get("totalWordCount")); assert summary.get("errorWords") instanceof List; printErrorWords((List) summary.get("errorWords")); } @@ -48,7 +57,7 @@ private static void printErrorStatistics(int errorWordCount, double errorWordPer + errorWordCount + "/" + totalWordCount - + "|" + String.format("%.2f", errorWordPercentage) + "%"); + + "|" + String.format("%.2f", errorWordPercentage) + "%\n"); } private static void printSuccessStatistics(int correctWordCount, double correctWordPercentage, int totalWordCount) { @@ -56,11 +65,12 @@ private static void printSuccessStatistics(int correctWordCount, double correctW + correctWordCount + "/" + totalWordCount - + "|" + String.format("%.2f", correctWordPercentage) + "%"); + + "|" + String.format("%.2f", correctWordPercentage) + "%\n"); } private static void printErrorWords(List errorWords) { setUpLog(); + out.print("Mistakes: "); if (errorWords == null) { out.print("No words typed wrongly.\n"); return; @@ -82,7 +92,7 @@ private static void printErrorWords(List errorWords) { private static void printOverview(double timeElapsed, String gameMode, double wpm) { System.out.print(SUMMARY + '\n'); - System.out.println("Game Mode: " + gameMode); + System.out.println("Game Mode: " + gameMode + '\n'); System.out.print("WPM: " + String.format("%.2f", wpm) + '\n'); System.out.print("Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n"); } From 78f1cf1af436af1b1d7939f46d3fac0379a5fb78 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 15:32:34 +0800 Subject: [PATCH 114/272] Add test code for SummaryUi and SummaryManager --- src/main/java/seedu/typists/ui/SummaryUi.java | 25 +-- .../typists/game/SummaryManagerTest.java | 93 ++++++++++++ .../java/seedu/typists/ui/SummaryUiTest.java | 142 ++++++++++++++++++ 3 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 src/test/java/seedu/typists/game/SummaryManagerTest.java create mode 100644 src/test/java/seedu/typists/ui/SummaryUiTest.java diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index 0485ace883..9a804a5708 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -1,6 +1,7 @@ package seedu.typists.ui; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.logging.Logger; @@ -10,7 +11,6 @@ import java.util.logging.FileHandler; import java.util.logging.ConsoleHandler; -import static java.lang.System.out; import static seedu.typists.common.Messages.SUMMARY; public class SummaryUi { @@ -49,7 +49,7 @@ public static void displaySummary(HashMap summary) { (Double) summary.get("correctWordPercentage"), (Integer) summary.get("totalWordCount")); assert summary.get("errorWords") instanceof List; - printErrorWords((List) summary.get("errorWords")); + printErrorWords((ArrayList) summary.get("errorWords")); } private static void printErrorStatistics(int errorWordCount, double errorWordPercentage, int totalWordCount) { @@ -68,31 +68,32 @@ private static void printSuccessStatistics(int correctWordCount, double correctW + "|" + String.format("%.2f", correctWordPercentage) + "%\n"); } - private static void printErrorWords(List errorWords) { + static void printErrorWords(ArrayList errorWords) { setUpLog(); - out.print("Mistakes: "); - if (errorWords == null) { - out.print("No words typed wrongly.\n"); + assert errorWords!= null; + System.out.print("Mistakes: "); + if (errorWords.size()==0) { + System.out.print("No words typed wrongly.\n"); return; } for (int i = 0; i < errorWords.size(); i++) { assert errorWords != null; - if (i != 0 && i % 8 == 0) { - out.print("\n"); + if (i % 8 == 0) { + System.out.print("\n"); } - out.print(errorWords.get(i)); + System.out.print(errorWords.get(i)); if (i != (errorWords.size() - 1)) { - out.print("|"); + System.out.print("|"); } } if ((errorWords.size() - 1) % 8 != 0) { - out.print("\n"); + System.out.print("\n"); } } private static void printOverview(double timeElapsed, String gameMode, double wpm) { System.out.print(SUMMARY + '\n'); - System.out.println("Game Mode: " + gameMode + '\n'); + System.out.print("Game Mode: " + gameMode + '\n'); System.out.print("WPM: " + String.format("%.2f", wpm) + '\n'); System.out.print("Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n"); } diff --git a/src/test/java/seedu/typists/game/SummaryManagerTest.java b/src/test/java/seedu/typists/game/SummaryManagerTest.java new file mode 100644 index 0000000000..e3d11cfebf --- /dev/null +++ b/src/test/java/seedu/typists/game/SummaryManagerTest.java @@ -0,0 +1,93 @@ +package seedu.typists.game; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SummaryManagerTest { + + @Test + void generateSummary_0ErrorWords() { + ArrayList expectedInput = new ArrayList<>(); + expectedInput.add(new String[]{"one", "two", "three", "four"}); + expectedInput.add(new String[]{"five", "six", "seven", "eight", "nine", "ten"}); + int totalWordCount = expectedInput.get(0).length + expectedInput.get(1).length; + int correctWordCount = totalWordCount; + int errorWordCount = 0; + ArrayList errorWords = new ArrayList<>(); + ArrayList actualInput = new ArrayList<>(); + actualInput.addAll(expectedInput); + double timeElapsed = 10.9021; + String gameMode = "Time-limited"; + HashMap actual = SummaryManager.generateSummary(expectedInput, actualInput, timeElapsed, gameMode); + HashMap expected = initializeExpectedOutput( + timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords + ); + assertEquals(expected, actual); + } + + @Test + void generateSummary_oneLineAllErrorWords() { + ArrayList expectedInput = new ArrayList<>(); + expectedInput.add(new String[]{"one", "two", "three", "four"}); + expectedInput.add(new String[]{"five", "six", "seven", "eight", "nine", "ten"}); + ArrayList actualInput = new ArrayList<>(); + actualInput.add(expectedInput.get(0)); + actualInput.add(expectedInput.get(0)); + double timeElapsed = 10.9021; + String gameMode = "Time-limited"; + int totalWordCount = expectedInput.get(0).length + expectedInput.get(1).length; + int errorWordCount = expectedInput.get(1).length; + int correctWordCount = totalWordCount - errorWordCount; + ArrayList errorWords = new ArrayList<>(Arrays.asList(expectedInput.get(1))); + HashMap actual = SummaryManager.generateSummary( + expectedInput, actualInput, timeElapsed, gameMode + ); + HashMap expected = initializeExpectedOutput( + timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords + ); + assertEquals(expected, actual); + } + + @Test + void generateSummary_noUserInput() { + ArrayList expectedInput = new ArrayList<>(); + expectedInput.add(new String[]{"one", "two", "three", "four"}); + expectedInput.add(new String[]{"five", "six", "seven", "eight", "nine", "ten"}); + ArrayList actualInput = new ArrayList<>();double timeElapsed = 10.9021; + String gameMode = "Time-limited"; + int totalWordCount = expectedInput.get(0).length + expectedInput.get(1).length; + int errorWordCount = totalWordCount; + int correctWordCount = 0; + ArrayList errorWords = new ArrayList<>(Arrays.asList(expectedInput.get(0))); + errorWords.addAll(Arrays.asList(expectedInput.get(1))); + HashMap actual = SummaryManager.generateSummary( + expectedInput, actualInput, timeElapsed, gameMode + ); + HashMap expected = initializeExpectedOutput( + timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords + ); + assertEquals(expected, actual); + + } + HashMap initializeExpectedOutput( + double timeElapsed, String gameMode, int errorWordCount, + int correctWordCount, int totalWordCount, ArrayList errorWords + ) { + HashMap expected = new HashMap<>(); + expected.put("timeElapsed", timeElapsed); + expected.put("gameMode", gameMode); + expected.put("wordsPerMinute", (correctWordCount / timeElapsed) * 60); + expected.put("errorWordCount", errorWordCount); + expected.put("correctWordCount", correctWordCount); + expected.put("totalWordCount", totalWordCount); + expected.put("errorWordPercentage", ((double) errorWordCount / totalWordCount) * 100); + expected.put("correctWordPercentage", ((double) correctWordCount / totalWordCount) * 100); + expected.put("errorWords", errorWords); + return expected; + } +} \ No newline at end of file diff --git a/src/test/java/seedu/typists/ui/SummaryUiTest.java b/src/test/java/seedu/typists/ui/SummaryUiTest.java new file mode 100644 index 0000000000..21bb771127 --- /dev/null +++ b/src/test/java/seedu/typists/ui/SummaryUiTest.java @@ -0,0 +1,142 @@ +package seedu.typists.ui; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static seedu.typists.common.Messages.SUMMARY; + +class SummaryUiTest { + + //This code (lines 15 to 38) was referenced from https://www.baeldung.com/java-testing-system-out-println + private final PrintStream standardOut = System.out; + private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); + @BeforeEach + public void setUp() { + System.setOut(new PrintStream(outputStreamCaptor)); + } + + @Test + void displaySummary_0ErrorWords() { + double timeElapsed = 10.03221; + String gameMode = "Word-limited"; + int errorWordCount = 0; + int correctWordCount = 10; + int totalWordCount = 0; + ArrayList errorWords = new ArrayList<>(); + HashMap summary = initializeSummary( + timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords + ); + String expected = SUMMARY + '\n' + + "Game Mode: " + gameMode + '\n' + + "WPM: " + String.format("%.2f", (Double) summary.get("wordsPerMinute")) + "\n" + + "Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n" + + "Number of Wrong Words: " + errorWordCount + "/" + totalWordCount + + "|" + String.format("%.2f", summary.get("errorWordPercentage")) + "%\n" + + "Number of Correct Words: " + + correctWordCount + + "/" + + totalWordCount + + "|" + String.format("%.2f", summary.get("correctWordPercentage")) + "%\n" + + "Mistakes: No words typed wrongly.\n"; + + SummaryUi.displaySummary(summary); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + + } + + @Test + void displaySummary_noUserInput() { + double timeElapsed = 10.03221; + String gameMode = "Word-limited"; + int errorWordCount = 10; + int correctWordCount = 0; + int totalWordCount = 10; + ArrayList errorWords = new ArrayList<>( + Arrays.asList(new String[]{"one","two","three","four","five","six","seven","eight","nine","ten"}) + ); + HashMap summary = initializeSummary( + timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords + ); + String expected = SUMMARY + '\n' + + "Game Mode: " + gameMode + '\n' + + "WPM: " + String.format("%.2f", (Double) summary.get("wordsPerMinute")) + "\n" + + "Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n" + + "Number of Wrong Words: " + errorWordCount + "/" + totalWordCount + + "|" + String.format("%.2f", summary.get("errorWordPercentage")) + "%\n" + + "Number of Correct Words: " + + correctWordCount + + "/" + + totalWordCount + + "|" + String.format("%.2f", summary.get("correctWordPercentage")) + "%\n" + + "Mistakes: \n" + + "one|two|three|four|five|six|seven|eight|\n" + + "nine|ten\n"; + + SummaryUi.displaySummary(summary); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + + + @Test + void printErrorWords_multipleOfEight() { + ArrayList errorWords = new ArrayList<>(Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7", "bar8" + )); + String expected = "Mistakes: \n" + + "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7|bar8\n"; + SummaryUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @Test + void printErrorWords_notMultipleOfEight() { + ArrayList errorWords = new ArrayList<>(Arrays.asList( + "foo1", "foo2", "foo3", "foo4", "foo5", "foo6", "foo7", "foo8", + "bar1", "bar2", "bar3", "bar4", "bar5", "bar6", "bar7" + )); + String expected = "Mistakes: \n" + + "foo1|foo2|foo3|foo4|foo5|foo6|foo7|foo8|\n" + + "bar1|bar2|bar3|bar4|bar5|bar6|bar7\n"; + SummaryUi.printErrorWords(errorWords); + String actual = outputStreamCaptor.toString(); + assertEquals(expected, actual); + } + + @AfterEach + public void tearDown() { + System.setOut(standardOut); + } + + HashMap initializeSummary( + double timeElapsed, String gameMode, int errorWordCount, + int correctWordCount, int totalWordCount, ArrayList errorWords + ) { + HashMap expected = new HashMap<>(); + expected.put("timeElapsed", timeElapsed); + expected.put("gameMode", gameMode); + expected.put("wordsPerMinute", (correctWordCount / timeElapsed) * 60); + expected.put("errorWordCount", errorWordCount); + expected.put("correctWordCount", correctWordCount); + expected.put("totalWordCount", totalWordCount); + expected.put("errorWordPercentage", ((double) errorWordCount / totalWordCount) * 100); + expected.put("correctWordPercentage", ((double) correctWordCount / totalWordCount) * 100); + expected.put("errorWords", errorWords); + return expected; + + } +} \ No newline at end of file From c64423444dd26eb384e4d80f07e4c59fa851d0f8 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 15:41:59 +0800 Subject: [PATCH 115/272] Reformat code to abide by coding standard --- src/main/java/seedu/typists/ui/SummaryUi.java | 4 ++-- src/test/java/seedu/typists/game/SummaryManagerTest.java | 8 ++++++-- src/test/java/seedu/typists/ui/SummaryUiTest.java | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index 9a804a5708..dd80457beb 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -70,9 +70,9 @@ private static void printSuccessStatistics(int correctWordCount, double correctW static void printErrorWords(ArrayList errorWords) { setUpLog(); - assert errorWords!= null; + assert errorWords != null; System.out.print("Mistakes: "); - if (errorWords.size()==0) { + if (errorWords.size() == 0) { System.out.print("No words typed wrongly.\n"); return; } diff --git a/src/test/java/seedu/typists/game/SummaryManagerTest.java b/src/test/java/seedu/typists/game/SummaryManagerTest.java index e3d11cfebf..8053083fac 100644 --- a/src/test/java/seedu/typists/game/SummaryManagerTest.java +++ b/src/test/java/seedu/typists/game/SummaryManagerTest.java @@ -23,7 +23,9 @@ void generateSummary_0ErrorWords() { actualInput.addAll(expectedInput); double timeElapsed = 10.9021; String gameMode = "Time-limited"; - HashMap actual = SummaryManager.generateSummary(expectedInput, actualInput, timeElapsed, gameMode); + HashMap actual = SummaryManager.generateSummary( + expectedInput, actualInput, timeElapsed, gameMode + ); HashMap expected = initializeExpectedOutput( timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords ); @@ -58,7 +60,8 @@ void generateSummary_noUserInput() { ArrayList expectedInput = new ArrayList<>(); expectedInput.add(new String[]{"one", "two", "three", "four"}); expectedInput.add(new String[]{"five", "six", "seven", "eight", "nine", "ten"}); - ArrayList actualInput = new ArrayList<>();double timeElapsed = 10.9021; + ArrayList actualInput = new ArrayList<>(); + double timeElapsed = 10.9021; String gameMode = "Time-limited"; int totalWordCount = expectedInput.get(0).length + expectedInput.get(1).length; int errorWordCount = totalWordCount; @@ -74,6 +77,7 @@ void generateSummary_noUserInput() { assertEquals(expected, actual); } + HashMap initializeExpectedOutput( double timeElapsed, String gameMode, int errorWordCount, int correctWordCount, int totalWordCount, ArrayList errorWords diff --git a/src/test/java/seedu/typists/ui/SummaryUiTest.java b/src/test/java/seedu/typists/ui/SummaryUiTest.java index 21bb771127..a186fdd60e 100644 --- a/src/test/java/seedu/typists/ui/SummaryUiTest.java +++ b/src/test/java/seedu/typists/ui/SummaryUiTest.java @@ -19,6 +19,7 @@ class SummaryUiTest { //This code (lines 15 to 38) was referenced from https://www.baeldung.com/java-testing-system-out-println private final PrintStream standardOut = System.out; private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); + @BeforeEach public void setUp() { System.setOut(new PrintStream(outputStreamCaptor)); @@ -62,7 +63,8 @@ void displaySummary_noUserInput() { int correctWordCount = 0; int totalWordCount = 10; ArrayList errorWords = new ArrayList<>( - Arrays.asList(new String[]{"one","two","three","four","five","six","seven","eight","nine","ten"}) + Arrays.asList( + new String[]{"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}) ); HashMap summary = initializeSummary( timeElapsed, gameMode, errorWordCount, correctWordCount, totalWordCount, errorWords @@ -88,7 +90,6 @@ void displaySummary_noUserInput() { } - @Test void printErrorWords_multipleOfEight() { ArrayList errorWords = new ArrayList<>(Arrays.asList( From 3701657e8b24f7589bf9cddfbdebc065993f04b2 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 18:32:59 +0800 Subject: [PATCH 116/272] First commit of storage feature (untested) --- seedu.typists.ui.TextUi.log | 2 +- src/main/java/seedu/typists/Main.java | 6 +- .../java/seedu/typists/game/GameRecord.java | 17 ++- .../seedu/typists/storage/FileParser.java | 76 ++++++++++ .../java/seedu/typists/storage/Storage.java | 141 ++++++++++++++++++ .../seedu/typists/storage/StorageFile.java | 7 - src/main/java/seedu/typists/ui/SummaryUi.java | 6 +- 7 files changed, 241 insertions(+), 14 deletions(-) create mode 100644 src/main/java/seedu/typists/storage/FileParser.java create mode 100644 src/main/java/seedu/typists/storage/Storage.java delete mode 100644 src/main/java/seedu/typists/storage/StorageFile.java diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 8f340113de..9407182132 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 25, 2021 7:49:39 PM seedu.typists.ui.TextUi setUpLog +Oct 26, 2021 3:41:10 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in TextUi diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index d8e4f98fb9..6e60fc2638 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -5,7 +5,7 @@ import seedu.typists.command.CommandFactory; import seedu.typists.ui.TextUi; -import seedu.typists.storage.StorageFile; +import seedu.typists.storage.Storage; import java.util.Scanner; @@ -18,12 +18,12 @@ public class Main { public static final int LINE_LENGTH = 10; public static Content content; public static TextUi uiBot; - StorageFile storage; + Storage storage; public Main() { uiBot = new TextUi(); - this.storage = new StorageFile(); + this.storage = new Storage(); content = new Content(); } diff --git a/src/main/java/seedu/typists/game/GameRecord.java b/src/main/java/seedu/typists/game/GameRecord.java index c63ca3523b..39f694fbff 100644 --- a/src/main/java/seedu/typists/game/GameRecord.java +++ b/src/main/java/seedu/typists/game/GameRecord.java @@ -1,5 +1,6 @@ package seedu.typists.game; +import java.lang.reflect.Array; import java.util.ArrayList; public class GameRecord { @@ -34,5 +35,19 @@ public String getGameMode() { return gameMode; } - + public String getStringFormat() { + String separator = "\\|"; + String formatted = gameMode + + separator + + timeElapsed + + separator + + errorWordCount + + separator + + correctWordCount + + separator + + totalWordCount + + separator + + errorWords.toString(); + return formatted; + } } diff --git a/src/main/java/seedu/typists/storage/FileParser.java b/src/main/java/seedu/typists/storage/FileParser.java new file mode 100644 index 0000000000..10e8da0ad9 --- /dev/null +++ b/src/main/java/seedu/typists/storage/FileParser.java @@ -0,0 +1,76 @@ +package seedu.typists.storage; + +import seedu.typists.game.GameRecord; + +import java.util.ArrayList; +import java.util.Arrays; + +public class FileParser { + + public static GameRecord convertStringToGameRecord(String gameRecordString) { + String[] gameRecordStats = gameRecordString.split("\\|"); + assert gameRecordStats.length >= 8; + String gameMode = getGameMode(gameRecordStats); + double timeElapsed = getTimeElapsed(gameRecordStats); + int errorWordCount = getErrorWordCount(gameRecordStats); + int correctWordCount = getCorrectWordCount(gameRecordStats); + int totalWordCount = getTotalWordCount(gameRecordStats); + double errorWordPercentage = getErrorWordPercentage(gameRecordStats); + double correctWordPercentage = getCorrectWordPercentage(gameRecordStats); + double wpm = getWpm(gameRecordStats); + ArrayList errorWords = getErrorWords(gameRecordStats); + + GameRecord gameRecord = new GameRecord( + gameMode, + timeElapsed, + errorWordCount, + correctWordCount, + totalWordCount, + errorWordPercentage, + correctWordPercentage, + wpm, + errorWords + ); + return gameRecord; + } + + private static String getGameMode(String[] gameRecordStats) { + return gameRecordStats[0]; + } + + private static double getTimeElapsed(String[] gameRecordStats) { + return Double.parseDouble(gameRecordStats[1]); + } + + private static int getErrorWordCount(String[] errorWordCountString) { + return Integer.parseInt(errorWordCountString[2]); + } + + private static int getCorrectWordCount(String[] gameRecordStats) { + return Integer.parseInt(gameRecordStats[3]); + } + + private static int getTotalWordCount(String[] gameRecordStats) { + return Integer.parseInt(gameRecordStats[4]); + } + + private static double getErrorWordPercentage(String[] gameRecordStats) { + return Double.parseDouble(gameRecordStats[5]); + } + + private static double getCorrectWordPercentage(String[] gameRecordStats) { + return Double.parseDouble(gameRecordStats[6]); + } + + private static double getWpm(String[] wpmString) { + return Double.parseDouble(wpmString[7]); + } + + private static ArrayList getErrorWords(String[] gameRecordStats) { + if (gameRecordStats.length <= 8) { + return new ArrayList<>(); + } + String[] errorWords = gameRecordStats[8].substring(1, gameRecordStats[8].length() - 1).split(","); + return new ArrayList<>(Arrays.asList(errorWords)); + } +} diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java new file mode 100644 index 0000000000..852b84e707 --- /dev/null +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -0,0 +1,141 @@ +package seedu.typists.storage; + + +import seedu.typists.game.GameRecord; +import seedu.typists.ui.TextUi; + + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Locale; +import java.util.Scanner; + +import java.util.logging.Logger; +import java.util.logging.LogManager; +import java.util.logging.Level; +import java.util.logging.SimpleFormatter; +import java.util.logging.FileHandler; +import java.util.logging.ConsoleHandler; + +public class Storage { + + private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); + + public ArrayList readGameRecords(String gameMode) { + + ArrayList gameRecordsStringArrayList = readFile(gameMode); + ArrayList gameRecords = convertToGameRecords(gameRecordsStringArrayList); + return gameRecords; + + } + + public void writeGameRecords(ArrayList gameRecords, String gameMode) { + assert gameRecords != null; + ArrayList gameRecordsStringArrayList = convertToGameRecordsStringArrayList(gameRecords); + writeToFile(gameRecordsStringArrayList, gameMode); + } + + private ArrayList readFile(String gameMode) { + ArrayList fileLines = new ArrayList<>(); + String filename = getFileName(gameMode); + try { + File gameRecordsFile = new File(filename); + Scanner fc = new Scanner(gameRecordsFile); + while (fc.hasNextLine()) { + String fileLine = fc.nextLine(); + fileLines.add(fileLine); + } + } catch (NullPointerException e) { + LOGGER.log(Level.SEVERE, "Caught NullPointerException when creating file", e); + } catch (FileNotFoundException e) { + LOGGER.log(Level.SEVERE, "Caught FileNotFoundException when initializing scanner.", e); + assert false; + } + return fileLines; + } + + private void writeToFile(ArrayList gameRecordsStringArrayList, String gameMode) { + String filename = getFileName(gameMode); + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(filename)); + for (String gameRecordString : gameRecordsStringArrayList) { + bw.write(gameRecordString); + bw.newLine(); + } + bw.flush(); + bw.close(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Caught FileNotFoundException when creating fileWriter", e); + System.out.print("Failed to write to file.\n"); + System.out.print("File named '" + filename + "' could not be opened for some reasons.\n" + + "Ensure that there are no directories named '" + + filename + + "' in the directory where the .jar file resides.\n"); + } + + } + + private ArrayList convertToGameRecords(ArrayList gameRecordsStringArrayList) { + ArrayList gameRecords = new ArrayList<>(); + if (gameRecordsStringArrayList.isEmpty()) { + return gameRecords; + } else { + for (String gameRecordString : gameRecordsStringArrayList) { + GameRecord gameRecord = FileParser.convertStringToGameRecord(gameRecordString); + gameRecords.add(gameRecord); + } + return gameRecords; + } + } + + private ArrayList convertToGameRecordsStringArrayList(ArrayList gameRecords) { + ArrayList gameRecordsStringArrayList = new ArrayList<>(); + if (gameRecords.isEmpty()) { + return gameRecordsStringArrayList; + } + for (GameRecord gameRecord : gameRecords) { + String gameRecordString = convertGameRecordToString(gameRecord); + gameRecordsStringArrayList.add(gameRecordString); + } + return gameRecordsStringArrayList; + } + + private String convertGameRecordToString(GameRecord gameRecord) { + return gameRecord.getStringFormat(); + } + + + private String getFileName(String gameMode) { + assert ((gameMode == "Time-limited") || (gameMode == "Word-limited")); + String filename = gameMode.toLowerCase(Locale.ROOT) + "_records.txt"; + return filename; + + } + + private static void setUpLog() { + LogManager.getLogManager().reset(); + LOGGER.setLevel(Level.ALL); + + ConsoleHandler ch = new ConsoleHandler(); + ch.setLevel(Level.SEVERE); + LOGGER.addHandler(ch); + + try { + FileHandler fh = new FileHandler(TextUi.class.getName() + ".log"); + fh.setFormatter(new SimpleFormatter()); + fh.setLevel(Level.FINE); + LOGGER.addHandler(fh); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); + } + + LOGGER.info("Set up log in Storage"); + } + + +} diff --git a/src/main/java/seedu/typists/storage/StorageFile.java b/src/main/java/seedu/typists/storage/StorageFile.java deleted file mode 100644 index cd4c079efc..0000000000 --- a/src/main/java/seedu/typists/storage/StorageFile.java +++ /dev/null @@ -1,7 +0,0 @@ -package seedu.typists.storage; - -/** - * Represents the file used to store Typing data. - */ -public class StorageFile { -} diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index dd80457beb..3af9e1f864 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -68,12 +68,14 @@ private static void printSuccessStatistics(int correctWordCount, double correctW + "|" + String.format("%.2f", correctWordPercentage) + "%\n"); } + static void printErrorWords(ArrayList errorWords) { setUpLog(); assert errorWords != null; System.out.print("Mistakes: "); if (errorWords.size() == 0) { System.out.print("No words typed wrongly.\n"); + return; } for (int i = 0; i < errorWords.size(); i++) { @@ -98,7 +100,7 @@ private static void printOverview(double timeElapsed, String gameMode, double wp System.out.print("Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n"); } - private static void setUpLog() { + public static void setUpLog() { LogManager.getLogManager().reset(); LOGGER.setLevel(Level.ALL); @@ -115,7 +117,7 @@ private static void setUpLog() { LOGGER.log(Level.SEVERE, "File logger failed to set up\n", e); } - LOGGER.info("Set up log in TextUi"); + LOGGER.info("Set up log in SummaryUi"); } From 9ef90fd4ff1897b2ab56ec5f013f1b8e4e0461de Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 18:50:19 +0800 Subject: [PATCH 117/272] Edit Command interface to accept command arguments. Add ViewCommand. Make required changes to pass CLI checks --- src/main/java/seedu/typists/Main.java | 6 +++++- src/main/java/seedu/typists/command/Command.java | 4 +++- src/main/java/seedu/typists/command/ContentCommand.java | 4 +++- src/main/java/seedu/typists/command/ErrorCommand.java | 4 +++- src/main/java/seedu/typists/command/ExitCommand.java | 4 +++- src/main/java/seedu/typists/command/TimeGameCommand.java | 3 ++- src/main/java/seedu/typists/command/ViewCommand.java | 9 +++++++++ src/main/java/seedu/typists/command/WordGameCommand.java | 4 +++- 8 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 src/main/java/seedu/typists/command/ViewCommand.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index d8e4f98fb9..e733b11042 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -7,6 +7,8 @@ import seedu.typists.storage.StorageFile; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Scanner; @@ -39,12 +41,14 @@ public String read() { public void runCommandLoop() { CommandFactory cmdFactory = new CommandFactory(); String command; + ArrayList args; do { String[] input = read().split(" "); command = input[0]; + args = new ArrayList(Arrays.asList(Arrays.copyOfRange(input,1,input.length))); Command c = cmdFactory.getCommand(input[0]); if (c != null) { - c.run(); + c.run(args); } } while (!command.equals("bye")); } diff --git a/src/main/java/seedu/typists/command/Command.java b/src/main/java/seedu/typists/command/Command.java index 602a275949..ce16792cd2 100644 --- a/src/main/java/seedu/typists/command/Command.java +++ b/src/main/java/seedu/typists/command/Command.java @@ -1,5 +1,7 @@ package seedu.typists.command; +import java.util.ArrayList; + public interface Command { - void run(); + void run(ArrayList args); } diff --git a/src/main/java/seedu/typists/command/ContentCommand.java b/src/main/java/seedu/typists/command/ContentCommand.java index b1e7be0355..82e5bb8e73 100644 --- a/src/main/java/seedu/typists/command/ContentCommand.java +++ b/src/main/java/seedu/typists/command/ContentCommand.java @@ -2,12 +2,14 @@ package seedu.typists.command; +import java.util.ArrayList; + import static seedu.typists.Main.content; public class ContentCommand implements Command { @Override - public void run() { + public void run(ArrayList args) { content.setContent(); } diff --git a/src/main/java/seedu/typists/command/ErrorCommand.java b/src/main/java/seedu/typists/command/ErrorCommand.java index 211a83bb2c..a8ce10a33e 100644 --- a/src/main/java/seedu/typists/command/ErrorCommand.java +++ b/src/main/java/seedu/typists/command/ErrorCommand.java @@ -2,12 +2,14 @@ import seedu.typists.game.ErrorGame; +import java.util.ArrayList; + import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.Main.content; public class ErrorCommand implements Command { @Override - public void run() { + public void run(ArrayList args) { startErrorGame(); } diff --git a/src/main/java/seedu/typists/command/ExitCommand.java b/src/main/java/seedu/typists/command/ExitCommand.java index 26a708fb61..8c8c970992 100644 --- a/src/main/java/seedu/typists/command/ExitCommand.java +++ b/src/main/java/seedu/typists/command/ExitCommand.java @@ -1,10 +1,12 @@ package seedu.typists.command; +import java.util.ArrayList; + import static seedu.typists.Main.uiBot; public class ExitCommand implements Command { @Override - public void run() { + public void run(ArrayList args) { uiBot.showBye(); } } diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 5db90cba03..5ed321e943 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -4,6 +4,7 @@ import seedu.typists.game.DataProcessor; import seedu.typists.game.TimeModeGame; +import java.util.ArrayList; import java.util.Arrays; import static seedu.typists.Main.content; @@ -14,7 +15,7 @@ public class TimeGameCommand implements Command { @Override - public void run() { + public void run(ArrayList args) { TimeModeGame game = createGame(); game.runGame(); process(game); diff --git a/src/main/java/seedu/typists/command/ViewCommand.java b/src/main/java/seedu/typists/command/ViewCommand.java new file mode 100644 index 0000000000..6b296d66b4 --- /dev/null +++ b/src/main/java/seedu/typists/command/ViewCommand.java @@ -0,0 +1,9 @@ +package seedu.typists.command; + +import java.util.ArrayList; + +public class ViewCommand implements Command { + public void run(ArrayList args) { + + } +} diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java index cd3680895d..60f12eb90f 100644 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -3,12 +3,14 @@ import seedu.typists.command.Command; import seedu.typists.game.WordLimitGame; +import java.util.ArrayList; + import static seedu.typists.Main.content; import static seedu.typists.Main.uiBot; public class WordGameCommand implements Command { @Override - public void run() { + public void run(ArrayList args) { startWordLimitGame(); } From 38a9ffb2f84b532efb20f1dae3749f6a17a48db5 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 19:40:10 +0800 Subject: [PATCH 118/272] Convert methods in Storage to static. Associate Storage to GameRecordsManager. --- .../seedu/typists/game/GameRecordsManager.java | 8 ++++++-- src/main/java/seedu/typists/storage/Storage.java | 16 ++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index 7e882a54a4..cc70ee3b07 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -1,16 +1,20 @@ package seedu.typists.game; +import seedu.typists.storage.Storage; + import java.util.ArrayList; import java.util.HashMap; public class GameRecordsManager { private static GameRecordsManager instance = null; - private ArrayList timeLimitedGameRecords = null; - private ArrayList wordLimitedGameRecords = null; + private ArrayList timeLimitedGameRecords; + private ArrayList wordLimitedGameRecords; private GameRecordsManager() { // get gameRecords using some file reader. + timeLimitedGameRecords = Storage.readGameRecords("Time-limited"); + wordLimitedGameRecords = Storage.readGameRecords("Word-limited"); } public static GameRecordsManager getGameRecordsManager() { diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java index 852b84e707..b90ee6ff04 100644 --- a/src/main/java/seedu/typists/storage/Storage.java +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -26,7 +26,7 @@ public class Storage { private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); - public ArrayList readGameRecords(String gameMode) { + public static ArrayList readGameRecords(String gameMode) { ArrayList gameRecordsStringArrayList = readFile(gameMode); ArrayList gameRecords = convertToGameRecords(gameRecordsStringArrayList); @@ -34,13 +34,13 @@ public ArrayList readGameRecords(String gameMode) { } - public void writeGameRecords(ArrayList gameRecords, String gameMode) { + public static void writeGameRecords(ArrayList gameRecords, String gameMode) { assert gameRecords != null; ArrayList gameRecordsStringArrayList = convertToGameRecordsStringArrayList(gameRecords); writeToFile(gameRecordsStringArrayList, gameMode); } - private ArrayList readFile(String gameMode) { + private static ArrayList readFile(String gameMode) { ArrayList fileLines = new ArrayList<>(); String filename = getFileName(gameMode); try { @@ -59,7 +59,7 @@ private ArrayList readFile(String gameMode) { return fileLines; } - private void writeToFile(ArrayList gameRecordsStringArrayList, String gameMode) { + private static void writeToFile(ArrayList gameRecordsStringArrayList, String gameMode) { String filename = getFileName(gameMode); try { BufferedWriter bw = new BufferedWriter(new FileWriter(filename)); @@ -80,7 +80,7 @@ private void writeToFile(ArrayList gameRecordsStringArrayList, String ga } - private ArrayList convertToGameRecords(ArrayList gameRecordsStringArrayList) { + private static ArrayList convertToGameRecords(ArrayList gameRecordsStringArrayList) { ArrayList gameRecords = new ArrayList<>(); if (gameRecordsStringArrayList.isEmpty()) { return gameRecords; @@ -93,7 +93,7 @@ private ArrayList convertToGameRecords(ArrayList gameRecords } } - private ArrayList convertToGameRecordsStringArrayList(ArrayList gameRecords) { + private static ArrayList convertToGameRecordsStringArrayList(ArrayList gameRecords) { ArrayList gameRecordsStringArrayList = new ArrayList<>(); if (gameRecords.isEmpty()) { return gameRecordsStringArrayList; @@ -105,12 +105,12 @@ private ArrayList convertToGameRecordsStringArrayList(ArrayList Date: Tue, 26 Oct 2021 20:19:32 +0800 Subject: [PATCH 119/272] Some DG update --- docs/DeveloperGuide.md | 26 ++++++++++++++ docs/uml/WordLimitMode.png | Bin 0 -> 53814 bytes docs/uml/WordLimitMode.puml | 69 ++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 docs/uml/WordLimitMode.png create mode 100644 docs/uml/WordLimitMode.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 96c578b3b5..67e4f27392 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -6,12 +6,36 @@ {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} * https://www.baeldung.com/java-testing-system-out-println + +##Architecture + +(Some architecture diagram) + ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### Choose game mode + +### Choose the game content + +### Word Limit Game + +Once the CommandFactory reads a 'word' command, a word limit game will begin. + +Gonna to change this .puml diagram later - zhansen + +![](uml/WordLimitMode.png) + +### Time Limit Game + +### Storage ## Product scope + +Our product is a typing game, intent to provide enjoyment for people who are familiar with the CML. + + ### Target user profile {Describe the target user profile} @@ -30,6 +54,8 @@ ## Non-Functional Requirements {Give non-functional requirements} +### Animation + ## Glossary diff --git a/docs/uml/WordLimitMode.png b/docs/uml/WordLimitMode.png new file mode 100644 index 0000000000000000000000000000000000000000..158124bac2edea439ac977432794a52ba649c7a2 GIT binary patch literal 53814 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�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 SearchCommand : execute() +activate SearchCommand + +alt Able to connect + SearchCommand -> NusMods : searchModsOnline() + activate NusMods + NusMods -> NusMods : getOnlineModList() + activate NusMods + NusMods --> NusMods + deactivate NusMods + loop for each mod + alt Module Code Match + NusMods -> NusMods : fetchModOnline() + activate NusMods + NusMods -> NusMods : getOnlineModInfo() + activate NusMods + NusMods --> NusMods + deactivate NusMods + NusMods -> ModStorage : saveModInfo() + activate ModStorage + ModStorage --> NusMods + deactivate ModStorage + NusMods -> ModStorage : loadModInfo() + activate ModStorage + ModStorage --> NusMods + deactivate ModStorage + deactivate NusMods + alt All Flags Match + NusMods -> TextUI : PrintModBriefDescription() + activate TextUI + TextUI --> NusMods + deactivate TextUI + else + end + else + end + end + NusMods --> SearchCommand + deactivate NusMods + +else No connection or Quicksearch + + SearchCommand -> ModStorage : searchFiles() + activate ModStorage + loop for each json + alt Module Code Match + ModStorage -> ModStorage : loadModInfo() + activate ModStorage + ModStorage --> ModStorage + deactivate ModStorage + alt All Flags Match + ModStorage -> TextUI : PrintModBriefDescription() + activate TextUI + TextUI --> ModStorage + deactivate TextUI + end + end + end + ModStorage --> SearchCommand + deactivate ModStorage + +end + +<-- SearchCommand +deactivate SearchCommand + +@enduml \ No newline at end of file From f8d90b4e865259bb408e916e5fa8c2094e408f91 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 22:37:20 +0800 Subject: [PATCH 120/272] First commit of view feature (untested) --- .../seedu/typists/command/ViewCommand.java | 76 +++++++++++++++++++ .../java/seedu/typists/game/GameRecord.java | 30 ++++++++ .../typists/game/GameRecordsManager.java | 15 ++++ src/main/java/seedu/typists/ui/SummaryUi.java | 15 ++++ .../java/seedu/typists/ui/ViewCommandUi.java | 18 +++++ 5 files changed, 154 insertions(+) create mode 100644 src/main/java/seedu/typists/ui/ViewCommandUi.java diff --git a/src/main/java/seedu/typists/command/ViewCommand.java b/src/main/java/seedu/typists/command/ViewCommand.java index 6b296d66b4..4546816bc9 100644 --- a/src/main/java/seedu/typists/command/ViewCommand.java +++ b/src/main/java/seedu/typists/command/ViewCommand.java @@ -1,9 +1,85 @@ package seedu.typists.command; +import seedu.typists.game.GameRecord; +import seedu.typists.game.GameRecordsManager; +import seedu.typists.ui.ViewCommandUi; + import java.util.ArrayList; public class ViewCommand implements Command { + private int numberOfRecords = 10; + private String gameMode; + private ArrayList args; + private static final String GAME_MODE_OPTION = "g"; + private static final String NUMBER_OF_RECORDS_OPTION = "n"; + private static final String HELP_OPTION = "h"; + + public void run(ArrayList args) { + this.args = args; + boolean isHelp = isHelpCommand(); + if (isHelp) { + ViewCommandUi.displayHelp(); + } else { + executeCommand(); + } + } + + private void executeCommand() { + GameRecordsManager gameRecordsManager = GameRecordsManager.getGameRecordsManager(); + parseCommand(); + ArrayList gameRecords = gameRecordsManager.getGameRecords(gameMode, numberOfRecords); + ViewCommandUi.displayGameRecords(gameRecords); + } + + + private boolean isHelpCommand() { + int indexHelp = args.indexOf("-" + HELP_OPTION); + if (indexHelp != -1) { + return true; + } else { + return false; + } } + + private void parseCommand() { + getGameMode(); + getNumberOfRecords(); + } + + private void getNumberOfRecords() { + int indexNumberOfRecords = args.indexOf("-" + NUMBER_OF_RECORDS_OPTION); + if (indexNumberOfRecords == -1) { + return; + } else { + try { + numberOfRecords = Integer.parseInt(args.get(indexNumberOfRecords + 1)); + } catch (NumberFormatException e) { + System.out.print("Invalid argument for number of records option.\n" + + "Option only accepts integer values." + + "Input \"View -h\" for help\n"); + } + } + + } + + private void getGameMode() { + int indexGameMode = args.indexOf("-" + GAME_MODE_OPTION); + if (indexGameMode == -1) { + System.out.print("Invalid command.\n" + + "Input \"View -h\" for help\n"); + return; + } else { + gameMode = args.get(indexGameMode + 1); + } + if (gameMode != "time" && gameMode != "word") { + System.out.print("Invalid argument for game mode option.\n" + + "Input \"View -h\" for help\n"); + return; + } else { + gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; + } + } + } diff --git a/src/main/java/seedu/typists/game/GameRecord.java b/src/main/java/seedu/typists/game/GameRecord.java index c63ca3523b..52680afb6f 100644 --- a/src/main/java/seedu/typists/game/GameRecord.java +++ b/src/main/java/seedu/typists/game/GameRecord.java @@ -34,5 +34,35 @@ public String getGameMode() { return gameMode; } + public double getTimeElapsed() { + return timeElapsed; + } + + public int getErrorWordCount() { + return errorWordCount; + } + + public int getCorrectWordCount() { + return correctWordCount; + } + + public int getTotalWordCount() { + return totalWordCount; + } + public double getErrorWordPercentage() { + return errorWordPercentage; + } + + public double getCorrectWordPercentage() { + return correctWordPercentage; + } + + public double getWpm() { + return wpm; + } + + public ArrayList getErrorWords() { + return errorWords; + } } diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index 7e882a54a4..b5d0b43d13 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -52,4 +52,19 @@ private void addRecordToArray(GameRecord gameRecord) { } } + public ArrayList getGameRecords(String gameMode, int numberOfRecords) { + assert ((gameMode == "Time-limited") || (gameMode == "Word-limited")); + if (gameMode == "Time-limited") { + return new ArrayList<>(timeLimitedGameRecords.subList( + timeLimitedGameRecords.size() - numberOfRecords, + timeLimitedGameRecords.size() + )); + } else { + return new ArrayList<>(wordLimitedGameRecords.subList( + wordLimitedGameRecords.size() - numberOfRecords, + wordLimitedGameRecords.size() + )); + } + } + } diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index dd80457beb..07a1f2ca6d 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -1,5 +1,7 @@ package seedu.typists.ui; +import seedu.typists.game.GameRecord; + import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -52,6 +54,19 @@ public static void displaySummary(HashMap summary) { printErrorWords((ArrayList) summary.get("errorWords")); } + public static void displaySummary(GameRecord gameRecord) { + printOverview(gameRecord.getTimeElapsed(), + gameRecord.getGameMode(), + gameRecord.getWpm()); + printErrorStatistics(gameRecord.getErrorWordCount(), + gameRecord.getErrorWordPercentage(), + gameRecord.getTotalWordCount()); + printSuccessStatistics(gameRecord.getCorrectWordCount(), + gameRecord.getCorrectWordPercentage(), + gameRecord.getTotalWordCount()); + printErrorWords(gameRecord.getErrorWords()); + } + private static void printErrorStatistics(int errorWordCount, double errorWordPercentage, int totalWordCount) { System.out.print("Number of Wrong Words: " + errorWordCount diff --git a/src/main/java/seedu/typists/ui/ViewCommandUi.java b/src/main/java/seedu/typists/ui/ViewCommandUi.java new file mode 100644 index 0000000000..6a1ba5d746 --- /dev/null +++ b/src/main/java/seedu/typists/ui/ViewCommandUi.java @@ -0,0 +1,18 @@ +package seedu.typists.ui; + +import seedu.typists.game.GameRecord; + +import java.util.ArrayList; + +public class ViewCommandUi { + public static void displayGameRecords(ArrayList gameRecords) { + for (GameRecord gameRecord:gameRecords) { + SummaryUi.displaySummary(gameRecord); + } + } + + public static void displayHelp() { + //do after user guide + System.out.print("display help placeholder\n"); + } +} From 8af73973e09326417d1e40edf3967a960cb9fc36 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 22:38:54 +0800 Subject: [PATCH 121/272] Ignore seedu.typists.ui.TextUi.log --- seedu.typists.ui.TextUi.log | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 seedu.typists.ui.TextUi.log diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log deleted file mode 100644 index 8f340113de..0000000000 --- a/seedu.typists.ui.TextUi.log +++ /dev/null @@ -1,2 +0,0 @@ -Oct 25, 2021 7:49:39 PM seedu.typists.ui.TextUi setUpLog -INFO: Set up log in TextUi From f575d63ea0039746b7d89811504aa0e1fabbc5db Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 22:40:58 +0800 Subject: [PATCH 122/272] commit log file --- seedu.typists.ui.TextUi.log | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 seedu.typists.ui.TextUi.log diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log new file mode 100644 index 0000000000..7e27343ee9 --- /dev/null +++ b/seedu.typists.ui.TextUi.log @@ -0,0 +1,2 @@ +Oct 26, 2021 10:36:13 PM seedu.typists.ui.SummaryUi setUpLog +INFO: Set up log in TextUi From 32b8eb0534534aea324b4bbd77f39b1225727467 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Tue, 26 Oct 2021 23:10:22 +0800 Subject: [PATCH 123/272] Add automatic store and read game records feature Fixes #41 Fixes #40 --- .../java/seedu/typists/command/ExitCommand.java | 5 +++++ src/main/java/seedu/typists/game/Game.java | 8 +++++--- .../java/seedu/typists/game/GameRecord.java | 2 +- .../seedu/typists/game/GameRecordsManager.java | 17 +++++++++++++++++ .../java/seedu/typists/game/TimeModeGame.java | 4 +++- .../java/seedu/typists/storage/Storage.java | 3 +-- 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/typists/command/ExitCommand.java b/src/main/java/seedu/typists/command/ExitCommand.java index 8c8c970992..ff48e90402 100644 --- a/src/main/java/seedu/typists/command/ExitCommand.java +++ b/src/main/java/seedu/typists/command/ExitCommand.java @@ -1,5 +1,7 @@ package seedu.typists.command; +import seedu.typists.game.GameRecordsManager; + import java.util.ArrayList; import static seedu.typists.Main.uiBot; @@ -7,6 +9,9 @@ public class ExitCommand implements Command { @Override public void run(ArrayList args) { + System.out.print("Updating game records..."); + GameRecordsManager gameRecordsManager = GameRecordsManager.getGameRecordsManager(); + gameRecordsManager.updateGameRecords(); uiBot.showBye(); } } diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 95899dc387..21d11dcfdc 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -23,16 +23,18 @@ public double duration(long startTime, long endTime) { public abstract void runGame(); - public void handleSummary( + public HashMap handleSummary( ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode ) { HashMap summary = SummaryManager.generateSummary( expectedInput, actualInput, timeElapsed, gameMode ); SummaryUi.displaySummary(summary); + return summary; } - public void handleStorage() { - + public void handleStorage(HashMap summary) { + GameRecordsManager gameRecordsManager = GameRecordsManager.getGameRecordsManager(); + gameRecordsManager.addGameRecord(summary); } } diff --git a/src/main/java/seedu/typists/game/GameRecord.java b/src/main/java/seedu/typists/game/GameRecord.java index 39f694fbff..4352f33fab 100644 --- a/src/main/java/seedu/typists/game/GameRecord.java +++ b/src/main/java/seedu/typists/game/GameRecord.java @@ -36,7 +36,7 @@ public String getGameMode() { } public String getStringFormat() { - String separator = "\\|"; + String separator = "|"; String formatted = gameMode + separator + timeElapsed diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index cc70ee3b07..4a913e42c0 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -17,6 +17,11 @@ private GameRecordsManager() { wordLimitedGameRecords = Storage.readGameRecords("Word-limited"); } + public void updateGameRecords() { + Storage.writeGameRecords(timeLimitedGameRecords, "Time-limited"); + Storage.writeGameRecords(wordLimitedGameRecords, "Word-limited"); + } + public static GameRecordsManager getGameRecordsManager() { if (instance == null) { instance = new GameRecordsManager(); @@ -27,6 +32,7 @@ public static GameRecordsManager getGameRecordsManager() { public void addGameRecord(HashMap gameSummary) { GameRecord newGameRecord = createGameRecord(gameSummary); addRecordToArray(newGameRecord); + writeRecordToFile(newGameRecord); } private GameRecord createGameRecord(HashMap gameSummary) { @@ -56,4 +62,15 @@ private void addRecordToArray(GameRecord gameRecord) { } } + private void writeRecordToFile(GameRecord gameRecord) { + String gameMode = gameRecord.getGameMode(); + if (gameMode == "Word Limited") { + Storage.writeGameRecords(wordLimitedGameRecords, "Word-limited"); + } else { + Storage.writeGameRecords(timeLimitedGameRecords, "Time-limited"); + + } + + } + } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index cf92dd2403..3edc3b0ae7 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,6 +1,7 @@ package seedu.typists.game; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Scanner; import java.util.logging.Level; @@ -74,7 +75,8 @@ public void runGame() { } updateUserLines(inputs); ui.printScreen("Game Finished."); - handleSummary(wordLines, userLines, realGameTime, "Word-limited"); + HashMap summary = handleSummary(wordLines, userLines, realGameTime, "Word-limited"); + handleStorage(summary); } } diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java index b90ee6ff04..68f89065f2 100644 --- a/src/main/java/seedu/typists/storage/Storage.java +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -53,8 +53,7 @@ private static ArrayList readFile(String gameMode) { } catch (NullPointerException e) { LOGGER.log(Level.SEVERE, "Caught NullPointerException when creating file", e); } catch (FileNotFoundException e) { - LOGGER.log(Level.SEVERE, "Caught FileNotFoundException when initializing scanner.", e); - assert false; + LOGGER.log(Level.INFO, "create new file with filename: " + filename); } return fileLines; } From 668b8a7e461d11706ebfa526e380a0f668a23e5c Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Tue, 26 Oct 2021 23:17:37 +0800 Subject: [PATCH 124/272] fix bug --- seedu.typists.ui.TextUi.log | 2 +- .../java/seedu/typists/command/TimeGameCommand.java | 1 - src/main/java/seedu/typists/game/TimeModeGame.java | 10 ---------- src/main/java/seedu/typists/game/WordLimitGame.java | 10 ---------- 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 8f340113de..862eb1ea32 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 25, 2021 7:49:39 PM seedu.typists.ui.TextUi setUpLog +Oct 26, 2021 11:15:55 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in TextUi diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 5ed321e943..7ef267c3b7 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -1,6 +1,5 @@ package seedu.typists.command; -import seedu.typists.command.Command; import seedu.typists.game.DataProcessor; import seedu.typists.game.TimeModeGame; diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index b9488f2bc8..0cf38cbaa5 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -14,7 +14,6 @@ public class TimeModeGame extends Game { protected int gameTime; protected final ArrayList wordLines; - public double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { @@ -79,15 +78,6 @@ public void runGame() { } } - @Override - public void store() { - - } - - @Override - public void getSummary() { - - } public void updateUserLines(List stringArray) { userLines = getWordLineFromStringArray(stringArray); diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 43aec4dbd8..a828c51640 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -39,16 +39,6 @@ public void runGame() { } } - @Override - public void store() { - - } - - @Override - public void getSummary() { - - } - public int getTotalSentence() { return eachWord.size(); } From 3f128925db074c33d2b924fd3a3e547bce3aebe8 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Tue, 26 Oct 2021 23:23:27 +0800 Subject: [PATCH 125/272] minor --- seedu.typists.ui.TextUi.log | 2 +- src/main/java/seedu/typists/ui/TextUi.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 862eb1ea32..86f839d4bc 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 26, 2021 11:15:55 PM seedu.typists.ui.SummaryUi setUpLog +Oct 26, 2021 11:21:51 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in TextUi diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 3669e4636a..0239e3d5c2 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,7 +1,5 @@ package seedu.typists.ui; -import java.io.IOException; - import seedu.typists.common.Error; import seedu.typists.content.Animation; From c92eca1fd5f2c6e4d331cf3d345e42d5de3e97f5 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 02:31:18 +0800 Subject: [PATCH 126/272] Edit exit logic --- src/main/java/seedu/typists/command/ExitCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/typists/command/ExitCommand.java b/src/main/java/seedu/typists/command/ExitCommand.java index ff48e90402..ffbe5f2d4f 100644 --- a/src/main/java/seedu/typists/command/ExitCommand.java +++ b/src/main/java/seedu/typists/command/ExitCommand.java @@ -9,7 +9,6 @@ public class ExitCommand implements Command { @Override public void run(ArrayList args) { - System.out.print("Updating game records..."); GameRecordsManager gameRecordsManager = GameRecordsManager.getGameRecordsManager(); gameRecordsManager.updateGameRecords(); uiBot.showBye(); From 589b05db0eee3d32a199efb3982b17e292d902cb Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 03:14:40 +0800 Subject: [PATCH 127/272] Update proposedImplementation for View Statistics Feature --- docs/DeveloperGuide.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 67e4f27392..0544772cdb 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -29,7 +29,42 @@ Gonna to change this .puml diagram later - zhansen ### Time Limit Game -### Storage +### \[Proposed\] View Statistics feature +An enhancement of view best statistics feature. +#### \[Proposed Implementation\] +The top-level logic of view statistics feature resides in ViewStatistics. It implements the Command +interface. The key methods in the ViewStatistics class is +* `retrieveStatistics()` - Decides which of the 3 methods below to run +* `calculateBestStatistics()` - Returns the best statistics over the past n games +* `calculateWorstStatistics()` - Returns the worst statistics over the past n games +* `calculateAverageStatistics()` - Returns the average statistics over the past n games + +Given below is an example usage scenario and how the program implements the feature + +Step 1: The user launches the application (scenario assumes that there are several game records already stored in multiple files). +1. The program carries out the initialization code and creates a HistoryManager object. + + +Step 2: The user executes `view -m best -g game error -n 9` to view his/her best statistics for the error game mode over the past 9 games. +1. A ViewCommand object is then instantiated. +2. ViewCommand calls the retrieveStatistics() method of RetrieveStatisticsManager. +3. RetrieveStatisticsManager then calls the getNGames() method of historyManager() and self-invokes calculateBestStatistics(). +4. calculateBestStatistics() returns a HashMap containing the statistics. +5. The statistics are then displayed using the displayStatistics() method of StatisticsUI class. + + +The following sequence diagram shows how the above scenario is executed + +The following class diagram shows the relationship among the main involved classes + + +#### Alternative Implementation +* One implementation considered is to do away with the retrieveStatistics() method and immediately call one of calculateBestStatistics, +calculateWorstStatistics() or calculateAverageStatistics() based on the gamer's imput using a switch statement. This implementation choice +was not used because it violates the Single Responsibility Principle and does not do SLAP well. +* Another implementation considered was for HistoryManager to do the main logic. This implementation was not done as it violates the +Single Responsibility Principle + ## Product scope From 4a167a9744cabb60f8cbec0e469fabe9034c328e Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 27 Oct 2021 06:05:54 +0800 Subject: [PATCH 128/272] Remove animation and error, DG update --- docs/DeveloperGuide.md | 12 ++++- docs/team/{johndoe.md => williamwahyudi.md} | 2 +- docs/uml/Content.png | Bin 0 -> 22810 bytes docs/uml/Content.puml | 31 ++++++++++++ seedu.typists.ui.TextUi.log | 2 +- .../seedu/typists/command/CommandFactory.java | 2 - .../seedu/typists/command/ErrorCommand.java | 19 -------- .../java/seedu/typists/game/ErrorGame.java | 46 ------------------ src/main/java/seedu/typists/ui/TextUi.java | 2 +- 9 files changed, 44 insertions(+), 72 deletions(-) rename docs/team/{johndoe.md => williamwahyudi.md} (50%) create mode 100644 docs/uml/Content.png create mode 100644 docs/uml/Content.puml delete mode 100644 src/main/java/seedu/typists/command/ErrorCommand.java delete mode 100644 src/main/java/seedu/typists/game/ErrorGame.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 67e4f27392..7c3085144a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -15,10 +15,18 @@ {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} -### Choose game mode - ### Choose the game content +Input the 'content' command to start the text selection. + +There are 3 types: + + 1. Opening paragraphs from famous books + 2. Custom Wikipedia article + 3. Random words + +![](uml/Content.png) + ### Word Limit Game Once the CommandFactory reads a 'word' command, a word limit game will begin. diff --git a/docs/team/johndoe.md b/docs/team/williamwahyudi.md similarity index 50% rename from docs/team/johndoe.md rename to docs/team/williamwahyudi.md index ab75b391b8..70abee6cbd 100644 --- a/docs/team/johndoe.md +++ b/docs/team/williamwahyudi.md @@ -1,4 +1,4 @@ -# John Doe - Project Portfolio Page +# William Wahyudi - Project Portfolio Page ## Overview diff --git a/docs/uml/Content.png b/docs/uml/Content.png new file mode 100644 index 0000000000000000000000000000000000000000..a27f80679b887ce441a2e48aac2d9204bc4b703c GIT binary patch literal 22810 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 Content: setContent() + +alt Input = 0 + Content -> Books: setBooks() + activate Books + Books --> Content: getBook() + deactivate Books + +else Input = 1 + + Content -> WikiImport: setWikipedia() + activate WikiImport + WikiImport --> Content: getArticle() + deactivate WikiImport + +else Input = 2 + + Content -> RandomGenerator: setRandomContent() + activate RandomGenerator + RandomGenerator --> Content: randomString() + deactivate RandomGenerator + +end + +<-- Content: getContent() + +@enduml \ No newline at end of file diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 86f839d4bc..07f12c3e16 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 26, 2021 11:21:51 PM seedu.typists.ui.SummaryUi setUpLog +Oct 27, 2021 3:43:18 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in TextUi diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index af89123b73..1805399094 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -13,8 +13,6 @@ public Command getCommand(String commandType) { return new WordGameCommand(); case "content": return new ContentCommand(); - case "error": - return new ErrorCommand(); case "bye": return new ExitCommand(); default: diff --git a/src/main/java/seedu/typists/command/ErrorCommand.java b/src/main/java/seedu/typists/command/ErrorCommand.java deleted file mode 100644 index a8ce10a33e..0000000000 --- a/src/main/java/seedu/typists/command/ErrorCommand.java +++ /dev/null @@ -1,19 +0,0 @@ -package seedu.typists.command; - -import seedu.typists.game.ErrorGame; - -import java.util.ArrayList; - -import static seedu.typists.Main.LINE_LENGTH; -import static seedu.typists.Main.content; - -public class ErrorCommand implements Command { - @Override - public void run(ArrayList args) { - startErrorGame(); - } - - public void startErrorGame() { - new ErrorGame(content.getContent(), LINE_LENGTH); - } -} diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java deleted file mode 100644 index 44884e5632..0000000000 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ /dev/null @@ -1,46 +0,0 @@ -package seedu.typists.game; - -import seedu.typists.ui.TextUi; -import java.util.ArrayList; -import java.util.Scanner; - -import static seedu.typists.common.Utils.getWordLines; - -public class ErrorGame extends Game { - private final TextUi ui; - - protected ArrayList inputLines; - protected final ArrayList wordLines; - - public ErrorGame(String targetWordSet, int wordsPerLine) { - ui = new TextUi(); - inputLines = new ArrayList<>(); - wordLines = getWordLines(targetWordSet, wordsPerLine); - runGame(); - } - - public boolean readyToStartGame() { - Scanner in = new Scanner(System.in); - String command = ""; - while (!command.equals("yes")) { - ui.printScreen("Do you want to start now?"); - command = in.nextLine(); - } - return true; - } - - public void runGame() { - if (readyToStartGame()) { - for (int i = 0; i < wordLines.size(); i++) { - ui.printLine(wordLines.get(i)); - } - } - Scanner in = new Scanner(System.in); - for (int i = 0; i < wordLines.size(); i++) { - String userInput = in.nextLine(); - inputLines.add(userInput); - i++; - } - System.out.println("Game Finished."); - } -} diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 0239e3d5c2..e23d0c004f 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -101,7 +101,7 @@ public void showBye() { } public void printGameMode1Progress(int a, int b) throws InterruptedException { - viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); + printLine("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } public void printKeyboard() { From ddf1f145df2fe0dd4fb9eb8d1020cddae01a646e Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 27 Oct 2021 06:14:22 +0800 Subject: [PATCH 129/272] DG --- docs/DeveloperGuide.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 7c3085144a..f49600484c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -6,6 +6,7 @@ {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} * https://www.baeldung.com/java-testing-system-out-println +* https://github.com/fastily/jwiki ##Architecture @@ -25,8 +26,12 @@ There are 3 types: 2. Custom Wikipedia article 3. Random words +The following UML diagram illustrates the way content selection works in the program. + ![](uml/Content.png) +There only exists one content string for all sessions. + ### Word Limit Game Once the CommandFactory reads a 'word' command, a word limit game will begin. From 72a8d18e1cd6f59d9887cf91046d21ab0e52e329 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 27 Oct 2021 06:30:44 +0800 Subject: [PATCH 130/272] DG --- docs/DeveloperGuide.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f49600484c..8a2c15f6ba 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -62,6 +62,10 @@ Our product is a typing game, intent to provide enjoyment for people who are fam |Version| As a ... | I want to ... | So that I can ...| |--------|----------|---------------|------------------| |v1.0|new user|see usage instructions|refer to them when I forget how to use the application| +|v1.0|user|customize the time limit to finish a game|train myself to type faster| +|v1.0|user|customize the word limit, in multiples of 100|have an optimal gaming experience by being able to choose my preferred length of text for the game| +|v1.0|user|choose text from famous books, randomly generated text or customized text for my game|make my gaming experience more fun and fulfilling| +|v2.0|user|view my game statistics after the game finishes|know how I fared| |v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| ## Non-Functional Requirements From e35ca2a89b4e76ab409cf1752552669b8fec324c Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 27 Oct 2021 06:44:49 +0800 Subject: [PATCH 131/272] DG --- docs/DeveloperGuide.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8a2c15f6ba..5ea5302c74 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -18,7 +18,10 @@ ### Choose the game content -Input the 'content' command to start the text selection. +Once the game starts, the main class instantiates a Content object containing a string, which is set to a default +value (lorem ipsum paragraph). The string can only be changed through the setContent() method. + +Users can input the 'content' command to start the text selection. There are 3 types: @@ -30,7 +33,9 @@ The following UML diagram illustrates the way content selection works in the pro ![](uml/Content.png) -There only exists one content string for all sessions. +There only exists one private content string for all sessions. Each time a set method is called, the string is changed +depending on the choices that the user made throughout the process. Whenever the user starts a game, the getContent() +method is called and the text is set accordingly. ### Word Limit Game From de55a0c7d067ab686824e5fd5e4b16313b957fc9 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 09:57:20 +0800 Subject: [PATCH 132/272] Update seedu.typists.ui.TextUi.log --- seedu.typists.ui.TextUi.log | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 86f839d4bc..7e22f1566a 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 26, 2021 11:21:51 PM seedu.typists.ui.SummaryUi setUpLog +Oct 26, 2021 11:23:43 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in TextUi From 254b50074cb6542c23abbb165a54fa1de90150bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Wed, 27 Oct 2021 11:25:33 +0800 Subject: [PATCH 133/272] Delete Content.puml --- docs/uml/Content.puml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 docs/uml/Content.puml diff --git a/docs/uml/Content.puml b/docs/uml/Content.puml deleted file mode 100644 index b4a6ab2c5c..0000000000 --- a/docs/uml/Content.puml +++ /dev/null @@ -1,31 +0,0 @@ -@startuml -'https://plantuml.com/sequence-diagram - -activate Content -[-> Content: setContent() - -alt Input = 0 - Content -> Books: setBooks() - activate Books - Books --> Content: getBook() - deactivate Books - -else Input = 1 - - Content -> WikiImport: setWikipedia() - activate WikiImport - WikiImport --> Content: getArticle() - deactivate WikiImport - -else Input = 2 - - Content -> RandomGenerator: setRandomContent() - activate RandomGenerator - RandomGenerator --> Content: randomString() - deactivate RandomGenerator - -end - -<-- Content: getContent() - -@enduml \ No newline at end of file From 5c4bb29730b189fb7a54208bbf69634b23e8f0fb Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 14:53:47 +0800 Subject: [PATCH 134/272] Finish view history feature. Rename ViewCommand and ViewCommandUi class to HistoryCommand and HistoryCommandUi respectively Add a constructor with a String argument to InvalidCommandException Add history as a command to the game Debug summary feature Fixes #6 Fixes #39 --- src/main/java/seedu/typists/Main.java | 2 +- .../seedu/typists/command/CommandFactory.java | 2 + .../seedu/typists/command/HistoryCommand.java | 100 ++++++++++++++++++ .../seedu/typists/command/ViewCommand.java | 85 --------------- .../java/seedu/typists/common/Messages.java | 33 +++--- .../exception/InvalidCommandException.java | 9 +- .../java/seedu/typists/game/GameRecord.java | 6 ++ .../typists/game/GameRecordsManager.java | 20 +++- .../seedu/typists/game/SummaryManager.java | 2 +- .../java/seedu/typists/game/TimeModeGame.java | 2 +- .../seedu/typists/ui/HistoryCommandUi.java | 29 +++++ src/main/java/seedu/typists/ui/SummaryUi.java | 8 +- .../java/seedu/typists/ui/ViewCommandUi.java | 18 ---- 13 files changed, 192 insertions(+), 124 deletions(-) create mode 100644 src/main/java/seedu/typists/command/HistoryCommand.java delete mode 100644 src/main/java/seedu/typists/command/ViewCommand.java create mode 100644 src/main/java/seedu/typists/ui/HistoryCommandUi.java delete mode 100644 src/main/java/seedu/typists/ui/ViewCommandUi.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 6f4f8c122b..f033612cfa 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -16,7 +16,7 @@ public class Main { /** * Version info of the program. */ - public static final String VERSION = "Typist - Version 1.0"; + public static final String VERSION = "Typist - Version 2.0"; public static final int LINE_LENGTH = 10; public static Content content; public static TextUi uiBot; diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index af89123b73..63e4dcf59d 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -15,6 +15,8 @@ public Command getCommand(String commandType) { return new ContentCommand(); case "error": return new ErrorCommand(); + case "history": + return new HistoryCommand(); case "bye": return new ExitCommand(); default: diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/HistoryCommand.java new file mode 100644 index 0000000000..f53ad0be29 --- /dev/null +++ b/src/main/java/seedu/typists/command/HistoryCommand.java @@ -0,0 +1,100 @@ +package seedu.typists.command; + +import seedu.typists.exception.InvalidCommandException; +import seedu.typists.game.GameRecord; +import seedu.typists.game.GameRecordsManager; +import seedu.typists.ui.HistoryCommandUi; + +import java.util.ArrayList; + +public class HistoryCommand implements Command { + private int numberOfRecords = 10; + private int totalNumberOfRecords; + private String gameMode; + private ArrayList args; + private static final String GAME_MODE_OPTION = "g"; + private static final String NUMBER_OF_RECORDS_OPTION = "n"; + private static final String HELP_OPTION = "h"; + private static GameRecordsManager gameRecordsManager; + + public void run(ArrayList args) { + this.args = args; + boolean isHelp = isHelpCommand(); + if (isHelp) { + HistoryCommandUi.displayHelp(); + } else { + executeCommand(); + } + } + + private void executeCommand() { + gameRecordsManager = GameRecordsManager.getGameRecordsManager(); + try { + parseCommand(); + ArrayList gameRecords = gameRecordsManager.getGameRecords(gameMode, numberOfRecords); + HistoryCommandUi.displayGameRecords(gameRecords, totalNumberOfRecords); + } catch (InvalidCommandException e) { + String errorMessage = "Error: " + e.toString().split(":")[1]; + System.out.print(errorMessage); + } + } + + + private boolean isHelpCommand() { + int indexHelp = args.indexOf("-" + HELP_OPTION); + if (indexHelp != -1) { + return true; + } else { + return false; + } + + } + + private void parseCommand() throws InvalidCommandException { + getGameMode(); + getNumberOfRecords(); + } + + private void getNumberOfRecords() throws InvalidCommandException { + int indexNumberOfRecords = args.indexOf("-" + NUMBER_OF_RECORDS_OPTION); + if (indexNumberOfRecords == -1) { + totalNumberOfRecords = gameRecordsManager.getNumberOfGameRecords(gameMode); + numberOfRecords = totalNumberOfRecords; + return; + } else { + if (args.size() < indexNumberOfRecords + 2) { + throw new InvalidCommandException("Missing argument for number of records option.\n"); + } + try { + totalNumberOfRecords = gameRecordsManager.getNumberOfGameRecords(gameMode); + numberOfRecords = Integer.parseInt(args.get(indexNumberOfRecords + 1)); + } catch (NumberFormatException e) { + throw new InvalidCommandException("Invalid argument for number of records option.\n" + + "Option only accepts integer values." + + "Input \"history -h\" for help\n"); + } + } + + } + + private void getGameMode() throws InvalidCommandException { + int indexGameMode = args.indexOf("-" + GAME_MODE_OPTION); + if (indexGameMode == -1) { + throw new InvalidCommandException("Invalid command.\n" + + "Input \"history -h\" for help\n"); + } else { + if (args.size() < indexGameMode + 2) { + throw new InvalidCommandException("Missing argument for game more option.\n"); + } + gameMode = args.get(indexGameMode + 1); + + } + if (!gameMode.equals("time") && !gameMode.equals("word")) { + throw new InvalidCommandException("Invalid argument for game mode option.\n" + + "Input \"history -h\" for help\n"); + } else { + gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; + } + } + +} diff --git a/src/main/java/seedu/typists/command/ViewCommand.java b/src/main/java/seedu/typists/command/ViewCommand.java deleted file mode 100644 index 4546816bc9..0000000000 --- a/src/main/java/seedu/typists/command/ViewCommand.java +++ /dev/null @@ -1,85 +0,0 @@ -package seedu.typists.command; - -import seedu.typists.game.GameRecord; -import seedu.typists.game.GameRecordsManager; -import seedu.typists.ui.ViewCommandUi; - -import java.util.ArrayList; - -public class ViewCommand implements Command { - private int numberOfRecords = 10; - private String gameMode; - private ArrayList args; - private static final String GAME_MODE_OPTION = "g"; - private static final String NUMBER_OF_RECORDS_OPTION = "n"; - private static final String HELP_OPTION = "h"; - - - public void run(ArrayList args) { - this.args = args; - boolean isHelp = isHelpCommand(); - if (isHelp) { - ViewCommandUi.displayHelp(); - } else { - executeCommand(); - } - } - - private void executeCommand() { - GameRecordsManager gameRecordsManager = GameRecordsManager.getGameRecordsManager(); - parseCommand(); - ArrayList gameRecords = gameRecordsManager.getGameRecords(gameMode, numberOfRecords); - ViewCommandUi.displayGameRecords(gameRecords); - } - - - private boolean isHelpCommand() { - int indexHelp = args.indexOf("-" + HELP_OPTION); - if (indexHelp != -1) { - return true; - } else { - return false; - } - - } - - private void parseCommand() { - getGameMode(); - getNumberOfRecords(); - } - - private void getNumberOfRecords() { - int indexNumberOfRecords = args.indexOf("-" + NUMBER_OF_RECORDS_OPTION); - if (indexNumberOfRecords == -1) { - return; - } else { - try { - numberOfRecords = Integer.parseInt(args.get(indexNumberOfRecords + 1)); - } catch (NumberFormatException e) { - System.out.print("Invalid argument for number of records option.\n" - + "Option only accepts integer values." - + "Input \"View -h\" for help\n"); - } - } - - } - - private void getGameMode() { - int indexGameMode = args.indexOf("-" + GAME_MODE_OPTION); - if (indexGameMode == -1) { - System.out.print("Invalid command.\n" - + "Input \"View -h\" for help\n"); - return; - } else { - gameMode = args.get(indexGameMode + 1); - } - if (gameMode != "time" && gameMode != "word") { - System.out.print("Invalid argument for game mode option.\n" - + "Input \"View -h\" for help\n"); - return; - } else { - gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; - } - } - -} diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 202d174e2c..240d563563 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -19,6 +19,14 @@ public class Messages { + " ___/ / /_/ / / / / / / / ___ |/ _, _/ / / \n" + "/____/\\____/_/ /_/_/ /_/_/ |_/_/ |_| /_/"; + public static final String HISTORY = + " __ _____________________ ______ __\n" + + " / / / / _/ ___/_ __/ __ \\/ __ \\ \\/ /\n" + + " / /_/ // / \\__ \\ / / / / / / /_/ /\\ / \n" + + " / __ // / ___/ // / / /_/ / _, _/ / / \n" + + "/_/ /_/___//____//_/ \\____/_/ |_| /_/"; + + public static final String KEYBOARD = ",---,---,---,---,---,---,---,---,---,---,---,---,---,-------,\n" + "|1/2| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | + | ' | <- |\n" @@ -57,22 +65,23 @@ public class Messages { + "content: set the content\n" + "word: start a new word game\n" + "time: start a new timer game\n" + + "history: view past game records\n" + "bye: exit typist"; //This sample text is gotten from https://www.lipsum.com/ public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " - + "imply dummy text of the printing and typesetting industry ipum is simply dummy " - + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " - + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry "; + + "imply dummy text of the printing and typesetting industry ipum is simply dummy " + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry " + + "industry industry industry industry industry industry industry industry industry industry industry "; //public static final String MESSAGE_GOODBYE = "Goodbye!"; //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; diff --git a/src/main/java/seedu/typists/exception/InvalidCommandException.java b/src/main/java/seedu/typists/exception/InvalidCommandException.java index 762c54b2e1..c5c821c4af 100644 --- a/src/main/java/seedu/typists/exception/InvalidCommandException.java +++ b/src/main/java/seedu/typists/exception/InvalidCommandException.java @@ -1,4 +1,11 @@ package seedu.typists.exception; -public class InvalidCommandException extends Exception{ +public class InvalidCommandException extends Exception { + public InvalidCommandException(String errorMessage) { + super(errorMessage); + } + + public InvalidCommandException() { + super(); + } } diff --git a/src/main/java/seedu/typists/game/GameRecord.java b/src/main/java/seedu/typists/game/GameRecord.java index 571552e16a..43c16e948b 100644 --- a/src/main/java/seedu/typists/game/GameRecord.java +++ b/src/main/java/seedu/typists/game/GameRecord.java @@ -87,6 +87,12 @@ public String getStringFormat() { + separator + totalWordCount + separator + + errorWordPercentage + + separator + + correctWordPercentage + + separator + + wpm + + separator + errorWords.toString(); return formatted; diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index de4d2fca06..b1ff60757e 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -55,7 +55,7 @@ private GameRecord createGameRecord(HashMap gameSummary) { private void addRecordToArray(GameRecord gameRecord) { String gameMode = gameRecord.getGameMode(); - if (gameMode == "Word Limited") { + if (gameMode.equals("Word Limited")) { wordLimitedGameRecords.add(gameRecord); } else { timeLimitedGameRecords.add(gameRecord); @@ -64,13 +64,20 @@ private void addRecordToArray(GameRecord gameRecord) { public ArrayList getGameRecords(String gameMode, int numberOfRecords) { - assert ((gameMode == "Time-limited") || (gameMode == "Word-limited")); - if (gameMode == "Time-limited") { + + assert ((gameMode.equals("Time-limited")) || (gameMode.equals("Word-limited"))); + if (gameMode.equals("Time-limited")) { + if (numberOfRecords > timeLimitedGameRecords.size()) { + return null; + } return new ArrayList<>(timeLimitedGameRecords.subList( timeLimitedGameRecords.size() - numberOfRecords, timeLimitedGameRecords.size() )); } else { + if (numberOfRecords > wordLimitedGameRecords.size()) { + return null; + } return new ArrayList<>(wordLimitedGameRecords.subList( wordLimitedGameRecords.size() - numberOfRecords, wordLimitedGameRecords.size() @@ -88,4 +95,11 @@ private void writeRecordToFile(GameRecord gameRecord) { } } + public int getNumberOfGameRecords(String gameMode) { + if (gameMode.equals("Word-limited")) { + return wordLimitedGameRecords.size(); + } else { + return timeLimitedGameRecords.size(); + } + } } diff --git a/src/main/java/seedu/typists/game/SummaryManager.java b/src/main/java/seedu/typists/game/SummaryManager.java index 7fd363afd7..049e610033 100644 --- a/src/main/java/seedu/typists/game/SummaryManager.java +++ b/src/main/java/seedu/typists/game/SummaryManager.java @@ -55,9 +55,9 @@ private static ArrayList getErrorWords( assert expectedLine.size() > 0; ArrayList actualLine = new ArrayList<>(Arrays.asList(actualInput.get(outerLoopCount))); + int innerLoopCount = 0; for (String expectedWord : expectedLine) { - int innerLoopCount = 0; if (actualLine.size() == 0) { ArrayList remainingWords = new ArrayList<>( expectedLine.subList(innerLoopCount, expectedLine.size()) diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 9145b74e00..6145abe228 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -75,7 +75,7 @@ public void runGame() { } updateUserLines(inputs); ui.printScreen("Game Finished."); - HashMap summary = handleSummary(wordLines, userLines, realGameTime, "Word-limited"); + HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); handleStorage(summary); } } diff --git a/src/main/java/seedu/typists/ui/HistoryCommandUi.java b/src/main/java/seedu/typists/ui/HistoryCommandUi.java new file mode 100644 index 0000000000..36ab1500b8 --- /dev/null +++ b/src/main/java/seedu/typists/ui/HistoryCommandUi.java @@ -0,0 +1,29 @@ +package seedu.typists.ui; + +import seedu.typists.game.GameRecord; + +import java.util.ArrayList; + +import static seedu.typists.common.Messages.HISTORY; + +public class HistoryCommandUi { + public static void displayGameRecords(ArrayList gameRecords, int numberOfGameRecords) { + if (gameRecords == null) { + System.out.print("The number of game records you requested to view is more than what you have.\n" + + "Number of game records you have is " + numberOfGameRecords + ".\n"); + return; + } + System.out.print(HISTORY + "\n"); + if (gameRecords.size() == 0) { + System.out.print("No records to display.\n"); + } + for (GameRecord gameRecord : gameRecords) { + SummaryUi.displaySummary(gameRecord); + } + } + + public static void displayHelp() { + //do after user guide + System.out.print("display help placeholder\n"); + } +} diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index 84b08fbdc7..5588e9958d 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -34,6 +34,7 @@ public static void displaySummary(HashMap summary) { assert summary.get("timeElapsed") instanceof Double; assert summary.get("gameMode") instanceof String; assert summary.get("wordsPerMinute") instanceof Double; + printHeader(); printOverview( (Double) summary.get("timeElapsed"), (String) summary.get("gameMode"), @@ -98,7 +99,7 @@ static void printErrorWords(ArrayList errorWords) { if (i % 8 == 0) { System.out.print("\n"); } - System.out.print(errorWords.get(i)); + System.out.print(errorWords.get(i).trim()); if (i != (errorWords.size() - 1)) { System.out.print("|"); } @@ -109,12 +110,15 @@ static void printErrorWords(ArrayList errorWords) { } private static void printOverview(double timeElapsed, String gameMode, double wpm) { - System.out.print(SUMMARY + '\n'); System.out.print("Game Mode: " + gameMode + '\n'); System.out.print("WPM: " + String.format("%.2f", wpm) + '\n'); System.out.print("Total Time taken for the game: " + String.format("%.2f", timeElapsed) + " seconds\n"); } + private static void printHeader() { + System.out.print(SUMMARY + '\n'); + } + public static void setUpLog() { LogManager.getLogManager().reset(); LOGGER.setLevel(Level.ALL); diff --git a/src/main/java/seedu/typists/ui/ViewCommandUi.java b/src/main/java/seedu/typists/ui/ViewCommandUi.java deleted file mode 100644 index 6a1ba5d746..0000000000 --- a/src/main/java/seedu/typists/ui/ViewCommandUi.java +++ /dev/null @@ -1,18 +0,0 @@ -package seedu.typists.ui; - -import seedu.typists.game.GameRecord; - -import java.util.ArrayList; - -public class ViewCommandUi { - public static void displayGameRecords(ArrayList gameRecords) { - for (GameRecord gameRecord:gameRecords) { - SummaryUi.displaySummary(gameRecord); - } - } - - public static void displayHelp() { - //do after user guide - System.out.print("display help placeholder\n"); - } -} From da76407562f98f3516ef39aa8ede480742426071 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 16:19:21 +0800 Subject: [PATCH 135/272] Remove IO redirection test from CLI --- .github/workflows/gradle.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index fd8c44d086..ae06f4ee5a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -33,18 +33,18 @@ jobs: - name: Build and check with Gradle run: ./gradlew check - - name: Perform IO redirection test (*NIX) - if: runner.os == 'Linux' - working-directory: ${{ github.workspace }}/text-ui-test - run: ./runtest.sh - - - name: Perform IO redirection test (MacOS) - if: always() && runner.os == 'macOS' - working-directory: ${{ github.workspace }}/text-ui-test - run: ./runtest.sh - - - name: Perform IO redirection test (Windows) - if: always() && runner.os == 'Windows' - working-directory: ${{ github.workspace }}/text-ui-test - shell: cmd - run: runtest.bat \ No newline at end of file + #- name: Perform IO redirection test (*NIX) + # if: runner.os == 'Linux' + # working-directory: ${{ github.workspace }}/text-ui-test + # run: ./runtest.sh + + #- name: Perform IO redirection test (MacOS) + # if: always() && runner.os == 'macOS' + # working-directory: ${{ github.workspace }}/text-ui-test + # run: ./runtest.sh + + #- name: Perform IO redirection test (Windows) + # if: always() && runner.os == 'Windows' + # working-directory: ${{ github.workspace }}/text-ui-test + # shell: cmd + # run: runtest.bat \ No newline at end of file From 3af64f7a54166a2b53ce089091a51aa8b0449b7c Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 16:20:52 +0800 Subject: [PATCH 136/272] Add a println at exit command to inform user the program is updating the records --- src/main/java/seedu/typists/command/ExitCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/typists/command/ExitCommand.java b/src/main/java/seedu/typists/command/ExitCommand.java index ffbe5f2d4f..6138dd8f77 100644 --- a/src/main/java/seedu/typists/command/ExitCommand.java +++ b/src/main/java/seedu/typists/command/ExitCommand.java @@ -9,6 +9,7 @@ public class ExitCommand implements Command { @Override public void run(ArrayList args) { + System.out.println("Updating game records..."); GameRecordsManager gameRecordsManager = GameRecordsManager.getGameRecordsManager(); gameRecordsManager.updateGameRecords(); uiBot.showBye(); From 4e275dad6057f946d188bba3a1c0218792b85d09 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 16:53:04 +0800 Subject: [PATCH 137/272] Add ClearCommand class --- src/main/java/seedu/typists/Main.java | 6 +- .../seedu/typists/command/ClearCommand.java | 69 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/typists/command/ClearCommand.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 6f4f8c122b..f544b313b1 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -45,7 +45,11 @@ public void runCommandLoop() { do { String[] input = read().split(" "); command = input[0]; - args = new ArrayList(Arrays.asList(Arrays.copyOfRange(input,1,input.length))); + if (input.length>1) { + args = new ArrayList(Arrays.asList(Arrays.copyOfRange(input, 1, input.length))); + } else { + args = null; + } Command c = cmdFactory.getCommand(input[0]); if (c != null) { c.run(args); diff --git a/src/main/java/seedu/typists/command/ClearCommand.java b/src/main/java/seedu/typists/command/ClearCommand.java new file mode 100644 index 0000000000..1eb54ec5aa --- /dev/null +++ b/src/main/java/seedu/typists/command/ClearCommand.java @@ -0,0 +1,69 @@ +package seedu.typists.command; + +import seedu.typists.exception.InvalidCommandException; +import seedu.typists.game.GameRecordsManager; + +import java.util.ArrayList; + +public class ClearCommand implements Command{ + private int numberOfRecords = 0; + private String gameMode; + private ArrayList args; + GameRecordsManager gameRecordsManager; + private static final String HELP_OPTION = "h"; + private static final String GAME_MODE_OPTION = "g"; + private static final String NUMBER_OF_RECORDS_OPTION = "n"; + public void run(ArrayList args) { + this.args = args; + boolean isHelp = isHelpCommand(); + if (isHelp) { + ClearCommandUi.displayHelp(); + } else { + executeCommand(); + } + } + + public void executeCommand() { + gameRecordsManager = GameRecordsManager.getGameRecordsManager(); + try { + parseCommand(); + gameRecordsManager.clearGameRecords(gameMode); + } catch (InvalidCommandException e) { + String errorMessage = "Error: " + e.toString().split(":")[1]; + System.out.print(errorMessage); + } + } + + private boolean isHelpCommand() { + int indexHelp = args.indexOf("-" + HELP_OPTION); + if (indexHelp != -1) { + return true; + } else { + return false; + } + } + + private void parseCommand() throws InvalidCommandException { + getGameMode(); + } + + private void getGameMode() throws InvalidCommandException { + int indexGameMode = args.indexOf("-" + GAME_MODE_OPTION); + if (indexGameMode == -1) { + gameMode = "all"; + } else { + if (args.size() < indexGameMode + 2) { + throw new InvalidCommandException("Missing argument for game more option.\n"); + } + gameMode = args.get(indexGameMode + 1); + + } + if (!gameMode.equals("time") && !gameMode.equals("word")) { + throw new InvalidCommandException("Invalid argument for game mode option.\n" + + "Input \"history -h\" for help\n"); + } else { + gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; + } + } + +} From 3f83e2ef4784e99f4963b7b28bcf2ba72bac1952 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 17:50:32 +0800 Subject: [PATCH 138/272] Complete clear records feature Fixes #38 --- src/main/java/seedu/typists/Main.java | 6 +----- .../seedu/typists/command/ClearCommand.java | 18 ++++++++++++------ .../seedu/typists/command/CommandFactory.java | 2 ++ .../seedu/typists/command/HistoryCommand.java | 2 +- .../java/seedu/typists/common/Messages.java | 8 ++++++++ .../seedu/typists/game/GameRecordsManager.java | 16 ++++++++++++++-- .../java/seedu/typists/game/TimeModeGame.java | 2 +- .../java/seedu/typists/storage/FileParser.java | 2 +- .../java/seedu/typists/ui/ClearCommandUi.java | 15 +++++++++++++++ .../seedu/typists/ui/HistoryCommandUi.java | 4 ++++ src/main/java/seedu/typists/ui/SummaryUi.java | 5 +---- 11 files changed, 60 insertions(+), 20 deletions(-) create mode 100644 src/main/java/seedu/typists/ui/ClearCommandUi.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index fac7e10d31..943005f524 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -45,11 +45,7 @@ public void runCommandLoop() { do { String[] input = read().split(" "); command = input[0]; - if (input.length>1) { - args = new ArrayList(Arrays.asList(Arrays.copyOfRange(input, 1, input.length))); - } else { - args = null; - } + args = new ArrayList(Arrays.asList(Arrays.copyOfRange(input, 1, input.length))); Command c = cmdFactory.getCommand(input[0]); if (c != null) { c.run(args); diff --git a/src/main/java/seedu/typists/command/ClearCommand.java b/src/main/java/seedu/typists/command/ClearCommand.java index 1eb54ec5aa..580edabbce 100644 --- a/src/main/java/seedu/typists/command/ClearCommand.java +++ b/src/main/java/seedu/typists/command/ClearCommand.java @@ -2,17 +2,18 @@ import seedu.typists.exception.InvalidCommandException; import seedu.typists.game.GameRecordsManager; +import seedu.typists.ui.ClearCommandUi; import java.util.ArrayList; -public class ClearCommand implements Command{ +public class ClearCommand implements Command { private int numberOfRecords = 0; private String gameMode; private ArrayList args; GameRecordsManager gameRecordsManager; private static final String HELP_OPTION = "h"; private static final String GAME_MODE_OPTION = "g"; - private static final String NUMBER_OF_RECORDS_OPTION = "n"; + public void run(ArrayList args) { this.args = args; boolean isHelp = isHelpCommand(); @@ -27,7 +28,8 @@ public void executeCommand() { gameRecordsManager = GameRecordsManager.getGameRecordsManager(); try { parseCommand(); - gameRecordsManager.clearGameRecords(gameMode); + gameRecordsManager.clearAllRecords(gameMode); + ClearCommandUi.displaySuccess(gameMode); } catch (InvalidCommandException e) { String errorMessage = "Error: " + e.toString().split(":")[1]; System.out.print(errorMessage); @@ -53,16 +55,20 @@ private void getGameMode() throws InvalidCommandException { gameMode = "all"; } else { if (args.size() < indexGameMode + 2) { - throw new InvalidCommandException("Missing argument for game more option.\n"); + throw new InvalidCommandException("Missing argument for game mode option.\n"); } gameMode = args.get(indexGameMode + 1); } - if (!gameMode.equals("time") && !gameMode.equals("word")) { + if (!gameMode.equals("time") && !gameMode.equals("word") && !gameMode.equals("all")) { throw new InvalidCommandException("Invalid argument for game mode option.\n" + "Input \"history -h\" for help\n"); } else { - gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; + if (gameMode.equals("all")) { + gameMode = "all"; + } else { + gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; + } } } diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 63e4dcf59d..93eb23812f 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -17,6 +17,8 @@ public Command getCommand(String commandType) { return new ErrorCommand(); case "history": return new HistoryCommand(); + case "clear": + return new ClearCommand(); case "bye": return new ExitCommand(); default: diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/HistoryCommand.java index f53ad0be29..ff9d7b8f68 100644 --- a/src/main/java/seedu/typists/command/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/HistoryCommand.java @@ -84,7 +84,7 @@ private void getGameMode() throws InvalidCommandException { + "Input \"history -h\" for help\n"); } else { if (args.size() < indexGameMode + 2) { - throw new InvalidCommandException("Missing argument for game more option.\n"); + throw new InvalidCommandException("Missing argument for game mode option.\n"); } gameMode = args.get(indexGameMode + 1); diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 240d563563..eb3bd5a76a 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -26,6 +26,13 @@ public class Messages { + " / __ // / ___/ // / / /_/ / _, _/ / / \n" + "/_/ /_/___//____//_/ \\____/_/ |_| /_/"; + public static final String CLEAR_RECORDS = + " ________ _________ ____ ____ ________________ ____ ____ _____\n" + + " / ____/ / / ____/ | / __ \\ / __ \\/ ____/ ____/ __ \\/ __ \\/ __ \\/ ___/\n" + + " / / / / / __/ / /| | / /_/ / / /_/ / __/ / / / / / / /_/ / / / /\\__ \\ \n" + + "/ /___/ /___/ /___/ ___ |/ _, _/ / _, _/ /___/ /___/ /_/ / _, _/ /_/ /___/ / \n" + + "\\____/_____/_____/_/ |_/_/ |_| /_/ |_/_____/\\____/\\____/_/ |_/_____//____/ \n"; + public static final String KEYBOARD = ",---,---,---,---,---,---,---,---,---,---,---,---,---,-------,\n" @@ -66,6 +73,7 @@ public class Messages { + "word: start a new word game\n" + "time: start a new timer game\n" + "history: view past game records\n" + + "clear: clear all game records\n" + "bye: exit typist"; //This sample text is gotten from https://www.lipsum.com/ diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index b1ff60757e..6a7532e704 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -55,7 +55,7 @@ private GameRecord createGameRecord(HashMap gameSummary) { private void addRecordToArray(GameRecord gameRecord) { String gameMode = gameRecord.getGameMode(); - if (gameMode.equals("Word Limited")) { + if (gameMode.equals("Word-limited")) { wordLimitedGameRecords.add(gameRecord); } else { timeLimitedGameRecords.add(gameRecord); @@ -87,7 +87,7 @@ public ArrayList getGameRecords(String gameMode, int numberOfRecords private void writeRecordToFile(GameRecord gameRecord) { String gameMode = gameRecord.getGameMode(); - if (gameMode == "Word Limited") { + if (gameMode.equals("Word-limited")) { Storage.writeGameRecords(wordLimitedGameRecords, "Word-limited"); } else { Storage.writeGameRecords(timeLimitedGameRecords, "Time-limited"); @@ -102,4 +102,16 @@ public int getNumberOfGameRecords(String gameMode) { return timeLimitedGameRecords.size(); } } + + public void clearAllRecords(String gameMode) { + assert (gameMode.equals("Time-limited") || gameMode.equals("Word-limited") || gameMode.equals("all")); + if (gameMode.equals("Word-limited")) { + wordLimitedGameRecords.clear(); + } else if (gameMode.equals("Time-limited")) { + timeLimitedGameRecords.clear(); + } else { + wordLimitedGameRecords.clear(); + timeLimitedGameRecords.clear(); + } + } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 6145abe228..ae3164991a 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -75,7 +75,7 @@ public void runGame() { } updateUserLines(inputs); ui.printScreen("Game Finished."); - HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); + HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Time-limited"); handleStorage(summary); } } diff --git a/src/main/java/seedu/typists/storage/FileParser.java b/src/main/java/seedu/typists/storage/FileParser.java index 10e8da0ad9..bf51fc10c1 100644 --- a/src/main/java/seedu/typists/storage/FileParser.java +++ b/src/main/java/seedu/typists/storage/FileParser.java @@ -67,7 +67,7 @@ private static double getWpm(String[] wpmString) { } private static ArrayList getErrorWords(String[] gameRecordStats) { - if (gameRecordStats.length <= 8) { + if (gameRecordStats[8].trim().equals("[]")) { return new ArrayList<>(); } String[] errorWords = gameRecordStats[8].substring(1, gameRecordStats[8].length() - 1).split(","); diff --git a/src/main/java/seedu/typists/ui/ClearCommandUi.java b/src/main/java/seedu/typists/ui/ClearCommandUi.java new file mode 100644 index 0000000000..4fbb5aeab2 --- /dev/null +++ b/src/main/java/seedu/typists/ui/ClearCommandUi.java @@ -0,0 +1,15 @@ +package seedu.typists.ui; + +import static seedu.typists.common.Messages.CLEAR_RECORDS; + +public class ClearCommandUi { + + public static void displayHelp() { + //update after finish UG + } + + public static void displaySuccess(String gameMode) { + System.out.print(CLEAR_RECORDS + "\n"); + System.out.println("Successfully cleared " + gameMode + " game records.\n"); + } +} diff --git a/src/main/java/seedu/typists/ui/HistoryCommandUi.java b/src/main/java/seedu/typists/ui/HistoryCommandUi.java index 36ab1500b8..48a33a7f82 100644 --- a/src/main/java/seedu/typists/ui/HistoryCommandUi.java +++ b/src/main/java/seedu/typists/ui/HistoryCommandUi.java @@ -7,6 +7,9 @@ import static seedu.typists.common.Messages.HISTORY; public class HistoryCommandUi { + private static final String SUMMARY_SEPARATOR = + "=================================================================="; + public static void displayGameRecords(ArrayList gameRecords, int numberOfGameRecords) { if (gameRecords == null) { System.out.print("The number of game records you requested to view is more than what you have.\n" @@ -19,6 +22,7 @@ public static void displayGameRecords(ArrayList gameRecords, int num } for (GameRecord gameRecord : gameRecords) { SummaryUi.displaySummary(gameRecord); + System.out.print(SUMMARY_SEPARATOR + "\n"); } } diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index 5588e9958d..fb04b343c5 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -91,7 +91,6 @@ static void printErrorWords(ArrayList errorWords) { System.out.print("Mistakes: "); if (errorWords.size() == 0) { System.out.print("No words typed wrongly.\n"); - return; } for (int i = 0; i < errorWords.size(); i++) { @@ -104,9 +103,7 @@ static void printErrorWords(ArrayList errorWords) { System.out.print("|"); } } - if ((errorWords.size() - 1) % 8 != 0) { - System.out.print("\n"); - } + System.out.print("\n"); } private static void printOverview(double timeElapsed, String gameMode, double wpm) { From b576641ddb79d9b0f3585bfa30341714a29c5120 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 20:26:38 +0800 Subject: [PATCH 139/272] TimerMode Enhance Create gameUi class delete dataprocessor class fix bugs --- seedu.typists.ui.TextUi.log | 2 + seedu.typists.ui.TextUi.log.lck | 0 src/main/java/seedu/typists/Main.java | 2 - .../typists/command/TimeGameCommand.java | 16 +--- .../java/seedu/typists/common/Messages.java | 11 +-- .../seedu/typists/game/DataProcessor.java | 85 ------------------- .../java/seedu/typists/game/ErrorGame.java | 5 ++ src/main/java/seedu/typists/game/Game.java | 9 +- .../java/seedu/typists/game/TimeModeGame.java | 76 ++++++++++------- .../seedu/typists/game/WordLimitGame.java | 5 ++ src/main/java/seedu/typists/ui/GameUi.java | 29 +++++++ .../seedu/typists/ui/HistoryCommandUi.java | 2 +- src/main/java/seedu/typists/ui/SummaryUi.java | 2 +- time-limited_records.txt | 4 + word-limited_records.txt | 0 15 files changed, 102 insertions(+), 146 deletions(-) create mode 100644 seedu.typists.ui.TextUi.log create mode 100644 seedu.typists.ui.TextUi.log.lck delete mode 100644 src/main/java/seedu/typists/game/DataProcessor.java create mode 100644 src/main/java/seedu/typists/ui/GameUi.java create mode 100644 time-limited_records.txt create mode 100644 word-limited_records.txt diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log new file mode 100644 index 0000000000..0432929693 --- /dev/null +++ b/seedu.typists.ui.TextUi.log @@ -0,0 +1,2 @@ +Oct 27, 2021 8:25:01 PM seedu.typists.ui.SummaryUi setUpLog +INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index f033612cfa..afcda7bb24 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -53,8 +53,6 @@ public void runCommandLoop() { } while (!command.equals("bye")); } - public void exit() { - } /** * Runs the program until termination. diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 7ef267c3b7..cda31b522a 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -1,6 +1,5 @@ package seedu.typists.command; -import seedu.typists.game.DataProcessor; import seedu.typists.game.TimeModeGame; import java.util.ArrayList; @@ -17,23 +16,10 @@ public class TimeGameCommand implements Command { public void run(ArrayList args) { TimeModeGame game = createGame(); game.runGame(); - process(game); - printUserInput(game); + game.gameSummary(); } public TimeModeGame createGame() { return new TimeModeGame(content.getContent(), LINE_LENGTH); } - - public void process(TimeModeGame tg) { - DataProcessor dp = new DataProcessor(tg); - } - - public void printUserInput(TimeModeGame tg) { - uiBot.printScreen("user input is: "); - for (String[] sa : tg.userLines) { - uiBot.printScreen(Arrays.toString(sa)); - } - } - } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 240d563563..3a18b89fd3 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -68,6 +68,8 @@ public class Messages { + "history: view past game records\n" + "bye: exit typist"; + public static String MESSAGE_TIME_GAME_END = "Timer's UP!"; + //This sample text is gotten from https://www.lipsum.com/ public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " + "imply dummy text of the printing and typesetting industry ipum is simply dummy " @@ -82,13 +84,4 @@ public class Messages { + "industry industry industry industry industry industry industry industry industry industry industry " + "industry industry industry industry industry industry industry industry industry industry industry " + "industry industry industry industry industry industry industry industry industry industry industry "; - - //public static final String MESSAGE_GOODBYE = "Goodbye!"; - //public static final String MESSAGE_INIT_FAILED = "Failed to initialise address book application. Exiting..."; - //public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - //public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; - //public static final String MESSAGE_PERSON_NOT_FOUND = "Person could not be found in address book"; - //public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; - //public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " - // + "java seedu.typists.Main [STORAGE_FILE_PATH]"; } diff --git a/src/main/java/seedu/typists/game/DataProcessor.java b/src/main/java/seedu/typists/game/DataProcessor.java deleted file mode 100644 index 7d3c0f089f..0000000000 --- a/src/main/java/seedu/typists/game/DataProcessor.java +++ /dev/null @@ -1,85 +0,0 @@ -package seedu.typists.game; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static seedu.typists.Main.LINE_LENGTH; -import static seedu.typists.common.Utils.getWordLineFromStringArray; - -public class DataProcessor { - private static final Logger logger = Logger.getLogger("Foo"); - private final List checkerWordLines; - private final List userWordLines; - public final double totalTime; - private final List errorWords; - - public DataProcessor(TimeModeGame tg) { - this.checkerWordLines = tg.wordLines; - this.userWordLines = tg.userLines; - this.totalTime = tg.realGameTime; - this.errorWords = getErrorWords(); - } - - /** Get the list of words that the user made mistakes on. */ - public List getErrorWords() { - List errorWords = new ArrayList<>(); - int i = 0; - for (String[] sa : userWordLines) { - String[] checker = checkerWordLines.get(i); - int ii = 0; - for (String s : checker) { - try { - if (!s.equals(sa[ii])) { - errorWords.add(s); - } - } catch (ArrayIndexOutOfBoundsException e) { - logger.log(Level.INFO, "word(s) missed during input."); - } - ii++; - } - i++; - } - return errorWords; - } - - /** Get the total number of wrong words typed.*/ - public int getErrorWordCount() { - return errorWords.size(); - } - - public int getTotalWordTyped() { - return userWordLines.size() * LINE_LENGTH; - } - - public double getWordPerMinute() { - return getTotalWordTyped() / (totalTime / 60); - } - - public void getWrongKeyStrokes(ArrayList checkerText, ArrayList userText) { - int totalErrorCount = 0; - for (int i = 0; i < userText.size(); i++) { - totalErrorCount += getLineWrongKeyStrokes(checkerText.get(i), userText.get(i)); - } - System.out.println("Total number of wrong keystrokes: " + totalErrorCount); - } - - public int getLineWrongKeyStrokes(String checker, String answer) { - int errorCount = 0; - for (int i = 0; i < checker.length(); i++) { - try { - if (checker.charAt(i) != answer.charAt(i)) { - errorCount++; - } - } catch (StringIndexOutOfBoundsException e) { - errorCount++; - } - } - return errorCount; - } - - public double getErrorPercentage() { - return (double) getErrorWordCount() / (double) getTotalWordTyped(); - } -} \ No newline at end of file diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java index 44884e5632..d4e2fdeace 100644 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -43,4 +43,9 @@ public void runGame() { } System.out.println("Game Finished."); } + + @Override + public void gameSummary() { + + } } diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 21297e5dca..732e49fe3a 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -1,5 +1,6 @@ package seedu.typists.game; +import seedu.typists.ui.GameUi; import seedu.typists.ui.SummaryUi; import seedu.typists.ui.TextUi; @@ -7,25 +8,27 @@ import java.util.HashMap; public abstract class Game { - protected final TextUi ui; + protected final GameUi ui; public ArrayList displayedLines; public ArrayList userLines; public Game() { - this.ui = new TextUi(); + this.ui = new GameUi(); } public long getTimeNow() { return System.currentTimeMillis(); } - public double duration(long startTime, long endTime) { + public double getDuration(long startTime, long endTime) { return (double) (endTime - startTime) / 1000; } public abstract void runGame(); + public abstract void gameSummary(); + public HashMap handleSummary( ArrayList expectedInput, ArrayList actualInput, double timeElapsed, String gameMode ) { diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 6145abe228..611ef0f69c 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -7,33 +7,25 @@ import java.util.logging.Level; import java.util.logging.Logger; -import static seedu.typists.common.Utils.getWordLineFromStringArray; -import static seedu.typists.common.Utils.getWordLines; +import static seedu.typists.common.Messages.MESSAGE_TIME_GAME_END; +import static seedu.typists.common.Utils.*; public class TimeModeGame extends Game { protected static final Logger logger = Logger.getLogger("Foo"); protected int gameTime; - protected final ArrayList wordLines; + protected final ArrayList wordLists; + protected int wordsPerLine; public double realGameTime; public TimeModeGame(String targetWordSet, int wordsPerLine) { super(); assert targetWordSet != null : "text passed into Time Game should not be null."; - this.wordLines = getWordLines(targetWordSet, wordsPerLine); + this.wordLists = splitStringIntoWordList(targetWordSet); this.userLines = new ArrayList<>(); this.displayedLines = new ArrayList<>(); this.gameTime = getGameTime(); - } - - public boolean readyToStartTimer() { - Scanner in = new Scanner(System.in); - String command = ""; - while (!command.equals("yes")) { - ui.printScreen("Do you want to start now?"); - command = in.nextLine(); - } - return true; + this.wordsPerLine = wordsPerLine; } public int getGameTime() { @@ -47,39 +39,63 @@ public int getGameTime() { } } + public void runGame() { Scanner in = new Scanner(System.in); List inputs = new ArrayList<>(); - if (readyToStartTimer()) { - int i = 0; - long beginTime = System.currentTimeMillis(); + if (ui.readyToStartTimer()) { + int currentRow = 1; + long beginTime = getTimeNow(); boolean timeOver = false; while (!timeOver) { - long currTime = System.currentTimeMillis() - beginTime; + long currTime = getTimeNow() - beginTime; if (currTime >= gameTime * 1000L) { - timeOver = true; realGameTime = (double) currTime / 1000; + timeOver = true; } else { - try { - String[] display = wordLines.get(i); - ui.printLine(display); - displayedLines.add(display); - } catch (IndexOutOfBoundsException e) { - logger.log(Level.WARNING, "no more content."); - } + String[] display = getDisplayLines(currentRow); + ui.printLine(display); + displayedLines.add(display); inputs.add(in.nextLine()); - i++; + currentRow++; } } + updateUserLines(inputs); - ui.printScreen("Game Finished."); - HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); - handleStorage(summary); + endGame(); + } + } + + public void endGame() { + ui.printEnd(MESSAGE_TIME_GAME_END); + double overshoot = realGameTime - gameTime; + assert overshoot >= 0; + if (overshoot > 0) { + ui.printOvershoot(overshoot); } } + public String[] getDisplayLines (int row) { + int startIndex = (row - 1) * wordsPerLine; + assert startIndex >= 0 : "word index should be non-negative"; + String[] line = new String[wordsPerLine]; + try { + for (int i = 0; i < wordsPerLine; i++) { + line[i] = wordLists.get(startIndex + i); + } + } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "exceed content maximum."); + } + return line; + } + + public void gameSummary() { + HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); + handleStorage(summary); + } + public void updateUserLines(List stringArray) { userLines = getWordLineFromStringArray(stringArray); diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index a828c51640..92cae6b7d9 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -39,6 +39,11 @@ public void runGame() { } } + @Override + public void gameSummary() { + + } + public int getTotalSentence() { return eachWord.size(); } diff --git a/src/main/java/seedu/typists/ui/GameUi.java b/src/main/java/seedu/typists/ui/GameUi.java new file mode 100644 index 0000000000..1039f13a9c --- /dev/null +++ b/src/main/java/seedu/typists/ui/GameUi.java @@ -0,0 +1,29 @@ +package seedu.typists.ui; + +import java.util.Scanner; + +public class GameUi extends TextUi { + + public void printEnd(String endMessage) { + printScreen(endMessage); + } + + public boolean readyToStartTimer() { + Scanner in = new Scanner(System.in); + String command = ""; + while (!command.equals("yes")) { + printScreen("Do you want to start now?"); + command = in.nextLine(); + } + return true; + } + + public void printOvershoot(double overshoot) { + printScreen( + "While on your last sentence, " + + "you exceeds the game by " + + String.format("%.2f", overshoot) + + " seconds." + ); + } +} diff --git a/src/main/java/seedu/typists/ui/HistoryCommandUi.java b/src/main/java/seedu/typists/ui/HistoryCommandUi.java index 36ab1500b8..5aa4e2d2ae 100644 --- a/src/main/java/seedu/typists/ui/HistoryCommandUi.java +++ b/src/main/java/seedu/typists/ui/HistoryCommandUi.java @@ -6,7 +6,7 @@ import static seedu.typists.common.Messages.HISTORY; -public class HistoryCommandUi { +public class HistoryCommandUi extends TextUi { public static void displayGameRecords(ArrayList gameRecords, int numberOfGameRecords) { if (gameRecords == null) { System.out.print("The number of game records you requested to view is more than what you have.\n" diff --git a/src/main/java/seedu/typists/ui/SummaryUi.java b/src/main/java/seedu/typists/ui/SummaryUi.java index 5588e9958d..ff08735d52 100644 --- a/src/main/java/seedu/typists/ui/SummaryUi.java +++ b/src/main/java/seedu/typists/ui/SummaryUi.java @@ -15,7 +15,7 @@ import static seedu.typists.common.Messages.SUMMARY; -public class SummaryUi { +public class SummaryUi extends TextUi { private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); diff --git a/time-limited_records.txt b/time-limited_records.txt new file mode 100644 index 0000000000..e27388598a --- /dev/null +++ b/time-limited_records.txt @@ -0,0 +1,4 @@ +Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] +Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] +Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] diff --git a/word-limited_records.txt b/word-limited_records.txt new file mode 100644 index 0000000000..e69de29bb2 From b1c51e58e2948897fe782265d5a260d3e0e73fd6 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 20:41:29 +0800 Subject: [PATCH 140/272] update to pass test --- seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.lck | 0 src/main/java/seedu/typists/game/TimeModeGame.java | 5 +++-- text-ui-test/EXPECTED.TXT | 5 ++++- word-limited_records.txt | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 seedu.typists.ui.TextUi.log.lck diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 0432929693..f73cd9832c 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 27, 2021 8:25:01 PM seedu.typists.ui.SummaryUi setUpLog +Oct 27, 2021 8:39:29 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 611ef0f69c..4beb9dcfaf 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -8,7 +8,8 @@ import java.util.logging.Logger; import static seedu.typists.common.Messages.MESSAGE_TIME_GAME_END; -import static seedu.typists.common.Utils.*; +import static seedu.typists.common.Utils.getWordLineFromStringArray; +import static seedu.typists.common.Utils.splitStringIntoWordList; public class TimeModeGame extends Game { protected static final Logger logger = Logger.getLogger("Foo"); @@ -77,7 +78,7 @@ public void endGame() { } } - public String[] getDisplayLines (int row) { + public String[] getDisplayLines(int row) { int startIndex = (row - 1) * wordsPerLine; assert startIndex >= 0 : "word index should be non-negative"; String[] line = new String[wordsPerLine]; diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index da9337bae3..bca340e8cf 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,4 +1,4 @@ - | Typist - Version 1.0 + | Typist - Version 2.0 | =========================================================== | ______ _ __ | /_ __/_ ______ (_)____/ /_ @@ -12,6 +12,9 @@ | content: set the content | word: start a new word game | time: start a new timer game + | history: view past game records + | clear: clear all game records | bye: exit typist | =========================================================== +Updating game records... | Bye. Hope to see you again soon! diff --git a/word-limited_records.txt b/word-limited_records.txt index e69de29bb2..fe445196fd 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -0,0 +1 @@ +Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] From cbe850862b8fcea229d7347ba9892473b1e942d5 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 21:41:10 +0800 Subject: [PATCH 141/272] Edit description of View Statistics feature --- docs/DeveloperGuide.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0544772cdb..8b7911549c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -30,7 +30,6 @@ Gonna to change this .puml diagram later - zhansen ### Time Limit Game ### \[Proposed\] View Statistics feature -An enhancement of view best statistics feature. #### \[Proposed Implementation\] The top-level logic of view statistics feature resides in ViewStatistics. It implements the Command interface. The key methods in the ViewStatistics class is @@ -39,19 +38,24 @@ interface. The key methods in the ViewStatistics class is * `calculateWorstStatistics()` - Returns the worst statistics over the past n games * `calculateAverageStatistics()` - Returns the average statistics over the past n games -Given below is an example usage scenario and how the program implements the feature +Given below is an example usage scenario and how the program implements the feature. Step 1: The user launches the application (scenario assumes that there are several game records already stored in multiple files). -1. The program carries out the initialization code and creates a HistoryManager object. - -Step 2: The user executes `view -m best -g game error -n 9` to view his/her best statistics for the error game mode over the past 9 games. -1. A ViewCommand object is then instantiated. -2. ViewCommand calls the retrieveStatistics() method of RetrieveStatisticsManager. -3. RetrieveStatisticsManager then calls the getNGames() method of historyManager() and self-invokes calculateBestStatistics(). -4. calculateBestStatistics() returns a HashMap containing the statistics. -5. The statistics are then displayed using the displayStatistics() method of StatisticsUI class. - +Step 2: The user executes `view -m best -g game error -n 9` to view his/her best statistics for the error game mode over the past 9 games. + +Step 3: A ViewCommand object is then instantiated. + +Step 4. ViewCommand calls the retrieveStatistics() method of RetrieveStatisticsManager. + +Step 5: RetrieveStatisticsManager creates a GameRecordsManager object. +* The constructor of GameRecordsManager calls the readGameRecords() method of the Storage class to retrieve the gamer's past game records from the text files. + +Step 7. RetrieveStatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). +* calculateBestStatistics() returns a HashMap containing the statistics. + +Step 8. RetrieveStatisticsManager calls displayStatistics of the ViewStatisticsUI class to display the statistics. + The following sequence diagram shows how the above scenario is executed @@ -99,3 +103,5 @@ Our product is a typing game, intent to provide enjoyment for people who are fam ## Instructions for manual testing {Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} + + From e77e0e9d300271ec65dc9b93d6d7c46027b1e85b Mon Sep 17 00:00:00 2001 From: Lim Jia Jing <80034449+LimJiaJing@users.noreply.github.com> Date: Wed, 27 Oct 2021 21:42:12 +0800 Subject: [PATCH 142/272] View Statistics Object Diagram.drawio.png --- docs/uml/Untitled Diagram.drawio.png | Bin 0 -> 21691 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/uml/Untitled Diagram.drawio.png diff --git a/docs/uml/Untitled Diagram.drawio.png b/docs/uml/Untitled Diagram.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..24a489d8476690b1de32448f432170ba88537516 GIT binary patch literal 21691 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 literal 0 HcmV?d00001 From 4ec260e1ff5cf853536a73d1dad80012645bea15 Mon Sep 17 00:00:00 2001 From: Lim Jia Jing <80034449+LimJiaJing@users.noreply.github.com> Date: Wed, 27 Oct 2021 21:43:53 +0800 Subject: [PATCH 143/272] Change style of object diagram --- docs/uml/Untitled Diagram.drawio.png | Bin 21691 -> 24172 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/uml/Untitled Diagram.drawio.png b/docs/uml/Untitled Diagram.drawio.png index 24a489d8476690b1de32448f432170ba88537516..a5e1f323cb9db1f3fff36c68a9a706050b98b1a5 100644 GIT binary patch literal 24172 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 literal 21691 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 From bfe56d1fa8bad9a20ed8989e4cf1088500f87abe Mon Sep 17 00:00:00 2001 From: Lim Jia Jing <80034449+LimJiaJing@users.noreply.github.com> Date: Wed, 27 Oct 2021 21:48:37 +0800 Subject: [PATCH 144/272] Add 3 object diagrams --- docs/uml/Untitled Diagram.drawio.png | Bin 24172 -> 6399 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/uml/Untitled Diagram.drawio.png b/docs/uml/Untitled Diagram.drawio.png index a5e1f323cb9db1f3fff36c68a9a706050b98b1a5..b4e7c63293776a1665c9d703a799748cd654fe4e 100644 GIT binary patch literal 6399 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 literal 24172 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 From edaf6c7a6e3600bdf21c16d6bd7b409731fc59e4 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 22:12:01 +0800 Subject: [PATCH 145/272] Add three object diagrams. Change to using svg file. Stop using drawio/mode=github. --- docs/uml/Untitled Diagram.drawio.png | Bin 6399 -> 0 bytes docs/uml/ViewStatistics-1.drawio.svg | 4 ++++ docs/uml/ViewStatistics-2.drawio.svg | 4 ++++ docs/uml/ViewStatistics-3.drawio.svg | 4 ++++ 4 files changed, 12 insertions(+) delete mode 100644 docs/uml/Untitled Diagram.drawio.png create mode 100644 docs/uml/ViewStatistics-1.drawio.svg create mode 100644 docs/uml/ViewStatistics-2.drawio.svg create mode 100644 docs/uml/ViewStatistics-3.drawio.svg diff --git a/docs/uml/Untitled Diagram.drawio.png b/docs/uml/Untitled Diagram.drawio.png deleted file mode 100644 index b4e7c63293776a1665c9d703a799748cd654fe4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6399 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 diff --git a/docs/uml/ViewStatistics-1.drawio.svg b/docs/uml/ViewStatistics-1.drawio.svg new file mode 100644 index 0000000000..0db5031503 --- /dev/null +++ b/docs/uml/ViewStatistics-1.drawio.svg @@ -0,0 +1,4 @@ + + + +
:ViewCommand
:ViewCommand
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-2.drawio.svg b/docs/uml/ViewStatistics-2.drawio.svg new file mode 100644 index 0000000000..61ec7b7890 --- /dev/null +++ b/docs/uml/ViewStatistics-2.drawio.svg @@ -0,0 +1,4 @@ + + + +
uses
uses
:RetrieveStatisitcsManager
:RetrieveStatisi...
:ViewCommand
:ViewCommand
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio.svg b/docs/uml/ViewStatistics-3.drawio.svg new file mode 100644 index 0000000000..ea89d480dc --- /dev/null +++ b/docs/uml/ViewStatistics-3.drawio.svg @@ -0,0 +1,4 @@ + + + +
:RetrieveStatisitcsManager
:RetrieveStatisi...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file From c2d456761d3de1c0192e941a2856fc390b4152d7 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 22:14:15 +0800 Subject: [PATCH 146/272] Add 3 object diagrams into DG --- docs/DeveloperGuide.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8b7911549c..5b24e35f93 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -44,17 +44,22 @@ Step 1: The user launches the application (scenario assumes that there are sever Step 2: The user executes `view -m best -g game error -n 9` to view his/her best statistics for the error game mode over the past 9 games. -Step 3: A ViewCommand object is then instantiated. +Step 3: A ViewCommand object is then instantiated. + +![Alt text](uml/ViewStatistics-1.drawio.svg) + +Step 4. ViewCommand calls the retrieveStatistics() method of RetrieveStatisticsManager. +![Alt text](uml/ViewStatistics-2.drawio.svg) -Step 4. ViewCommand calls the retrieveStatistics() method of RetrieveStatisticsManager. Step 5: RetrieveStatisticsManager creates a GameRecordsManager object. * The constructor of GameRecordsManager calls the readGameRecords() method of the Storage class to retrieve the gamer's past game records from the text files. - -Step 7. RetrieveStatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). + +![Alt text](uml/ViewStatistics-3.drawio.svg) +Step 6. RetrieveStatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). * calculateBestStatistics() returns a HashMap containing the statistics. -Step 8. RetrieveStatisticsManager calls displayStatistics of the ViewStatisticsUI class to display the statistics. +Step 7. RetrieveStatisticsManager calls displayStatistics of the ViewStatisticsUI class to display the statistics. The following sequence diagram shows how the above scenario is executed @@ -104,4 +109,3 @@ Our product is a typing game, intent to provide enjoyment for people who are fam {Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} - From 4df2d847a9b2d73cf1981be6b24e57915f0249ff Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 22:21:38 +0800 Subject: [PATCH 147/272] Complete object diagram part of View Statistics feature explanation. --- docs/DeveloperGuide.md | 6 +++--- docs/uml/ViewStatistics-4.drawio.svg | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 docs/uml/ViewStatistics-4.drawio.svg diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 5b24e35f93..59c3847ff0 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -57,14 +57,14 @@ Step 5: RetrieveStatisticsManager creates a GameRecordsManager object. ![Alt text](uml/ViewStatistics-3.drawio.svg) Step 6. RetrieveStatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). -* calculateBestStatistics() returns a HashMap containing the statistics. -Step 7. RetrieveStatisticsManager calls displayStatistics of the ViewStatisticsUI class to display the statistics. +Step 7. RetrieveStatisticsManager calls displayStatistics of the ViewCommandUI class to display the statistics. +![Alt test](uml/ViewStatistics-4.drawio.svg) The following sequence diagram shows how the above scenario is executed +![Alt test](uml/ViewStatistics-5.drawio.svg) -The following class diagram shows the relationship among the main involved classes #### Alternative Implementation diff --git a/docs/uml/ViewStatistics-4.drawio.svg b/docs/uml/ViewStatistics-4.drawio.svg new file mode 100644 index 0000000000..527931084b --- /dev/null +++ b/docs/uml/ViewStatistics-4.drawio.svg @@ -0,0 +1,4 @@ + + + +
:RetrieveStatisitcsManager
:RetrieveStatisi...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file From c59e1d8158996865c4ab3dd96450eb412261ff49 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 23:11:40 +0800 Subject: [PATCH 148/272] Update parser for timemodegame --- seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.lck | 0 src/main/java/seedu/typists/Main.java | 3 +- .../typists/command/TimeGameCommand.java | 43 +++++++++++++--- src/main/java/seedu/typists/common/Utils.java | 19 +++++++ .../exception/IncompleteCommandException.java | 5 ++ src/main/java/seedu/typists/game/Game.java | 5 +- .../java/seedu/typists/game/TimeModeGame.java | 50 ++++--------------- src/main/java/seedu/typists/ui/GameUi.java | 5 ++ src/main/java/seedu/typists/ui/TextUi.java | 22 +------- time-limited_records.txt | 3 +- word-limited_records.txt | 1 + 12 files changed, 84 insertions(+), 74 deletions(-) create mode 100644 seedu.typists.ui.TextUi.log.lck create mode 100644 src/main/java/seedu/typists/exception/IncompleteCommandException.java diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index f73cd9832c..4775273733 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 27, 2021 8:39:29 PM seedu.typists.ui.SummaryUi setUpLog +Oct 27, 2021 11:09:05 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 3557a2bee9..1f41bcbe38 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -41,11 +41,10 @@ public String read() { public void runCommandLoop() { CommandFactory cmdFactory = new CommandFactory(); String command; - ArrayList args; do { String[] input = read().split(" "); command = input[0]; - args = new ArrayList(Arrays.asList(Arrays.copyOfRange(input, 1, input.length))); + ArrayList args = new ArrayList<>(Arrays.asList(Arrays.copyOfRange(input, 1, input.length))); Command c = cmdFactory.getCommand(input[0]); if (c != null) { c.run(args); diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index cda31b522a..834260730f 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -1,25 +1,54 @@ package seedu.typists.command; +import seedu.typists.exception.IncompleteCommandException; +import seedu.typists.exception.InvalidCommandException; import seedu.typists.game.TimeModeGame; import java.util.ArrayList; -import java.util.Arrays; import static seedu.typists.Main.content; -import static seedu.typists.Main.uiBot; import static seedu.typists.Main.LINE_LENGTH; public class TimeGameCommand implements Command { + private static final String SIGNIFIER = "-t"; @Override public void run(ArrayList args) { - TimeModeGame game = createGame(); - game.runGame(); - game.gameSummary(); + try { + int timeInSeconds = getTime(args, SIGNIFIER); + TimeModeGame game = createGame(timeInSeconds); + game.runGame(); + game.gameSummary(); + } catch (InvalidCommandException e) { + System.out.println( + "Please enter time in multiple of 30 seconds.\n" + + "e.g. time -t 30 " + ); + } catch (IncompleteCommandException | IndexOutOfBoundsException e) { + System.out.println( + "Please specify duration of the game using " + + SIGNIFIER + "\n" + + "e.g. time -t 60 " + ); + } catch (NumberFormatException e) { + System.out.println("Duration should be a number"); + } } - public TimeModeGame createGame() { - return new TimeModeGame(content.getContent(), LINE_LENGTH); + public int getTime (ArrayList args, String key) throws InvalidCommandException, IncompleteCommandException { + if (!args.contains(key)) { + throw new IncompleteCommandException(); + } + int index = args.indexOf("-t"); + int time = Integer.parseInt(args.get(index + 1)); + if (time % 30 != 0 || time == 0) { + throw new InvalidCommandException(); + } + return time; + } + + public TimeModeGame createGame(int timeInSeconds) { + return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH); } } diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 4d15285802..67e5dd9580 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -3,17 +3,36 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Utility methods. */ public class Utils { + protected static final Logger logger = Logger.getLogger("Foo"); /** convert the line of text into an arraylist of word. */ public static ArrayList splitStringIntoWordList(String line) { return new ArrayList<>(Arrays.asList(line.split(" "))); } + + /** get one line that is supposed to be displayed at one time of game. **/ + public static String[] getDisplayLines(ArrayList wordLists, int wordsPerLine, int row) { + int startIndex = (row - 1) * wordsPerLine; + assert startIndex >= 0 : "word index should be non-negative"; + String[] line = new String[wordsPerLine]; + try { + for (int i = 0; i < wordsPerLine; i++) { + line[i] = wordLists.get(startIndex + i); + } + } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "exceed content maximum."); + } + return line; + } + /** group the word list into groups of x, where x is the number of words per line. */ public static ArrayList getWordLines(String text, int lineLength) { ArrayList wordList = splitStringIntoWordList(text); diff --git a/src/main/java/seedu/typists/exception/IncompleteCommandException.java b/src/main/java/seedu/typists/exception/IncompleteCommandException.java new file mode 100644 index 0000000000..becb0ed3af --- /dev/null +++ b/src/main/java/seedu/typists/exception/IncompleteCommandException.java @@ -0,0 +1,5 @@ +package seedu.typists.exception; + +public class IncompleteCommandException extends Exception { + //thrown when the command enter is missing key pointns +} diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 732e49fe3a..01c69f1ea2 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -10,8 +10,9 @@ public abstract class Game { protected final GameUi ui; - public ArrayList displayedLines; - public ArrayList userLines; + public ArrayList displayedLines = new ArrayList<>(); + public ArrayList userLines = new ArrayList<>(); + public double gameTime; public Game() { this.ui = new GameUi(); diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 4beb9dcfaf..ca50cb59e3 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -4,42 +4,26 @@ import java.util.HashMap; import java.util.List; import java.util.Scanner; -import java.util.logging.Level; -import java.util.logging.Logger; import static seedu.typists.common.Messages.MESSAGE_TIME_GAME_END; import static seedu.typists.common.Utils.getWordLineFromStringArray; import static seedu.typists.common.Utils.splitStringIntoWordList; +import static seedu.typists.common.Utils.getDisplayLines; public class TimeModeGame extends Game { - protected static final Logger logger = Logger.getLogger("Foo"); - protected int gameTime; + protected final int timeInSeconds; protected final ArrayList wordLists; protected int wordsPerLine; + protected double gameTime; - public double realGameTime; - - public TimeModeGame(String targetWordSet, int wordsPerLine) { + public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine) { super(); assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); - this.userLines = new ArrayList<>(); - this.displayedLines = new ArrayList<>(); - this.gameTime = getGameTime(); + this.timeInSeconds = timeInSeconds; this.wordsPerLine = wordsPerLine; } - public int getGameTime() { - Scanner in = new Scanner(System.in); - ui.printScreen("Enter how long (in seconds) you want the game to run: "); - try { - return Integer.parseInt(in.nextLine()); - } catch (NumberFormatException e) { - System.out.println("Not a Number!"); - return getGameTime(); - } - } - public void runGame() { Scanner in = new Scanner(System.in); @@ -52,11 +36,11 @@ public void runGame() { while (!timeOver) { long currTime = getTimeNow() - beginTime; - if (currTime >= gameTime * 1000L) { - realGameTime = (double) currTime / 1000; + if (currTime >= timeInSeconds * 1000L) { + gameTime = (double) currTime / 1000; timeOver = true; } else { - String[] display = getDisplayLines(currentRow); + String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); ui.printLine(display); displayedLines.add(display); inputs.add(in.nextLine()); @@ -71,29 +55,15 @@ public void runGame() { public void endGame() { ui.printEnd(MESSAGE_TIME_GAME_END); - double overshoot = realGameTime - gameTime; + double overshoot = gameTime - timeInSeconds; assert overshoot >= 0; if (overshoot > 0) { ui.printOvershoot(overshoot); } } - public String[] getDisplayLines(int row) { - int startIndex = (row - 1) * wordsPerLine; - assert startIndex >= 0 : "word index should be non-negative"; - String[] line = new String[wordsPerLine]; - try { - for (int i = 0; i < wordsPerLine; i++) { - line[i] = wordLists.get(startIndex + i); - } - } catch (IndexOutOfBoundsException e) { - logger.log(Level.WARNING, "exceed content maximum."); - } - return line; - } - public void gameSummary() { - HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); + HashMap summary = handleSummary(displayedLines, userLines, gameTime, "Time-limited"); handleStorage(summary); } diff --git a/src/main/java/seedu/typists/ui/GameUi.java b/src/main/java/seedu/typists/ui/GameUi.java index 1039f13a9c..3a6a3ed3ec 100644 --- a/src/main/java/seedu/typists/ui/GameUi.java +++ b/src/main/java/seedu/typists/ui/GameUi.java @@ -26,4 +26,9 @@ public void printOvershoot(double overshoot) { + " seconds." ); } + + public void printGameMode1Progress(int a, int b) throws InterruptedException { + viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); + } + } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 0239e3d5c2..e7c494acec 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -79,30 +79,10 @@ public String readCommand() { return sc.nextLine(); } - public void line() { - printScreen(DIVIDER); - } - - /** - * Print error message. - * - * @param meg obtained from DukeException message - */ - public void showText(String meg) { - System.out.println(meg); - } - - public void showNumber(int i) { - System.out.println(String.valueOf(i)); - } - public void showBye() { - printScreen("Bye. Hope to see you again soon!"); + printScreen("Thanks for using Typist! See you next time!"); } - public void printGameMode1Progress(int a, int b) throws InterruptedException { - viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); - } public void printKeyboard() { out.println(KEYBOARD); diff --git a/time-limited_records.txt b/time-limited_records.txt index e27388598a..2dc12de3ad 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,4 +1,5 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] diff --git a/word-limited_records.txt b/word-limited_records.txt index fe445196fd..05740c23b8 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1 +1,2 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] +Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] From a8fe4536d06d0ee222b8b8bdfa031e0c0a540608 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 23:15:14 +0800 Subject: [PATCH 149/272] update to pass test --- seedu.typists.ui.TextUi.log.1 | 2 ++ src/main/java/seedu/typists/command/TimeGameCommand.java | 2 +- text-ui-test/EXPECTED.TXT | 2 +- text-ui-test/time-limited_records.txt | 0 text-ui-test/word-limited_records.txt | 0 5 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 seedu.typists.ui.TextUi.log.1 create mode 100644 text-ui-test/time-limited_records.txt create mode 100644 text-ui-test/word-limited_records.txt diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 new file mode 100644 index 0000000000..1a29966417 --- /dev/null +++ b/seedu.typists.ui.TextUi.log.1 @@ -0,0 +1,2 @@ +Oct 27, 2021 11:13:26 PM seedu.typists.ui.SummaryUi setUpLog +INFO: Set up log in SummaryUi diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 834260730f..faf63188be 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -36,7 +36,7 @@ public void run(ArrayList args) { } } - public int getTime (ArrayList args, String key) throws InvalidCommandException, IncompleteCommandException { + public int getTime(ArrayList args, String key) throws InvalidCommandException, IncompleteCommandException { if (!args.contains(key)) { throw new IncompleteCommandException(); } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index bca340e8cf..394235cd68 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -17,4 +17,4 @@ | bye: exit typist | =========================================================== Updating game records... - | Bye. Hope to see you again soon! + | Thanks for using Typist! See you next time! diff --git a/text-ui-test/time-limited_records.txt b/text-ui-test/time-limited_records.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/text-ui-test/word-limited_records.txt b/text-ui-test/word-limited_records.txt new file mode 100644 index 0000000000..e69de29bb2 From fee453aafd0b6e126c8c6eb6b795fde484fa997b Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 23:30:45 +0800 Subject: [PATCH 150/272] add start now feature --- .../seedu/typists/command/TimeGameCommand.java | 18 ++++++++++++------ .../java/seedu/typists/common/Messages.java | 2 +- .../java/seedu/typists/game/TimeModeGame.java | 12 ++++++++++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index faf63188be..e5d91bfad3 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -11,13 +11,15 @@ public class TimeGameCommand implements Command { - private static final String SIGNIFIER = "-t"; + private static final String TIME_SIGNIFIER = "-t"; + private static final String START_SIGNIFIER = "-sn"; @Override public void run(ArrayList args) { + boolean is_StartNow = getStartNow(args, START_SIGNIFIER); try { - int timeInSeconds = getTime(args, SIGNIFIER); - TimeModeGame game = createGame(timeInSeconds); + int timeInSeconds = getTime(args, TIME_SIGNIFIER); + TimeModeGame game = createGame(timeInSeconds, is_StartNow); game.runGame(); game.gameSummary(); } catch (InvalidCommandException e) { @@ -28,7 +30,7 @@ public void run(ArrayList args) { } catch (IncompleteCommandException | IndexOutOfBoundsException e) { System.out.println( "Please specify duration of the game using " - + SIGNIFIER + "\n" + + TIME_SIGNIFIER + "\n" + "e.g. time -t 60 " ); } catch (NumberFormatException e) { @@ -36,6 +38,10 @@ public void run(ArrayList args) { } } + public boolean getStartNow(ArrayList args, String key) { + return args.contains(key); + } + public int getTime(ArrayList args, String key) throws InvalidCommandException, IncompleteCommandException { if (!args.contains(key)) { throw new IncompleteCommandException(); @@ -48,7 +54,7 @@ public int getTime(ArrayList args, String key) throws InvalidCommandExce return time; } - public TimeModeGame createGame(int timeInSeconds) { - return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH); + public TimeModeGame createGame(int timeInSeconds, boolean is_ready) { + return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, is_ready); } } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 9603412afe..38aee22137 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -71,7 +71,7 @@ public class Messages { public static final String MESSAGE_HELP = "Manual:\n" + "content: set the content\n" + "word: start a new word game\n" - + "time: start a new timer game\n" + + "time: start a new timer game <-t> to specify time <-sn> to start immediately\n" + "history: view past game records\n" + "clear: clear all game records\n" + "bye: exit typist"; diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index ca50cb59e3..6c58e81b38 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -15,21 +15,29 @@ public class TimeModeGame extends Game { protected final ArrayList wordLists; protected int wordsPerLine; protected double gameTime; + protected final boolean is_ready; - public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine) { + public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean is_ready) { super(); assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); this.timeInSeconds = timeInSeconds; this.wordsPerLine = wordsPerLine; + this.is_ready = is_ready; } + public boolean getReady(boolean is_ready) { + if (!is_ready) { + return ui.readyToStartTimer(); + } + return true; + } public void runGame() { Scanner in = new Scanner(System.in); List inputs = new ArrayList<>(); - if (ui.readyToStartTimer()) { + if (getReady(is_ready)) { int currentRow = 1; long beginTime = getTimeNow(); boolean timeOver = false; From eb7a129d419f452c92d4b9652f31a9b26d93fff0 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 23:35:34 +0800 Subject: [PATCH 151/272] checkstyle update --- .../java/seedu/typists/command/TimeGameCommand.java | 4 ++-- src/main/java/seedu/typists/game/TimeModeGame.java | 12 ++++++------ text-ui-test/EXPECTED.TXT | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index e5d91bfad3..d1060ec854 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -16,10 +16,10 @@ public class TimeGameCommand implements Command { @Override public void run(ArrayList args) { - boolean is_StartNow = getStartNow(args, START_SIGNIFIER); + boolean startNow = getStartNow(args, START_SIGNIFIER); try { int timeInSeconds = getTime(args, TIME_SIGNIFIER); - TimeModeGame game = createGame(timeInSeconds, is_StartNow); + TimeModeGame game = createGame(timeInSeconds, startNow); game.runGame(); game.gameSummary(); } catch (InvalidCommandException e) { diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 6c58e81b38..5e6eaf4d56 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -15,19 +15,19 @@ public class TimeModeGame extends Game { protected final ArrayList wordLists; protected int wordsPerLine; protected double gameTime; - protected final boolean is_ready; + protected final boolean isReady; - public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean is_ready) { + public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean isReady) { super(); assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); this.timeInSeconds = timeInSeconds; this.wordsPerLine = wordsPerLine; - this.is_ready = is_ready; + this.isReady = isReady; } - public boolean getReady(boolean is_ready) { - if (!is_ready) { + public boolean getReady(boolean isReady) { + if (!isReady) { return ui.readyToStartTimer(); } return true; @@ -37,7 +37,7 @@ public void runGame() { Scanner in = new Scanner(System.in); List inputs = new ArrayList<>(); - if (getReady(is_ready)) { + if (getReady(isReady)) { int currentRow = 1; long beginTime = getTimeNow(); boolean timeOver = false; diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 394235cd68..db4cf0105f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -11,7 +11,7 @@ | Manual: | content: set the content | word: start a new word game - | time: start a new timer game + | time: start a new timer game <-t> to specify time <-sn> to start immediately | history: view past game records | clear: clear all game records | bye: exit typist From 79fb64c44f0b5af47f339e6772d9af69101b6cbe Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Wed, 27 Oct 2021 23:38:18 +0800 Subject: [PATCH 152/272] Update TimeGameCommand.java --- src/main/java/seedu/typists/command/TimeGameCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index d1060ec854..93de4905ed 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -54,7 +54,7 @@ public int getTime(ArrayList args, String key) throws InvalidCommandExce return time; } - public TimeModeGame createGame(int timeInSeconds, boolean is_ready) { - return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, is_ready); + public TimeModeGame createGame(int timeInSeconds, boolean isReady) { + return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); } } From 3d4603115d34f13e74744f976587d2a0f1e18434 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 27 Oct 2021 23:51:56 +0800 Subject: [PATCH 153/272] Complete developer guide for View Statistics feature. #Fixes 68 --- docs/DeveloperGuide.md | 30 +++++++++++++++++----------- docs/uml/ViewStatistics-1.drawio | 1 + docs/uml/ViewStatistics-2.drawio | 1 + docs/uml/ViewStatistics-2.drawio.svg | 2 +- docs/uml/ViewStatistics-3.drawio | 1 + docs/uml/ViewStatistics-3.drawio.svg | 2 +- docs/uml/ViewStatistics-4.drawio | 1 + docs/uml/ViewStatistics-4.drawio.svg | 2 +- docs/uml/ViewStatistics-5.drawio | 1 + docs/uml/ViewStatistics-5.drawio.svg | 4 ++++ 10 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 docs/uml/ViewStatistics-1.drawio create mode 100644 docs/uml/ViewStatistics-2.drawio create mode 100644 docs/uml/ViewStatistics-3.drawio create mode 100644 docs/uml/ViewStatistics-4.drawio create mode 100644 docs/uml/ViewStatistics-5.drawio create mode 100644 docs/uml/ViewStatistics-5.drawio.svg diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 59c3847ff0..cc14afde44 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -31,9 +31,15 @@ Gonna to change this .puml diagram later - zhansen ### \[Proposed\] View Statistics feature #### \[Proposed Implementation\] -The top-level logic of view statistics feature resides in ViewStatistics. It implements the Command -interface. The key methods in the ViewStatistics class is -* `retrieveStatistics()` - Decides which of the 3 methods below to run +The top-level logic of view statistics feature resides in ViewCommand. It implements the Command +interface. The key method of the class is `executeCommand()`. +`executeCommand()` logic: +1. Calls the retrieveStatistics() method of StatisticsManager to get the statistics. +2. Calls the displayStatistics() method of ViewCommandUi to display the statistics retrieved. + +StatisticsManager performs the logic for processing the game records to obtain the statistics. +Its key methods are: +* `retrieveStatistics()` - Decides which of the three methods below to run * `calculateBestStatistics()` - Returns the best statistics over the past n games * `calculateWorstStatistics()` - Returns the worst statistics over the past n games * `calculateAverageStatistics()` - Returns the average statistics over the past n games @@ -42,27 +48,27 @@ Given below is an example usage scenario and how the program implements the feat Step 1: The user launches the application (scenario assumes that there are several game records already stored in multiple files). -Step 2: The user executes `view -m best -g game error -n 9` to view his/her best statistics for the error game mode over the past 9 games. +Step 2: The user executes `view -m best -g time -n 9` to view his/her best statistics for the error game mode over the past 9 games. Step 3: A ViewCommand object is then instantiated. ![Alt text](uml/ViewStatistics-1.drawio.svg) -Step 4. ViewCommand calls the retrieveStatistics() method of RetrieveStatisticsManager. +Step 4. ViewCommand calls the retrieveStatistics() method of StatisticsManager. ![Alt text](uml/ViewStatistics-2.drawio.svg) - -Step 5: RetrieveStatisticsManager creates a GameRecordsManager object. +Step 5: StatisticsManager creates a GameRecordsManager object. * The constructor of GameRecordsManager calls the readGameRecords() method of the Storage class to retrieve the gamer's past game records from the text files. ![Alt text](uml/ViewStatistics-3.drawio.svg) -Step 6. RetrieveStatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). +Step 6. StatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). +* Calculated statistics is returned. -Step 7. RetrieveStatisticsManager calls displayStatistics of the ViewCommandUI class to display the statistics. +Step 7. ViewCommand calls the displayStatistics() method of the ViewCommandUi class to display the statistics. ![Alt test](uml/ViewStatistics-4.drawio.svg) -The following sequence diagram shows how the above scenario is executed +The following sequence diagram shows how the above scenario is executed. ![Alt test](uml/ViewStatistics-5.drawio.svg) @@ -71,8 +77,8 @@ The following sequence diagram shows how the above scenario is executed * One implementation considered is to do away with the retrieveStatistics() method and immediately call one of calculateBestStatistics, calculateWorstStatistics() or calculateAverageStatistics() based on the gamer's imput using a switch statement. This implementation choice was not used because it violates the Single Responsibility Principle and does not do SLAP well. -* Another implementation considered was for HistoryManager to do the main logic. This implementation was not done as it violates the -Single Responsibility Principle +* Another implementation considered was for GameRecordsManager to do the main logic. This implementation was not done as it violates the +Single Responsibility Principle. ## Product scope diff --git a/docs/uml/ViewStatistics-1.drawio b/docs/uml/ViewStatistics-1.drawio new file mode 100644 index 0000000000..3fd76a1942 --- /dev/null +++ b/docs/uml/ViewStatistics-1.drawio @@ -0,0 +1 @@ +jZTNjpswEICfhmNWYCckOSYk7F4qtYq0PVYuTMCKYagxCdun7xgbEnYVqRcw3/wPMw54UvWvWjTlN8xBBSzM+4AfAsYituT0suTDkXW8dqDQMncovIOT/AvecqSdzKH1zCGDqIxs5jDDuobMzJjQGm9ztTOqfAYaUcAsDQtOmVDwRe2nzE3p6Iat7/wNZFGOkaN46yS/RXYpNHa1jxcwni7T6HB04kqMvnzcthQ53h4QPwY80YjGnao+AWV7O29b+kQ65a2hNv9jkJ77zaH/9R2bbvGja2N8b7cL7+UqVAdjGbEif/szklvqp8icIP7T2Uz3b6CuYGQm7ohOhX8Ppm0jaluw+VBzW+tz0Q4jsCOFKGz65166CfDdu4RbglUlqNleTIV2n02IudhfsKtmxGyWHStNpegU2dQvYDL730L6KEVWdhpeRUNgSaBBWRvQxyu1vPVK1nMqKqns/O90VkpDY9pShIPoaGxAe6UTdnroZWkMzTZb2R6s6HfZh1VoXwrEQoFoZPuSYTUIsnZQTc8uBB1nQVZs/zmM2zA25CaVSlChHurkKUuSTWqrNBov8CA5huvdKvUeHjjf8mQVTz27gjbQP52/aJpqui0AKzCaMg5Hg9gvgr8ophvgdl+7iHtWPqzcaCf8pheT6/u008EP/Ph5X6xB9nB78eM/ \ No newline at end of file diff --git a/docs/uml/ViewStatistics-2.drawio b/docs/uml/ViewStatistics-2.drawio new file mode 100644 index 0000000000..2e4fb472d9 --- /dev/null +++ b/docs/uml/ViewStatistics-2.drawio @@ -0,0 +1 @@ +7VdLc5swEP41PjoDyGD7aDsmmUkykxl3+jgqsAbFAlEh/Oiv7wqJl1u7TQ+ZHHoJ7LcvaffbNRmRVXa8k7RIn0QMfOQ58XFEbkeeN/WmDj40cjIImZKpQRLJYoM5HbBhP8CAboNWLIbSYgZSQnDFiiEYiTyHSA0wKqU4DM22gscDoKAJDI6hgU1EOfxi9oXFKjXozJt2+D2wJG0yu8HcaF5otEukqHKbb+SRcBK6t2ujzmgTy+YtUxqLQw8i6xFZSSGUecuOK+C6uMOyhRe07bkl5OpvHMLHh514We/gYbNm+WtVyHg8tlH2lFfQXCPgGG+5FRgW60kjowi+V/qky3vge1Asoh2kL6dOfGin/cdl3e4FGrhOcex7BIl+ViW23ibEk5ucRmWL1sb1IMa+WTEXOT6WdfVB389BqdyBilIrpDRKKwl3tEBggoCQKhWJyCl/FEKDLoKvoNTJcpJWSmhHlXGrhSNTX3vv33TsG99Kt0ebqhZOVtBXCGnGuAYWMkqZQtbiJR1MgCwCaY02opJ1aVOlkOqer8vkY/f0H21Q3iRCJBxowcqbSGS1Iipr03BrUuDrIInvLc/TmMu5gT5oHi/0xKAsCsg/pSzXZVNUtmYTY9YXy/qgzyBZBhh3U9CI5QlqZ6hE3wTUBSUSU56+NlXSQq+CWuxKWEunVopDxnnTViXFDlaCC1kTgayd6cIP7f16OJmTla/vyekL8GU7nj0TO6BkGdMyrYnjtlTT/Lo4Ws1mqq97ZZ68drBxY4LAokjskmPX5di5cf35xMSSwKli+2FOardZ0vq24Z4FqyeyiRU4xDdOdvWOvbnvDcPY3hnPbjcgC+ipZ1Zog/JqLse5kMuGxBcT9SxCk0JstyWoM49ejTqoXltvWGHeu60w73crrElWtQBZbBR2tmQqKp9ojj8gsrfjqnPHP+293kK6vuHqLoJc70E380OvI68+G854fza91WoW/tPAWwaAVHC8PsKXR9OfB8E5xWeWW4fuw8ANiMHS3kdB4Fye3gHd38pt8vG4/ZnBYSWyjOJ3z39Wf3RWB+58+o6sRrH7oDULvvu3gax/Ag== \ No newline at end of file diff --git a/docs/uml/ViewStatistics-2.drawio.svg b/docs/uml/ViewStatistics-2.drawio.svg index 61ec7b7890..9c82d85d60 100644 --- a/docs/uml/ViewStatistics-2.drawio.svg +++ b/docs/uml/ViewStatistics-2.drawio.svg @@ -1,4 +1,4 @@ -
uses
uses
:RetrieveStatisitcsManager
:RetrieveStatisi...
:ViewCommand
:ViewCommand
Viewer does not support full SVG 1.1
\ No newline at end of file +
uses
uses
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio b/docs/uml/ViewStatistics-3.drawio new file mode 100644 index 0000000000..7da7f2e5cd --- /dev/null +++ b/docs/uml/ViewStatistics-3.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio.svg b/docs/uml/ViewStatistics-3.drawio.svg index ea89d480dc..d95c2d03c1 100644 --- a/docs/uml/ViewStatistics-3.drawio.svg +++ b/docs/uml/ViewStatistics-3.drawio.svg @@ -1,4 +1,4 @@ -
:RetrieveStatisitcsManager
:RetrieveStatisi...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file +
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-4.drawio b/docs/uml/ViewStatistics-4.drawio new file mode 100644 index 0000000000..dbb2a72940 --- /dev/null +++ b/docs/uml/ViewStatistics-4.drawio @@ -0,0 +1 @@ +7Vxbc5s4FP41ntl9iAdJXOzHxInbnWlnuk13u31UQLFpAXmFHDv761cCCRDgW3wjM2QysXUkJJC+c86nc1AGaBKvPzC8mH+mAYkG0ArWA3Q/gBDY0BYfUvKaS1wEc8GMhUEuskrBY/gfUVdq6TIMSKpkuYhTGvFwYQp9miTE54YMM0ZXZrNnGgWGYIFnxLgNKXj0cUQazb6HAZ/n0hH0SvlHEs7memTgjvOaJ+z/mjG6TNR4A4im9hTcP+TVMdZ9qXHTOQ7oqiJCDwM0YZTy/Fu8npBIzq05bdMNtcV9M5LwfS74Fn3/ClZ/Pi4tgJ/iL9+X6z/CG9VLyl/1fJBATI8qJjQRH3fZQxLZjSVK6S/C/bkqzLE/XzLyAS+EwBYCyviczmiCo0+USiEQwp+E81e19HjJqbyQx5GqJeuQ/1P5/kP2PXRU6X6thsoKr6rwTBM+xXEYScEt8+chF+BIxaOIAcRiEaYaPdIl8+W4c84FoqCDbsUfMUnyj2yQDmeUziKCF2E69GmcVfhp1nT6nA8hvhqDOPCuPkz+cMCVN5oEtxKYokwXJPk2DxM5bRyzopmdN6sWRfWM8C+EhTER/T4usB8mM1E7ytpy9vqPnghZqEySLJazlJVei1IwDaNIrxxn9BeZ0IiybK3Rg+XdOlP1CBU5GqOJIx8lwOk8W3ign0A/mYJGJqsMEeEnEt0VmlHpU+kGussRJ2G2EcgalXrtNqG3MBjZ3G1piAp9E3aMUDHDTKyqxUiEefhi3ghWBmVWtCsu/UJDcYvQ0sbPU6qtTB9yLLOL/AHUVaVqii+V2yhFmcIeoLxwH+X1l+ylWMJSk0FXNPmt0DagaZiDjyR6ITz0cU03rS1A3wfb7XpdV7EjtHyLfooRqroEJ5PR9OLqBsZ7qpt7pLoZinKoVqC83xccLYn2zG7E1eJLioDVU7r/LqXzvSsBU4gMtdJCef1Nmq2mcCIWgIt19Qp3pj6zwZaFAN0+cvHcacj99DNOBKFgupF4wGX9wkHul0pxTccr+rZdgRfS7hD28CIWOu2234TWFpAf7rYUAgjjZL0d9U2QqgsgGpu2XdO4VUkSgauwNq8QRNc6GNf06adkttDK1LkjmP07JKsJjWMs+O2haN2qn3Zl3pU+9+i+MLoLU34BdIuiAvgBRtxpMeId4zoFbxnCMTS5iwV2E3NRKmjAmykN7AClUSS3ndKcmO+0EUz9vZ1eXpYhuXsSJOBtVU9rCKCOqygNVaW37lh0E/r8nJKzbEbc7tGuDzgmX4lPWdDzrvfimewRuphn2g/Y3m5X1EPjEtBAyAy32C68MjRGnbZ5vbHrPKJtYCLac66M6PE+NPtC+QBr6OnQ4Y8qtXvPCYEqDz8Lpz424t8eji02PBu2M8Zeo570uFp6YNSufEdG/W0btSvtjqh/s6M61RnVtFot9LnSBzoDW3FfK+E3PoWxgHVgOJIWm/Apj1VVFRdH4Uys+r1PklwRpHEUvi66VRVxGARRZkGI8G34KevP0l4ke2rnbuDc13Sood/17XAbkDdATSngRuOt0szq3gaVrHGJv82Wc9uObuSZxh4et6PTkRzXNUFU6+F8Gz4AGvBp9x49Ug5Byo2ACkIjY1HBaaBSD/pdDiqw30N1g3HarmNgwHHcKzNOgDpFOWFPOa9HOcuk//slnWDfGPCxSfJ2I++MakESD76NnbpWtv+6KkG1W9yGEV/ZHTix2gInXMC4jebuFxu5MKeBdVPTRU4DNrxhVZIayz42h6GDJp4BSre2+zoji2lLSp4CjrLjHnrngx5AI5NP35yIUJtbL/1i8AWQ2O1kWx947vw2wDMVwtHYvd42oC3NdvXX9iiTpwd6OHcczq5be1ni6plB0EwN/pWSPpJ60LJ6wB5aFkKWa3lj2xqb7ta2PFFru5YNvJEArw7LH+C/odmjdzH/PW6gY8II5i0AEbPKz4cNGQlJFTYayqsWuKrprdGY7fgozB54k9l7y8v8p3CQoJabsZsWxXaaBkUzs5MbFNhM1rQak/70x/lPf6gWJ3xNsusnP5Qy7H6vcUNu49iUqwWG4+qPqZt7HrvanYCtd3Tm+BZsZtA0r0wXOGkls36+0JLIstnTb+KGxa8Y3qp8+32QUTTJmSX1Vfwuu0Z0hONFVomQhOW8QqLNGrOTegzDqMvvUlYmlMU4MqtXyj7Keju/z6wyEtaEsJtUa0LL9dL73SiHJ6uVzzOqQ2HTEtV99daySs5wkj6LTnX3QnN1A5nsNkevXh6E6SLCatrCJAorVz5HFPNqj/XdRM71ii1CvpobtgjKw68k8ZZWQYpXTBriqnE9msWdwCkCdyzU0AVjy/bk31p0GLmi1iuqm/6yhYDDs/nLPVKO/VHnjqWZ+mPOm09M7eF9N6nvlY45NzpqnKk7mb/t+gm6v8LTnqGD1Zh3f4juWofoQC0i4XgNp3fVU3ToHWway+S/Z2T/Syt/qh1gf1juoofldrur7Ym7Sx6Ca75G4Q6tyg/c8abuvh4QQDB06nFMFw5rmcMz7zvR5n3nQc7S9GIbt6x75cC37pj2y7W8g1DpkcHQrnnjc571MhVu3HxNEbU4Vv2/xw5zrOX/4Mo1rPxHZ+jhfw== \ No newline at end of file diff --git a/docs/uml/ViewStatistics-4.drawio.svg b/docs/uml/ViewStatistics-4.drawio.svg index 527931084b..823fb246cc 100644 --- a/docs/uml/ViewStatistics-4.drawio.svg +++ b/docs/uml/ViewStatistics-4.drawio.svg @@ -1,4 +1,4 @@ -
:RetrieveStatisitcsManager
:RetrieveStatisi...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file +
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-5.drawio b/docs/uml/ViewStatistics-5.drawio new file mode 100644 index 0000000000..c11d8a4f5e --- /dev/null +++ b/docs/uml/ViewStatistics-5.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-5.drawio.svg b/docs/uml/ViewStatistics-5.drawio.svg new file mode 100644 index 0000000000..89631fe5cd --- /dev/null +++ b/docs/uml/ViewStatistics-5.drawio.svg @@ -0,0 +1,4 @@ + + + +:ViewCommand:StatisticsManagerretrieveStatistics(best, "Time-limited", 9)
calculateBestStatistics()
calculateBestStatistics()
bestStatistics
bestStatistics
bestStatisticsnew StatisticsManager():GameRecordsManager()gameRecordsnew GameRecordsManager():Storagenew Storage()timeLimitedGameRecords = readGameRecords("Time-limited")wordLimitedGameRecords = readGameRecords("Word-limited")new getGameRecords("Time-limited", 9):ViewCommandUinew ViewCommandUi()displayStatistics(statistics)executeCommand(best, "Time-limited", 9)
Viewer does not support full SVG 1.1
\ No newline at end of file From 56535cf39019a992222d859c069c1455b9a8baec Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 00:12:47 +0800 Subject: [PATCH 154/272] fix content supply bug for timemodegame --- seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.1 | 2 +- src/main/java/seedu/typists/common/Utils.java | 11 ++++++++--- .../typists/exception/ExceedRangeException.java | 4 ++++ .../java/seedu/typists/game/TimeModeGame.java | 17 ++++++++++++----- time-limited_records.txt | 7 +++++-- 6 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 src/main/java/seedu/typists/exception/ExceedRangeException.java diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 4775273733..310df305d4 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 27, 2021 11:09:05 PM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 12:09:36 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index 1a29966417..d86cda2bb7 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Oct 27, 2021 11:13:26 PM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 12:12:02 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 67e5dd9580..6fa5cec8f9 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -1,5 +1,8 @@ package seedu.typists.common; +import seedu.typists.exception.ExceedRangeException; +import seedu.typists.exception.FaultyInputException; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -10,7 +13,6 @@ * Utility methods. */ public class Utils { - protected static final Logger logger = Logger.getLogger("Foo"); /** convert the line of text into an arraylist of word. */ public static ArrayList splitStringIntoWordList(String line) { @@ -19,17 +21,20 @@ public static ArrayList splitStringIntoWordList(String line) { /** get one line that is supposed to be displayed at one time of game. **/ - public static String[] getDisplayLines(ArrayList wordLists, int wordsPerLine, int row) { + public static String[] getDisplayLines(ArrayList wordLists, int wordsPerLine, int row) + throws ExceedRangeException { int startIndex = (row - 1) * wordsPerLine; assert startIndex >= 0 : "word index should be non-negative"; String[] line = new String[wordsPerLine]; + try { for (int i = 0; i < wordsPerLine; i++) { line[i] = wordLists.get(startIndex + i); } } catch (IndexOutOfBoundsException e) { - logger.log(Level.WARNING, "exceed content maximum."); + throw new ExceedRangeException(); } + return line; } diff --git a/src/main/java/seedu/typists/exception/ExceedRangeException.java b/src/main/java/seedu/typists/exception/ExceedRangeException.java new file mode 100644 index 0000000000..73dfdcada5 --- /dev/null +++ b/src/main/java/seedu/typists/exception/ExceedRangeException.java @@ -0,0 +1,4 @@ +package seedu.typists.exception; + +public class ExceedRangeException extends Throwable { +} diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 5e6eaf4d56..1f767392ab 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,5 +1,7 @@ package seedu.typists.game; +import seedu.typists.exception.ExceedRangeException; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -11,6 +13,7 @@ import static seedu.typists.common.Utils.getDisplayLines; public class TimeModeGame extends Game { + protected String targetWordSet; protected final int timeInSeconds; protected final ArrayList wordLists; protected int wordsPerLine; @@ -19,6 +22,7 @@ public class TimeModeGame extends Game { public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean isReady) { super(); + this.targetWordSet = targetWordSet; assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); this.timeInSeconds = timeInSeconds; @@ -48,10 +52,14 @@ public void runGame() { gameTime = (double) currTime / 1000; timeOver = true; } else { - String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); - ui.printLine(display); - displayedLines.add(display); - inputs.add(in.nextLine()); + try { + String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); + ui.printLine(display); + displayedLines.add(display); + inputs.add(in.nextLine()); + } catch (ExceedRangeException e) { + currentRow = 0; + } currentRow++; } } @@ -75,7 +83,6 @@ public void gameSummary() { handleStorage(summary); } - public void updateUserLines(List stringArray) { userLines = getWordLineFromStringArray(stringArray); } diff --git a/time-limited_records.txt b/time-limited_records.txt index 2dc12de3ad..d84ee8413c 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,5 +1,8 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] +Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] +Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] From cfc6d1d4499155e85cbfe8253115caa7c99c9676 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 00:50:53 +0800 Subject: [PATCH 155/272] minor --- seedu.typists.ui.TextUi.log | 2 +- time-limited_records.txt | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 310df305d4..99d7b8114e 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 28, 2021 12:09:36 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 12:45:41 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/time-limited_records.txt b/time-limited_records.txt index d84ee8413c..85ab3c28ef 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,8 +1,10 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] -Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] -Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] -Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] +Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] +Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] +Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] +Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] From 2d304dfc25e65f28186d69e6c9c1cefd93a10db5 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 00:52:20 +0800 Subject: [PATCH 156/272] minor --- seedu.typists.ui.TextUi.log | 2 +- time-limited_records.txt | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 4775273733..99d7b8114e 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 27, 2021 11:09:05 PM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 12:45:41 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/time-limited_records.txt b/time-limited_records.txt index 2dc12de3ad..85ab3c28ef 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,5 +1,10 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] +Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] +Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] +Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] +Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] From 5d6435d76ad86acc92ad1c7a7d57c8bb1b8775f7 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 00:52:44 +0800 Subject: [PATCH 157/272] set content with game feature --- .gitignore | 1 + .../seedu/typists/command/TimeGameCommand.java | 14 ++++++++++---- .../seedu/typists/command/WordGameCommand.java | 5 +++++ src/main/java/seedu/typists/common/Messages.java | 4 ++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index f69985ef1f..70c22a34e7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT +time-limited_records.txt diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 93de4905ed..e9b8827665 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -13,13 +13,15 @@ public class TimeGameCommand implements Command { private static final String TIME_SIGNIFIER = "-t"; private static final String START_SIGNIFIER = "-sn"; + private static final String CONTENT_SIGNIFIER = "-c"; @Override public void run(ArrayList args) { - boolean startNow = getStartNow(args, START_SIGNIFIER); + boolean startNow = getBoolean(args, START_SIGNIFIER); + boolean setContent = getBoolean(args, CONTENT_SIGNIFIER); try { int timeInSeconds = getTime(args, TIME_SIGNIFIER); - TimeModeGame game = createGame(timeInSeconds, startNow); + TimeModeGame game = createGame(timeInSeconds, startNow, setContent); game.runGame(); game.gameSummary(); } catch (InvalidCommandException e) { @@ -38,7 +40,8 @@ public void run(ArrayList args) { } } - public boolean getStartNow(ArrayList args, String key) { + /** Determine whether the user command has the signifier. **/ + public boolean getBoolean(ArrayList args, String key) { return args.contains(key); } @@ -54,7 +57,10 @@ public int getTime(ArrayList args, String key) throws InvalidCommandExce return time; } - public TimeModeGame createGame(int timeInSeconds, boolean isReady) { + public TimeModeGame createGame(int timeInSeconds, boolean isReady, boolean setContent) { + if (setContent) { + content.setContent(); + } return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); } } diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java index 60f12eb90f..dfc9440a1a 100644 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -9,8 +9,13 @@ import static seedu.typists.Main.uiBot; public class WordGameCommand implements Command { + private static final String CONTENT_SIGNIFIER = "-c"; + @Override public void run(ArrayList args) { + if (args.contains(CONTENT_SIGNIFIER)) { + content.setContent(); + } startWordLimitGame(); } diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 38aee22137..ee92571995 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -69,7 +69,7 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" - + "content: set the content\n" + + "content: set the content (or <-c> with game command)\n" + "word: start a new word game\n" + "time: start a new timer game <-t> to specify time <-sn> to start immediately\n" + "history: view past game records\n" @@ -80,7 +80,7 @@ public class Messages { //This sample text is gotten from https://www.lipsum.com/ public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " - + "imply dummy text of the printing and typesetting industry ipum is simply dummy " + + "imply dummy text of the printing and typesetting industry ipsum is simply dummy " + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + "industry industry industry industry industry industry industry industry industry industry industry " From d13dafe1d47a70333d73ba5157505e60588a4e27 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 01:01:51 +0800 Subject: [PATCH 158/272] update test result add log file into gitignore --- .gitignore | 3 +++ seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.1 | 2 +- seedu.typists.ui.TextUi.log.lck | 0 text-ui-test/EXPECTED.TXT | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 seedu.typists.ui.TextUi.log.lck diff --git a/.gitignore b/.gitignore index 70c22a34e7..45f2d19a29 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT time-limited_records.txt +seedu.typists.ui.TextUi.log +seedu.typists.ui.TextUi.log.1 +seedu.typists.ui.TextUi.log.lck diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 99d7b8114e..36eceaffbf 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 28, 2021 12:45:41 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 1:00:57 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index d86cda2bb7..d9a7423513 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Oct 28, 2021 12:12:02 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 12:59:28 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index db4cf0105f..4f19dd6661 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -9,7 +9,7 @@ | Welcome to Typist -- the ultimate cli typing game. | Brought to you by -- AY2122S1-CS2113-T13-4. | Manual: - | content: set the content + | content: set the content (or <-c> with game command) | word: start a new word game | time: start a new timer game <-t> to specify time <-sn> to start immediately | history: view past game records From 4cca1eea7a521963ec0aeeb86175d7a9928443c5 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 28 Oct 2021 01:05:30 +0800 Subject: [PATCH 159/272] Update UG Updates:notes about command format, view past records feature, clear feature, saving the data feature, and warning about editing the data file. --- docs/UserGuide.md | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 207fb7e491..8a582ffb66 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -12,6 +12,23 @@ 1. Down the latest version of `Duke` from [here](http://link.to/duke). ## Features + +### Notes about the command format: + +* Words in UPPER_CASE are parameters to be supplied by the user. +e.g. in `history -g GAME_MODE`, `GAME_MODE` is a parameter which can be used as `history -g time`. +* Items in square brackets are optional. +e.g. `-g GAME_MODE [-n NUMBER_OF_RECORDS]` can be used as `-g time -n 9` or as `-g time` +* Parameters can be in any order. +e.g. if command specifies `history -g GAME_MODE [-n NUMBER_OF_RECORDS]`, `history [-n NUMBER_OF_RECORDS] -g GAME_MODE` +is also acceptable. +* If a parameter is expected only once in the command but you specified it multiple times, +only the first occurrence of the parameter will be taken +e.g. if you specify `history -g time -g time -n 10`, only `history -g time -n 10` will be taken. +* For commands which have a help parameter, if `-h` is among the parameters provided, +all other parameters will be ignored and the guide for that command will be displayed. +e.g. `history -g time -h -n 10` will be interpreted as `history -h`. + ### Usage ### Open Game @@ -26,6 +43,37 @@ Examples * command example 2 +### View past records: `history` +View past game records. +Format: `history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` +* NUMBER_OF_RECORDS defaults to all records if not provided +* Possible arguments for GAME_MODE are - `word` or `time` + +Examples +* `history -g time -n 10` +* `history -g word` + + +### Clear past records: `clear` +Clear all past game records +Format: `clear [-g GAME_MODE] [-h]` +* GAME_MODE defaults to `all` if not provided +* Possible arguments for GAME_MODE are - `word`, `time` or `all` + +Examples +* `clear -g time` +* `clear` + + +### Saving the data +Typists automatically stores the updated game records when gamer enters the `bye` command to exit Typists. + +### Editing the data file +Typists is a game application and only game records will be stored. +Gamers should not edit the data it will manipulate the integrity of the records. +In the event where the data is editted and the wrong format is inputted, the game will crash when it tries to read the file. +The only way to make it run smoothly again is to delete the text files, hence losing all the game data. + ### `Keyword` - Describe action From 871255676b6f932b9e7b795e9d76f35b336b5a6e Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 28 Oct 2021 01:05:46 +0800 Subject: [PATCH 160/272] Change format of warning --- docs/UserGuide.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8a582ffb66..0d3bf2d9a1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -66,9 +66,11 @@ Examples ### Saving the data -Typists automatically stores the updated game records when gamer enters the `bye` command to exit Typists. +Typists automatically stores the updated game records into text files when gamer enters the +`bye` command to exit Typists. -### Editing the data file + +### !Warning: Editing the data file Typists is a game application and only game records will be stored. Gamers should not edit the data it will manipulate the integrity of the records. In the event where the data is editted and the wrong format is inputted, the game will crash when it tries to read the file. From 631013ba1699ac637f282b1690fc47614400a225 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 02:46:05 +0800 Subject: [PATCH 161/272] update game parser Merge time game parser and word game parser into one --- docs/UserGuide.md | 16 +++-- seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.1 | 2 +- .../seedu/typists/command/CommandFactory.java | 6 +- ...{TimeGameCommand.java => GameCommand.java} | 61 ++++++++++++++----- .../typists/command/WordGameCommand.java | 26 -------- .../java/seedu/typists/common/Messages.java | 7 +-- text-ui-test/EXPECTED.TXT | 5 +- time-limited_records.txt | 15 ++--- 9 files changed, 75 insertions(+), 65 deletions(-) rename src/main/java/seedu/typists/command/{TimeGameCommand.java => GameCommand.java} (52%) delete mode 100644 src/main/java/seedu/typists/command/WordGameCommand.java diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 0d3bf2d9a1..b9a4441289 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,15 +1,21 @@ # User Guide +* [Introduction](#introduction) +* [Quick Start](#quick-start) +* [Features](#features) +* [FAQ](#faq) +* [Command Summary](#command-summary) -## Introduction +## Introduction -{Give a product intro} +Typist is a CLI typing game. ## Quick Start {Give steps to get started quickly} -1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +1. Ensure that you have Java 11 or above installed. +2. Down the latest version of `Typist` from [here](http://link.to/duke). +3. Navigate to the folder containing the jar file and run `java -jar tp.jar` ## Features @@ -43,6 +49,8 @@ Examples * command example 2 +### Open Game: `time` + ### View past records: `history` View past game records. Format: `history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 36eceaffbf..8c3f75ee82 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 28, 2021 1:00:57 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 2:45:18 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index d9a7423513..6087e49b35 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Oct 28, 2021 12:59:28 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 2:42:10 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 93eb23812f..f0643dc2d1 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -7,10 +7,8 @@ public class CommandFactory { public Command getCommand(String commandType) { switch (commandType) { - case "time": - return new TimeGameCommand(); - case "word": - return new WordGameCommand(); + case "game": + return new GameCommand(); case "content": return new ContentCommand(); case "error": diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java similarity index 52% rename from src/main/java/seedu/typists/command/TimeGameCommand.java rename to src/main/java/seedu/typists/command/GameCommand.java index e9b8827665..0473e6c34d 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -2,16 +2,19 @@ import seedu.typists.exception.IncompleteCommandException; import seedu.typists.exception.InvalidCommandException; +import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; +import seedu.typists.game.WordLimitGame; import java.util.ArrayList; import static seedu.typists.Main.content; +import static seedu.typists.Main.uiBot; import static seedu.typists.Main.LINE_LENGTH; - -public class TimeGameCommand implements Command { +public class GameCommand implements Command { private static final String TIME_SIGNIFIER = "-t"; + private static final String WORD_SIGNIFIER = "-w"; private static final String START_SIGNIFIER = "-sn"; private static final String CONTENT_SIGNIFIER = "-c"; @@ -19,25 +22,59 @@ public class TimeGameCommand implements Command { public void run(ArrayList args) { boolean startNow = getBoolean(args, START_SIGNIFIER); boolean setContent = getBoolean(args, CONTENT_SIGNIFIER); + try { - int timeInSeconds = getTime(args, TIME_SIGNIFIER); - TimeModeGame game = createGame(timeInSeconds, startNow, setContent); + Game game = createGame(args, startNow, setContent); game.runGame(); game.gameSummary(); + } catch (IncompleteCommandException e) { + System.out.println("Please specify game type."); + } catch (NullPointerException e) { + //exit + } + } + + public Game createGame(ArrayList args, boolean startNow, boolean setContent) + throws IncompleteCommandException { + if (getBoolean(args, TIME_SIGNIFIER)) { + return createTimeLimitGame(args,startNow, setContent); + } else if (getBoolean(args, WORD_SIGNIFIER)) { + return createWordLimitGame(setContent); + } else { + throw new IncompleteCommandException(); + } + } + + public WordLimitGame createWordLimitGame(boolean setContent) { + uiBot.printKeyboard(); + if (setContent) { + content.setContent(); + } + return new WordLimitGame(content.getContent(), 5); + } + + public TimeModeGame createTimeLimitGame(ArrayList args, boolean isReady, boolean setContent) { + try { + int timeInSeconds = getTime(args, TIME_SIGNIFIER); + if (setContent) { + content.setContent(); + } + return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); } catch (InvalidCommandException e) { System.out.println( "Please enter time in multiple of 30 seconds.\n" - + "e.g. time -t 30 " + + "e.g. time -t 30 " ); } catch (IncompleteCommandException | IndexOutOfBoundsException e) { System.out.println( "Please specify duration of the game using " - + TIME_SIGNIFIER + "\n" - + "e.g. time -t 60 " + + TIME_SIGNIFIER + "\n" + + "e.g. time -t 60 " ); } catch (NumberFormatException e) { System.out.println("Duration should be a number"); } + return null; } /** Determine whether the user command has the signifier. **/ @@ -45,7 +82,8 @@ public boolean getBoolean(ArrayList args, String key) { return args.contains(key); } - public int getTime(ArrayList args, String key) throws InvalidCommandException, IncompleteCommandException { + public int getTime(ArrayList args, String key) + throws InvalidCommandException, IncompleteCommandException { if (!args.contains(key)) { throw new IncompleteCommandException(); } @@ -56,11 +94,4 @@ public int getTime(ArrayList args, String key) throws InvalidCommandExce } return time; } - - public TimeModeGame createGame(int timeInSeconds, boolean isReady, boolean setContent) { - if (setContent) { - content.setContent(); - } - return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); - } } diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java deleted file mode 100644 index dfc9440a1a..0000000000 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ /dev/null @@ -1,26 +0,0 @@ -package seedu.typists.command; - -import seedu.typists.command.Command; -import seedu.typists.game.WordLimitGame; - -import java.util.ArrayList; - -import static seedu.typists.Main.content; -import static seedu.typists.Main.uiBot; - -public class WordGameCommand implements Command { - private static final String CONTENT_SIGNIFIER = "-c"; - - @Override - public void run(ArrayList args) { - if (args.contains(CONTENT_SIGNIFIER)) { - content.setContent(); - } - startWordLimitGame(); - } - - public void startWordLimitGame() { - uiBot.printKeyboard(); - new WordLimitGame(content.getContent(), 5).runGame(); - } -} diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index ee92571995..794468692a 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -69,9 +69,8 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" - + "content: set the content (or <-c> with game command)\n" - + "word: start a new word game\n" - + "time: start a new timer game <-t> to specify time <-sn> to start immediately\n" + + "content: set the content\n" + + "game: start a new game\n" + "history: view past game records\n" + "clear: clear all game records\n" + "bye: exit typist"; @@ -80,7 +79,7 @@ public class Messages { //This sample text is gotten from https://www.lipsum.com/ public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " - + "imply dummy text of the printing and typesetting industry ipsum is simply dummy " + + "imply dummy text of the printing and typesetting industry ipum is simply dummy " + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " + "industry industry industry industry industry industry industry industry industry industry industry " diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 4f19dd6661..bba842da2f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -9,9 +9,8 @@ | Welcome to Typist -- the ultimate cli typing game. | Brought to you by -- AY2122S1-CS2113-T13-4. | Manual: - | content: set the content (or <-c> with game command) - | word: start a new word game - | time: start a new timer game <-t> to specify time <-sn> to start immediately + | content: set the content + | game: start a new game | history: view past game records | clear: clear all game records | bye: exit typist diff --git a/time-limited_records.txt b/time-limited_records.txt index 85ab3c28ef..c9dd4cca36 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,10 +1,11 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] -Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] -Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] -Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] -Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] -Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] +Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] +Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] +Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] +Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] +Time-limited|30.2|8|22|30|26.666666666666668|73.33333333333333|43.70860927152318|[fleshy, balloon, of, hair, and, the, that, grew] From 681fcb95fb17a1a0724037bdd84716656acdefcd Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 03:16:29 +0800 Subject: [PATCH 162/272] update UG --- docs/UserGuide.md | 44 +++++++++++++++++++++++++++---------- seedu.typists.ui.TextUi.log | 2 +- time-limited_records.txt | 17 +++++++------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b9a4441289..646cca513a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -49,7 +49,22 @@ Examples * command example 2 -### Open Game: `time` +### Open Game: `game` +Start a typing game. +Format: `game GAME_MODE [-c]` +* SET_CONTENT `-c` is optional, it allows user to set input content before game starts. +* GAME_MODE + * `-w` for game in Word Limit Mode + * `-t` for game in Time Limit Mode +* For Time Limit Game: + * Format: `game -t TIME_LIMIT [-sn] [-c]` + * START_NOW `-sn` allows user to start the game immediately without the "ready to start?" prompt. + +Examples +* `game -t 30 -sn` +* `game -w -c` + + ### View past records: `history` View past game records. @@ -107,18 +122,21 @@ Statistics of game is shown automatically after a game is finished. ## Example of usage: ->`new` -``` -| Enter how many words you want the game to run: -``` ->`12` ``` +game -w + | Enter how many words you want the game to run: +5 + | lorem ipsum is simply dummy lorem ipsum is simply dummy + | Your progress:5/5 ``` ->`lorem ipsum is simply dummy` ``` -Your progress:5/12 -text of the printing and +game -t 30 -sn + | lorem ipsum is simply dummy text of the printing and +lorem ipsum is simply dummy text of the printing and + | typesetting imply dummy text of the printing and typesetting industry +typesetting imply dummy text of the printing and typesetting industry + | Timer's UP! ``` ## FAQ @@ -128,6 +146,8 @@ text of the printing and ## Command Summary -{Give a 'cheat sheet' of commands here} - -* Add todo `todo n/TODO_NAME d/DEADLINE` +| Feature | Command | +| ------------- | ------------- | +| Start Word Limit Game| `game -w [-c]` | +| Start Time Limit Game | `game -t TIME_LIMIT [-sn] [-c]` +| Get History | `history -h`| \ No newline at end of file diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 8c3f75ee82..dc4af883a7 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 28, 2021 2:45:18 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 3:08:47 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/time-limited_records.txt b/time-limited_records.txt index c9dd4cca36..2a368dc8e6 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,11 +1,12 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] -Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] -Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] -Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] -Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] -Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] -Time-limited|30.2|8|22|30|26.666666666666668|73.33333333333333|43.70860927152318|[fleshy, balloon, of, hair, and, the, that, grew] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] +Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] +Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] +Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] +Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] +Time-limited|30.2|8|22|30|26.666666666666668|73.33333333333333|43.70860927152318|[fleshy, balloon, of, hair, and, the, that, grew] +Time-limited|36.219|7|23|30|23.333333333333332|76.66666666666667|38.10154891079268|[ipum, dummy, dummy, dummy, dummy, dummy, dummy] From c4fc1fc8aafa9de2d2f062139e5cde24a770807a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 28 Oct 2021 10:22:16 +0800 Subject: [PATCH 163/272] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8eceed43cf..950f0166b1 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,3 +1,4 @@ + # Developer Guide * [Acknowledgements](#acknowledgements) * [Design & Implementation](#design-&-implementation) From aebc03ef6fd0ab0eb51fcd641a15bdb956946519 Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Thu, 28 Oct 2021 13:04:09 +0800 Subject: [PATCH 164/272] add sequence diagram (temporary) --- docs/DeveloperGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e51d6b8cd7..8c5acc43ae 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -31,6 +31,8 @@ Gonna to change this .puml diagram later - zhansen ![](uml/WordLimitMode.png) ### Time Limit Game +Sequence Diagram for Time Mode Game: +![image](https://user-images.githubusercontent.com/69776265/139190231-eb648329-517b-42dc-a088-fbce5c93c616.png) ### \[Proposed\] View Statistics feature #### \[Proposed Implementation\] From 15038e0740d6594a4882910f43c2b43849503851 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 28 Oct 2021 22:23:49 +0800 Subject: [PATCH 165/272] Merge summary into word limit game --- seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.1 | 2 +- src/main/java/seedu/typists/common/Utils.java | 6 + .../typists/game/WordLimitDataProcessor.java | 53 --------- .../seedu/typists/game/WordLimitGame.java | 106 ++++++++---------- src/test/java/seedu/UtilsTest.java | 27 ++++- .../ui/WordLimitDataProcessorTest.java | 18 --- time-limited_records.txt | 5 +- word-limited_records.txt | 9 ++ 9 files changed, 89 insertions(+), 139 deletions(-) delete mode 100644 src/main/java/seedu/typists/game/WordLimitDataProcessor.java delete mode 100644 src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index 4775273733..d9d3977b29 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 27, 2021 11:09:05 PM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 10:12:31 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index 1a29966417..2286a1aa63 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Oct 27, 2021 11:13:26 PM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 10:19:58 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 67e5dd9580..489ca26fb6 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -25,11 +25,17 @@ public static String[] getDisplayLines(ArrayList wordLists, int wordsPer String[] line = new String[wordsPerLine]; try { for (int i = 0; i < wordsPerLine; i++) { + if (startIndex + i > wordLists.size() - 1) { + break; + } line[i] = wordLists.get(startIndex + i); } } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "exceed content maximum."); } + line = Arrays.stream(line) + .filter(s -> (s != null && s.length() > 0)) + .toArray(String[]::new); return line; } diff --git a/src/main/java/seedu/typists/game/WordLimitDataProcessor.java b/src/main/java/seedu/typists/game/WordLimitDataProcessor.java deleted file mode 100644 index 3351d1e282..0000000000 --- a/src/main/java/seedu/typists/game/WordLimitDataProcessor.java +++ /dev/null @@ -1,53 +0,0 @@ -package seedu.typists.game; - -import seedu.typists.exception.InvalidStringInputException; - -import java.util.ArrayList; - -import static seedu.typists.parser.StringParser.splitString; - -public class WordLimitDataProcessor { - protected String userInput; - protected String contentWords; - protected Boolean isExit; - - /** - * Ture if the 2 inputs are different. - * - * @param input one of inputs - * @param text another input - */ - public WordLimitDataProcessor(String input, String text) { - this.userInput = input; - this.contentWords = text; - this.isExit = !input.equals(text); - } - - /** - * Get exit. - * - * @return obtain the Exit status - */ - public Boolean getIsExit() { - return isExit; - } - - public int getError() throws InvalidStringInputException { - ArrayList userInput0 = splitString(userInput, " "); - ArrayList contentWords0 = splitString(contentWords, " "); - ArrayList list3 = new ArrayList(); - - for (int i = 0; i < contentWords0.size(); i++) { - for (int j = 0; j < userInput0.size(); j++) { - if (contentWords0.contains(userInput0.get(j))) { - if (contentWords0.get(i).equals(userInput0.get(j))) { - list3.add(contentWords0.get(i)); - } - } else { - break; - } - } - } - return contentWords0.size() - list3.size(); - } -} diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 92cae6b7d9..dceeb54304 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -1,47 +1,39 @@ package seedu.typists.game; import seedu.typists.exception.InvalidStringInputException; -import seedu.typists.ui.TextUi; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Scanner; +import static seedu.typists.common.Utils.getDisplayLines; +import static seedu.typists.common.Utils.getWordLineFromStringArray; import static seedu.typists.parser.StringParser.splitString; public class WordLimitGame extends Game { - private ArrayList eachWord; + protected ArrayList wordLines; protected int wordLimit; private int gameIndex; - private final int numberOfWordsDisplayed; + private final int wordsPerLine; private final String content1; + private long beginTime; public WordLimitGame(String targetWordSet, int wordsPerLine) { super(); this.eachWord = new ArrayList<>(100); this.gameIndex = 0; - this.numberOfWordsDisplayed = wordsPerLine; + this.wordsPerLine = wordsPerLine; this.content1 = targetWordSet; this.wordLimit = getWordLimit(); } @Override public void runGame() { - try { - game(); - } catch (InvalidStringInputException e) { - e.printStackTrace(); - //needs update - } catch (InterruptedException e) { - e.printStackTrace(); - //needs update - } - } - - @Override - public void gameSummary() { - + game(); + gameSummary(); } public int getTotalSentence() { @@ -60,62 +52,54 @@ public int getWordLimit() { } } - public void trimContent(int wordLimit) throws InvalidStringInputException { - eachWord = splitString(content1, " "); + public void trimContent(int wordLimit) { + try { + eachWord = splitString(content1, " "); + } catch (InvalidStringInputException e) { + e.printStackTrace(); + } eachWord = new ArrayList<>(eachWord.subList(0, wordLimit)); + System.out.println("ori"); + for (String arr : eachWord) { + System.out.println(arr); + } } - public void game() throws InterruptedException, InvalidStringInputException { + public void game() { trimContent(wordLimit); + beginTime = getTimeNow(); + List inputs = new ArrayList<>(); + int row = 0;// for method: getDisplayLines() boolean isExit = false; - int totalError = 0; - - String actualWord = ""; - String inputWord = ""; - while (!isExit) { - assert gameIndex < getTotalSentence() : "There are still texts to be typed."; - String temp = ""; - int number = 0; - - while (gameIndex < getTotalSentence()) { - temp += eachWord.get(gameIndex) + " "; - gameIndex += 1; - number += 1; - if (number >= numberOfWordsDisplayed) { - break; - } - } + row++; + String[] displayed = getDisplayLines(eachWord,wordsPerLine,row); + displayedLines.add(displayed); + ui.printLine(displayed); - actualWord += temp; - temp = temp.trim(); - ui.printLine(temp); + //read user input String fullCommand = ui.readCommand(); - inputWord += fullCommand + " "; - if (fullCommand.equals("Exit")) { - ui.showAnimatedWordLimitSummary(totalError, gameIndex); break; } - WordLimitDataProcessor recordError = new WordLimitDataProcessor(fullCommand, temp); - try { - totalError += recordError.getError(); - } catch (InvalidStringInputException e) { - e.printStackTrace(); - //do something - } - //isExit = recordError.getIsExit(); - ui.printGameMode1Progress(gameIndex, getTotalSentence()); - - if (gameIndex >= getTotalSentence()) { - ui.showAnimatedError( - splitString(actualWord.trim(), " "), - splitString(inputWord.trim(), " "), - getTotalSentence() - ); - break; + //update for summary + inputs.add(fullCommand); + updateUserLines(inputs); + + if ((wordsPerLine * (row)) > eachWord.size()) { + isExit = true; } } } + + public void gameSummary() { + double realGameTime = getDuration(beginTime, getTimeNow()); + HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); + handleStorage(summary); + } + + public void updateUserLines(List stringArray) { + userLines = getWordLineFromStringArray(stringArray); + } } diff --git a/src/test/java/seedu/UtilsTest.java b/src/test/java/seedu/UtilsTest.java index f14ae8298e..f793054346 100644 --- a/src/test/java/seedu/UtilsTest.java +++ b/src/test/java/seedu/UtilsTest.java @@ -2,24 +2,45 @@ import org.junit.jupiter.api.Test; -import static seedu.typists.common.Utils.getWordLines; -import static seedu.typists.common.Utils.splitStringIntoWordList; - import java.util.ArrayList; import java.util.Arrays; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.typists.common.Utils.getDisplayLines; +import static seedu.typists.common.Utils.splitStringIntoWordList; public class UtilsTest { private static final String SAMPLE = "this is test text here"; + private static final ArrayList places = new ArrayList<>(Arrays.asList( + "this", "is", "test", "text", "here","this1", "is1", "test1", "text1", "here1")); + //name: whatIsBeingTested_descriptionOfTestInputs_expectedOutcome @Test public void splitStringIntoWordList_sampleTxt_success() { ArrayList result = new ArrayList<>(Arrays.asList("this", "is", "test", "text", "here")); assertEquals(result, splitStringIntoWordList(SAMPLE)); + assertEquals(result.size(), 5); } + @Test + public void getDisplayLines_inRange_success() { + String[] displayed = getDisplayLines(places, 3, 3); + String[] result = { "is1", "test1", "text1"}; + for (int i = 0; i < displayed.length; i++) { + assertEquals(displayed[i], result[i]); + } + } + + @Test + public void getDisplayLines_outRange_success() { + String[] displayed = getDisplayLines(places, 6, 2); + String[] result = { "is1", "test1", "text1", "here1"}; + for (int i = 0; i < displayed.length; i++) { + assertEquals(displayed[i], result[i]); + } + } // this test is commented out // because it will fail due to array address allocation // but the result strings are identical diff --git a/src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java b/src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java deleted file mode 100644 index 591b5b38c4..0000000000 --- a/src/test/java/seedu/typists/ui/WordLimitDataProcessorTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package seedu.typists.ui; - -import org.junit.jupiter.api.Test; -import seedu.typists.exception.InvalidStringInputException; -import seedu.typists.game.WordLimitDataProcessor; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class WordLimitDataProcessorTest { - - @Test - void getError_expect1() throws InvalidStringInputException { - String a = "Equal Or Not"; - String b = "Equal Or Not?"; - WordLimitDataProcessor c = new WordLimitDataProcessor(a, b); - assertEquals(1,c.getError()); - } -} diff --git a/time-limited_records.txt b/time-limited_records.txt index 2dc12de3ad..5cf8143b33 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,5 +1,6 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] diff --git a/word-limited_records.txt b/word-limited_records.txt index 05740c23b8..c72a6f8dc4 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,2 +1,11 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] +Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] From a1fd749871f17c81b7e8a8eb40fee24106eabba4 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 29 Oct 2021 02:48:10 +0800 Subject: [PATCH 166/272] Merge from master to branch 76 --- .gitignore | 4 + docs/DeveloperGuide.md | 58 +++++++++- docs/UserGuide.md | 108 +++++++++++++++--- docs/uml/ViewStatistics-1.drawio | 1 + docs/uml/ViewStatistics-1.drawio.svg | 4 + docs/uml/ViewStatistics-2.drawio | 1 + docs/uml/ViewStatistics-2.drawio.svg | 4 + docs/uml/ViewStatistics-3.drawio | 1 + docs/uml/ViewStatistics-3.drawio.svg | 4 + docs/uml/ViewStatistics-4.drawio | 1 + docs/uml/ViewStatistics-4.drawio.svg | 4 + docs/uml/ViewStatistics-5.drawio | 1 + docs/uml/ViewStatistics-5.drawio.svg | 4 + seedu.typists.ui.TextUi.log | 2 +- seedu.typists.ui.TextUi.log.1 | 2 +- seedu.typists.ui.TextUi.log.lck | 0 .../seedu/typists/command/CommandFactory.java | 6 +- .../seedu/typists/command/GameCommand.java | 97 ++++++++++++++++ .../typists/command/TimeGameCommand.java | 60 ---------- .../typists/command/WordGameCommand.java | 21 ---- .../java/seedu/typists/common/Messages.java | 3 +- src/main/java/seedu/typists/common/Utils.java | 12 +- .../exception/ExceedRangeException.java | 4 + .../java/seedu/typists/game/TimeModeGame.java | 17 ++- .../seedu/typists/game/WordLimitGame.java | 8 +- src/test/java/seedu/UtilsTest.java | 5 +- text-ui-test/EXPECTED.TXT | 3 +- 27 files changed, 317 insertions(+), 118 deletions(-) create mode 100644 docs/uml/ViewStatistics-1.drawio create mode 100644 docs/uml/ViewStatistics-1.drawio.svg create mode 100644 docs/uml/ViewStatistics-2.drawio create mode 100644 docs/uml/ViewStatistics-2.drawio.svg create mode 100644 docs/uml/ViewStatistics-3.drawio create mode 100644 docs/uml/ViewStatistics-3.drawio.svg create mode 100644 docs/uml/ViewStatistics-4.drawio create mode 100644 docs/uml/ViewStatistics-4.drawio.svg create mode 100644 docs/uml/ViewStatistics-5.drawio create mode 100644 docs/uml/ViewStatistics-5.drawio.svg delete mode 100644 seedu.typists.ui.TextUi.log.lck create mode 100644 src/main/java/seedu/typists/command/GameCommand.java delete mode 100644 src/main/java/seedu/typists/command/TimeGameCommand.java delete mode 100644 src/main/java/seedu/typists/command/WordGameCommand.java create mode 100644 src/main/java/seedu/typists/exception/ExceedRangeException.java diff --git a/.gitignore b/.gitignore index f69985ef1f..45f2d19a29 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT +time-limited_records.txt +seedu.typists.ui.TextUi.log +seedu.typists.ui.TextUi.log.1 +seedu.typists.ui.TextUi.log.lck diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 67e4f27392..8c5acc43ae 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,4 +1,7 @@ + # Developer Guide +* [Acknowledgements](#acknowledgements) +* [Design & Implementation](#design-&-implementation) * [Acknoledgements](#acknowledgements) @@ -28,8 +31,60 @@ Gonna to change this .puml diagram later - zhansen ![](uml/WordLimitMode.png) ### Time Limit Game +Sequence Diagram for Time Mode Game: +![image](https://user-images.githubusercontent.com/69776265/139190231-eb648329-517b-42dc-a088-fbce5c93c616.png) + +### \[Proposed\] View Statistics feature +#### \[Proposed Implementation\] +The top-level logic of view statistics feature resides in ViewCommand. It implements the Command +interface. The key method of the class is `executeCommand()`. +`executeCommand()` logic: +1. Calls the retrieveStatistics() method of StatisticsManager to get the statistics. +2. Calls the displayStatistics() method of ViewCommandUi to display the statistics retrieved. + +StatisticsManager performs the logic for processing the game records to obtain the statistics. +Its key methods are: +* `retrieveStatistics()` - Decides which of the three methods below to run +* `calculateBestStatistics()` - Returns the best statistics over the past n games +* `calculateWorstStatistics()` - Returns the worst statistics over the past n games +* `calculateAverageStatistics()` - Returns the average statistics over the past n games + +Given below is an example usage scenario and how the program implements the feature. + +Step 1: The user launches the application (scenario assumes that there are several game records already stored in multiple files). + +Step 2: The user executes `view -m best -g time -n 9` to view his/her best statistics for the error game mode over the past 9 games. + +Step 3: A ViewCommand object is then instantiated. + +![Alt text](uml/ViewStatistics-1.drawio.svg) + +Step 4. ViewCommand calls the retrieveStatistics() method of StatisticsManager. +![Alt text](uml/ViewStatistics-2.drawio.svg) -### Storage +Step 5: StatisticsManager creates a GameRecordsManager object. +* The constructor of GameRecordsManager calls the readGameRecords() method of the Storage class to retrieve the gamer's past game records from the text files. + +![Alt text](uml/ViewStatistics-3.drawio.svg) +Step 6. StatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). +* Calculated statistics is returned. + +Step 7. ViewCommand calls the displayStatistics() method of the ViewCommandUi class to display the statistics. +![Alt test](uml/ViewStatistics-4.drawio.svg) + + +The following sequence diagram shows how the above scenario is executed. +![Alt test](uml/ViewStatistics-5.drawio.svg) + + + +#### Alternative Implementation +* One implementation considered is to do away with the retrieveStatistics() method and immediately call one of calculateBestStatistics, +calculateWorstStatistics() or calculateAverageStatistics() based on the gamer's imput using a switch statement. This implementation choice +was not used because it violates the Single Responsibility Principle and does not do SLAP well. +* Another implementation considered was for GameRecordsManager to do the main logic. This implementation was not done as it violates the +Single Responsibility Principle. + ## Product scope @@ -64,3 +119,4 @@ Our product is a typing game, intent to provide enjoyment for people who are fam ## Instructions for manual testing {Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} + diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 207fb7e491..646cca513a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,17 +1,40 @@ # User Guide +* [Introduction](#introduction) +* [Quick Start](#quick-start) +* [Features](#features) +* [FAQ](#faq) +* [Command Summary](#command-summary) -## Introduction +## Introduction -{Give a product intro} +Typist is a CLI typing game. ## Quick Start {Give steps to get started quickly} -1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +1. Ensure that you have Java 11 or above installed. +2. Down the latest version of `Typist` from [here](http://link.to/duke). +3. Navigate to the folder containing the jar file and run `java -jar tp.jar` ## Features + +### Notes about the command format: + +* Words in UPPER_CASE are parameters to be supplied by the user. +e.g. in `history -g GAME_MODE`, `GAME_MODE` is a parameter which can be used as `history -g time`. +* Items in square brackets are optional. +e.g. `-g GAME_MODE [-n NUMBER_OF_RECORDS]` can be used as `-g time -n 9` or as `-g time` +* Parameters can be in any order. +e.g. if command specifies `history -g GAME_MODE [-n NUMBER_OF_RECORDS]`, `history [-n NUMBER_OF_RECORDS] -g GAME_MODE` +is also acceptable. +* If a parameter is expected only once in the command but you specified it multiple times, +only the first occurrence of the parameter will be taken +e.g. if you specify `history -g time -g time -n 10`, only `history -g time -n 10` will be taken. +* For commands which have a help parameter, if `-h` is among the parameters provided, +all other parameters will be ignored and the guide for that command will be displayed. +e.g. `history -g time -h -n 10` will be interpreted as `history -h`. + ### Usage ### Open Game @@ -26,6 +49,56 @@ Examples * command example 2 +### Open Game: `game` +Start a typing game. +Format: `game GAME_MODE [-c]` +* SET_CONTENT `-c` is optional, it allows user to set input content before game starts. +* GAME_MODE + * `-w` for game in Word Limit Mode + * `-t` for game in Time Limit Mode +* For Time Limit Game: + * Format: `game -t TIME_LIMIT [-sn] [-c]` + * START_NOW `-sn` allows user to start the game immediately without the "ready to start?" prompt. + +Examples +* `game -t 30 -sn` +* `game -w -c` + + + +### View past records: `history` +View past game records. +Format: `history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` +* NUMBER_OF_RECORDS defaults to all records if not provided +* Possible arguments for GAME_MODE are - `word` or `time` + +Examples +* `history -g time -n 10` +* `history -g word` + + +### Clear past records: `clear` +Clear all past game records +Format: `clear [-g GAME_MODE] [-h]` +* GAME_MODE defaults to `all` if not provided +* Possible arguments for GAME_MODE are - `word`, `time` or `all` + +Examples +* `clear -g time` +* `clear` + + +### Saving the data +Typists automatically stores the updated game records into text files when gamer enters the +`bye` command to exit Typists. + + +### !Warning: Editing the data file +Typists is a game application and only game records will be stored. +Gamers should not edit the data it will manipulate the integrity of the records. +In the event where the data is editted and the wrong format is inputted, the game will crash when it tries to read the file. +The only way to make it run smoothly again is to delete the text files, hence losing all the game data. + ### `Keyword` - Describe action @@ -49,18 +122,21 @@ Statistics of game is shown automatically after a game is finished. ## Example of usage: ->`new` -``` -| Enter how many words you want the game to run: -``` ->`12` ``` +game -w + | Enter how many words you want the game to run: +5 + | lorem ipsum is simply dummy lorem ipsum is simply dummy + | Your progress:5/5 ``` ->`lorem ipsum is simply dummy` ``` -Your progress:5/12 -text of the printing and +game -t 30 -sn + | lorem ipsum is simply dummy text of the printing and +lorem ipsum is simply dummy text of the printing and + | typesetting imply dummy text of the printing and typesetting industry +typesetting imply dummy text of the printing and typesetting industry + | Timer's UP! ``` ## FAQ @@ -70,6 +146,8 @@ text of the printing and ## Command Summary -{Give a 'cheat sheet' of commands here} - -* Add todo `todo n/TODO_NAME d/DEADLINE` +| Feature | Command | +| ------------- | ------------- | +| Start Word Limit Game| `game -w [-c]` | +| Start Time Limit Game | `game -t TIME_LIMIT [-sn] [-c]` +| Get History | `history -h`| \ No newline at end of file diff --git a/docs/uml/ViewStatistics-1.drawio b/docs/uml/ViewStatistics-1.drawio new file mode 100644 index 0000000000..3fd76a1942 --- /dev/null +++ b/docs/uml/ViewStatistics-1.drawio @@ -0,0 +1 @@ +jZTNjpswEICfhmNWYCckOSYk7F4qtYq0PVYuTMCKYagxCdun7xgbEnYVqRcw3/wPMw54UvWvWjTlN8xBBSzM+4AfAsYituT0suTDkXW8dqDQMncovIOT/AvecqSdzKH1zCGDqIxs5jDDuobMzJjQGm9ztTOqfAYaUcAsDQtOmVDwRe2nzE3p6Iat7/wNZFGOkaN46yS/RXYpNHa1jxcwni7T6HB04kqMvnzcthQ53h4QPwY80YjGnao+AWV7O29b+kQ65a2hNv9jkJ77zaH/9R2bbvGja2N8b7cL7+UqVAdjGbEif/szklvqp8icIP7T2Uz3b6CuYGQm7ohOhX8Ppm0jaluw+VBzW+tz0Q4jsCOFKGz65166CfDdu4RbglUlqNleTIV2n02IudhfsKtmxGyWHStNpegU2dQvYDL730L6KEVWdhpeRUNgSaBBWRvQxyu1vPVK1nMqKqns/O90VkpDY9pShIPoaGxAe6UTdnroZWkMzTZb2R6s6HfZh1VoXwrEQoFoZPuSYTUIsnZQTc8uBB1nQVZs/zmM2zA25CaVSlChHurkKUuSTWqrNBov8CA5huvdKvUeHjjf8mQVTz27gjbQP52/aJpqui0AKzCaMg5Hg9gvgr8ophvgdl+7iHtWPqzcaCf8pheT6/u008EP/Ph5X6xB9nB78eM/ \ No newline at end of file diff --git a/docs/uml/ViewStatistics-1.drawio.svg b/docs/uml/ViewStatistics-1.drawio.svg new file mode 100644 index 0000000000..0db5031503 --- /dev/null +++ b/docs/uml/ViewStatistics-1.drawio.svg @@ -0,0 +1,4 @@ + + + +
:ViewCommand
:ViewCommand
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-2.drawio b/docs/uml/ViewStatistics-2.drawio new file mode 100644 index 0000000000..2e4fb472d9 --- /dev/null +++ b/docs/uml/ViewStatistics-2.drawio @@ -0,0 +1 @@ +7VdLc5swEP41PjoDyGD7aDsmmUkykxl3+jgqsAbFAlEh/Oiv7wqJl1u7TQ+ZHHoJ7LcvaffbNRmRVXa8k7RIn0QMfOQ58XFEbkeeN/WmDj40cjIImZKpQRLJYoM5HbBhP8CAboNWLIbSYgZSQnDFiiEYiTyHSA0wKqU4DM22gscDoKAJDI6hgU1EOfxi9oXFKjXozJt2+D2wJG0yu8HcaF5otEukqHKbb+SRcBK6t2ujzmgTy+YtUxqLQw8i6xFZSSGUecuOK+C6uMOyhRe07bkl5OpvHMLHh514We/gYbNm+WtVyHg8tlH2lFfQXCPgGG+5FRgW60kjowi+V/qky3vge1Asoh2kL6dOfGin/cdl3e4FGrhOcex7BIl+ViW23ibEk5ucRmWL1sb1IMa+WTEXOT6WdfVB389BqdyBilIrpDRKKwl3tEBggoCQKhWJyCl/FEKDLoKvoNTJcpJWSmhHlXGrhSNTX3vv33TsG99Kt0ebqhZOVtBXCGnGuAYWMkqZQtbiJR1MgCwCaY02opJ1aVOlkOqer8vkY/f0H21Q3iRCJBxowcqbSGS1Iipr03BrUuDrIInvLc/TmMu5gT5oHi/0xKAsCsg/pSzXZVNUtmYTY9YXy/qgzyBZBhh3U9CI5QlqZ6hE3wTUBSUSU56+NlXSQq+CWuxKWEunVopDxnnTViXFDlaCC1kTgayd6cIP7f16OJmTla/vyekL8GU7nj0TO6BkGdMyrYnjtlTT/Lo4Ws1mqq97ZZ68drBxY4LAokjskmPX5di5cf35xMSSwKli+2FOardZ0vq24Z4FqyeyiRU4xDdOdvWOvbnvDcPY3hnPbjcgC+ipZ1Zog/JqLse5kMuGxBcT9SxCk0JstyWoM49ejTqoXltvWGHeu60w73crrElWtQBZbBR2tmQqKp9ojj8gsrfjqnPHP+293kK6vuHqLoJc70E380OvI68+G854fza91WoW/tPAWwaAVHC8PsKXR9OfB8E5xWeWW4fuw8ANiMHS3kdB4Fye3gHd38pt8vG4/ZnBYSWyjOJ3z39Wf3RWB+58+o6sRrH7oDULvvu3gax/Ag== \ No newline at end of file diff --git a/docs/uml/ViewStatistics-2.drawio.svg b/docs/uml/ViewStatistics-2.drawio.svg new file mode 100644 index 0000000000..9c82d85d60 --- /dev/null +++ b/docs/uml/ViewStatistics-2.drawio.svg @@ -0,0 +1,4 @@ + + + +
uses
uses
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio b/docs/uml/ViewStatistics-3.drawio new file mode 100644 index 0000000000..7da7f2e5cd --- /dev/null +++ b/docs/uml/ViewStatistics-3.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio.svg b/docs/uml/ViewStatistics-3.drawio.svg new file mode 100644 index 0000000000..d95c2d03c1 --- /dev/null +++ b/docs/uml/ViewStatistics-3.drawio.svg @@ -0,0 +1,4 @@ + + + +
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-4.drawio b/docs/uml/ViewStatistics-4.drawio new file mode 100644 index 0000000000..dbb2a72940 --- /dev/null +++ b/docs/uml/ViewStatistics-4.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-4.drawio.svg b/docs/uml/ViewStatistics-4.drawio.svg new file mode 100644 index 0000000000..823fb246cc --- /dev/null +++ b/docs/uml/ViewStatistics-4.drawio.svg @@ -0,0 +1,4 @@ + + + +
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-5.drawio b/docs/uml/ViewStatistics-5.drawio new file mode 100644 index 0000000000..c11d8a4f5e --- /dev/null +++ b/docs/uml/ViewStatistics-5.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-5.drawio.svg b/docs/uml/ViewStatistics-5.drawio.svg new file mode 100644 index 0000000000..89631fe5cd --- /dev/null +++ b/docs/uml/ViewStatistics-5.drawio.svg @@ -0,0 +1,4 @@ + + + +:ViewCommand:StatisticsManagerretrieveStatistics(best, "Time-limited", 9)
calculateBestStatistics()
calculateBestStatistics()
bestStatistics
bestStatistics
bestStatisticsnew StatisticsManager():GameRecordsManager()gameRecordsnew GameRecordsManager():Storagenew Storage()timeLimitedGameRecords = readGameRecords("Time-limited")wordLimitedGameRecords = readGameRecords("Word-limited")new getGameRecords("Time-limited", 9):ViewCommandUinew ViewCommandUi()displayStatistics(statistics)executeCommand(best, "Time-limited", 9)
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index d9d3977b29..ffb1a5b619 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 28, 2021 10:12:31 PM seedu.typists.ui.SummaryUi setUpLog +Oct 29, 2021 2:47:24 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index 2286a1aa63..6087e49b35 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Oct 28, 2021 10:19:58 PM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 2:42:10 AM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/seedu.typists.ui.TextUi.log.lck b/seedu.typists.ui.TextUi.log.lck deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 93eb23812f..f0643dc2d1 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -7,10 +7,8 @@ public class CommandFactory { public Command getCommand(String commandType) { switch (commandType) { - case "time": - return new TimeGameCommand(); - case "word": - return new WordGameCommand(); + case "game": + return new GameCommand(); case "content": return new ContentCommand(); case "error": diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java new file mode 100644 index 0000000000..0473e6c34d --- /dev/null +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -0,0 +1,97 @@ +package seedu.typists.command; + +import seedu.typists.exception.IncompleteCommandException; +import seedu.typists.exception.InvalidCommandException; +import seedu.typists.game.Game; +import seedu.typists.game.TimeModeGame; +import seedu.typists.game.WordLimitGame; + +import java.util.ArrayList; + +import static seedu.typists.Main.content; +import static seedu.typists.Main.uiBot; +import static seedu.typists.Main.LINE_LENGTH; + +public class GameCommand implements Command { + private static final String TIME_SIGNIFIER = "-t"; + private static final String WORD_SIGNIFIER = "-w"; + private static final String START_SIGNIFIER = "-sn"; + private static final String CONTENT_SIGNIFIER = "-c"; + + @Override + public void run(ArrayList args) { + boolean startNow = getBoolean(args, START_SIGNIFIER); + boolean setContent = getBoolean(args, CONTENT_SIGNIFIER); + + try { + Game game = createGame(args, startNow, setContent); + game.runGame(); + game.gameSummary(); + } catch (IncompleteCommandException e) { + System.out.println("Please specify game type."); + } catch (NullPointerException e) { + //exit + } + } + + public Game createGame(ArrayList args, boolean startNow, boolean setContent) + throws IncompleteCommandException { + if (getBoolean(args, TIME_SIGNIFIER)) { + return createTimeLimitGame(args,startNow, setContent); + } else if (getBoolean(args, WORD_SIGNIFIER)) { + return createWordLimitGame(setContent); + } else { + throw new IncompleteCommandException(); + } + } + + public WordLimitGame createWordLimitGame(boolean setContent) { + uiBot.printKeyboard(); + if (setContent) { + content.setContent(); + } + return new WordLimitGame(content.getContent(), 5); + } + + public TimeModeGame createTimeLimitGame(ArrayList args, boolean isReady, boolean setContent) { + try { + int timeInSeconds = getTime(args, TIME_SIGNIFIER); + if (setContent) { + content.setContent(); + } + return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); + } catch (InvalidCommandException e) { + System.out.println( + "Please enter time in multiple of 30 seconds.\n" + + "e.g. time -t 30 " + ); + } catch (IncompleteCommandException | IndexOutOfBoundsException e) { + System.out.println( + "Please specify duration of the game using " + + TIME_SIGNIFIER + "\n" + + "e.g. time -t 60 " + ); + } catch (NumberFormatException e) { + System.out.println("Duration should be a number"); + } + return null; + } + + /** Determine whether the user command has the signifier. **/ + public boolean getBoolean(ArrayList args, String key) { + return args.contains(key); + } + + public int getTime(ArrayList args, String key) + throws InvalidCommandException, IncompleteCommandException { + if (!args.contains(key)) { + throw new IncompleteCommandException(); + } + int index = args.indexOf("-t"); + int time = Integer.parseInt(args.get(index + 1)); + if (time % 30 != 0 || time == 0) { + throw new InvalidCommandException(); + } + return time; + } +} diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java deleted file mode 100644 index 93de4905ed..0000000000 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ /dev/null @@ -1,60 +0,0 @@ -package seedu.typists.command; - -import seedu.typists.exception.IncompleteCommandException; -import seedu.typists.exception.InvalidCommandException; -import seedu.typists.game.TimeModeGame; - -import java.util.ArrayList; - -import static seedu.typists.Main.content; -import static seedu.typists.Main.LINE_LENGTH; - - -public class TimeGameCommand implements Command { - private static final String TIME_SIGNIFIER = "-t"; - private static final String START_SIGNIFIER = "-sn"; - - @Override - public void run(ArrayList args) { - boolean startNow = getStartNow(args, START_SIGNIFIER); - try { - int timeInSeconds = getTime(args, TIME_SIGNIFIER); - TimeModeGame game = createGame(timeInSeconds, startNow); - game.runGame(); - game.gameSummary(); - } catch (InvalidCommandException e) { - System.out.println( - "Please enter time in multiple of 30 seconds.\n" - + "e.g. time -t 30 " - ); - } catch (IncompleteCommandException | IndexOutOfBoundsException e) { - System.out.println( - "Please specify duration of the game using " - + TIME_SIGNIFIER + "\n" - + "e.g. time -t 60 " - ); - } catch (NumberFormatException e) { - System.out.println("Duration should be a number"); - } - } - - public boolean getStartNow(ArrayList args, String key) { - return args.contains(key); - } - - public int getTime(ArrayList args, String key) throws InvalidCommandException, IncompleteCommandException { - if (!args.contains(key)) { - throw new IncompleteCommandException(); - } - int index = args.indexOf("-t"); - int time = Integer.parseInt(args.get(index + 1)); - if (time % 30 != 0 || time == 0) { - throw new InvalidCommandException(); - } - return time; - } - - public TimeModeGame createGame(int timeInSeconds, boolean isReady) { - return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); - } -} diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java deleted file mode 100644 index 60f12eb90f..0000000000 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ /dev/null @@ -1,21 +0,0 @@ -package seedu.typists.command; - -import seedu.typists.command.Command; -import seedu.typists.game.WordLimitGame; - -import java.util.ArrayList; - -import static seedu.typists.Main.content; -import static seedu.typists.Main.uiBot; - -public class WordGameCommand implements Command { - @Override - public void run(ArrayList args) { - startWordLimitGame(); - } - - public void startWordLimitGame() { - uiBot.printKeyboard(); - new WordLimitGame(content.getContent(), 5).runGame(); - } -} diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 38aee22137..794468692a 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -70,8 +70,7 @@ public class Messages { public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" + "content: set the content\n" - + "word: start a new word game\n" - + "time: start a new timer game <-t> to specify time <-sn> to start immediately\n" + + "game: start a new game\n" + "history: view past game records\n" + "clear: clear all game records\n" + "bye: exit typist"; diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 489ca26fb6..b30839ffc2 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -1,5 +1,8 @@ package seedu.typists.common; +import seedu.typists.exception.ExceedRangeException; +import seedu.typists.exception.FaultyInputException; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -10,7 +13,6 @@ * Utility methods. */ public class Utils { - protected static final Logger logger = Logger.getLogger("Foo"); /** convert the line of text into an arraylist of word. */ public static ArrayList splitStringIntoWordList(String line) { @@ -19,10 +21,12 @@ public static ArrayList splitStringIntoWordList(String line) { /** get one line that is supposed to be displayed at one time of game. **/ - public static String[] getDisplayLines(ArrayList wordLists, int wordsPerLine, int row) { + public static String[] getDisplayLines(ArrayList wordLists, int wordsPerLine, int row) + throws ExceedRangeException { int startIndex = (row - 1) * wordsPerLine; assert startIndex >= 0 : "word index should be non-negative"; String[] line = new String[wordsPerLine]; + try { for (int i = 0; i < wordsPerLine; i++) { if (startIndex + i > wordLists.size() - 1) { @@ -31,8 +35,10 @@ public static String[] getDisplayLines(ArrayList wordLists, int wordsPer line[i] = wordLists.get(startIndex + i); } } catch (IndexOutOfBoundsException e) { - logger.log(Level.WARNING, "exceed content maximum."); + throw new ExceedRangeException(); } + + //remove null elements line = Arrays.stream(line) .filter(s -> (s != null && s.length() > 0)) .toArray(String[]::new); diff --git a/src/main/java/seedu/typists/exception/ExceedRangeException.java b/src/main/java/seedu/typists/exception/ExceedRangeException.java new file mode 100644 index 0000000000..73dfdcada5 --- /dev/null +++ b/src/main/java/seedu/typists/exception/ExceedRangeException.java @@ -0,0 +1,4 @@ +package seedu.typists.exception; + +public class ExceedRangeException extends Throwable { +} diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 5e6eaf4d56..1f767392ab 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,5 +1,7 @@ package seedu.typists.game; +import seedu.typists.exception.ExceedRangeException; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -11,6 +13,7 @@ import static seedu.typists.common.Utils.getDisplayLines; public class TimeModeGame extends Game { + protected String targetWordSet; protected final int timeInSeconds; protected final ArrayList wordLists; protected int wordsPerLine; @@ -19,6 +22,7 @@ public class TimeModeGame extends Game { public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean isReady) { super(); + this.targetWordSet = targetWordSet; assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); this.timeInSeconds = timeInSeconds; @@ -48,10 +52,14 @@ public void runGame() { gameTime = (double) currTime / 1000; timeOver = true; } else { - String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); - ui.printLine(display); - displayedLines.add(display); - inputs.add(in.nextLine()); + try { + String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); + ui.printLine(display); + displayedLines.add(display); + inputs.add(in.nextLine()); + } catch (ExceedRangeException e) { + currentRow = 0; + } currentRow++; } } @@ -75,7 +83,6 @@ public void gameSummary() { handleStorage(summary); } - public void updateUserLines(List stringArray) { userLines = getWordLineFromStringArray(stringArray); } diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index dceeb54304..a29d83b471 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -1,5 +1,6 @@ package seedu.typists.game; +import seedu.typists.exception.ExceedRangeException; import seedu.typists.exception.InvalidStringInputException; import java.util.ArrayList; @@ -73,7 +74,12 @@ public void game() { boolean isExit = false; while (!isExit) { row++; - String[] displayed = getDisplayLines(eachWord,wordsPerLine,row); + String[] displayed = new String[0]; + try { + displayed = getDisplayLines(eachWord,wordsPerLine,row); + } catch (ExceedRangeException e) { + e.printStackTrace(); + } displayedLines.add(displayed); ui.printLine(displayed); diff --git a/src/test/java/seedu/UtilsTest.java b/src/test/java/seedu/UtilsTest.java index f793054346..86d2a6f752 100644 --- a/src/test/java/seedu/UtilsTest.java +++ b/src/test/java/seedu/UtilsTest.java @@ -1,6 +1,7 @@ package seedu; import org.junit.jupiter.api.Test; +import seedu.typists.exception.ExceedRangeException; import java.util.ArrayList; import java.util.Arrays; @@ -25,7 +26,7 @@ public void splitStringIntoWordList_sampleTxt_success() { } @Test - public void getDisplayLines_inRange_success() { + public void getDisplayLines_inRange_success() throws ExceedRangeException { String[] displayed = getDisplayLines(places, 3, 3); String[] result = { "is1", "test1", "text1"}; for (int i = 0; i < displayed.length; i++) { @@ -34,7 +35,7 @@ public void getDisplayLines_inRange_success() { } @Test - public void getDisplayLines_outRange_success() { + public void getDisplayLines_outRange_success() throws ExceedRangeException { String[] displayed = getDisplayLines(places, 6, 2); String[] result = { "is1", "test1", "text1", "here1"}; for (int i = 0; i < displayed.length; i++) { diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index db4cf0105f..bba842da2f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -10,8 +10,7 @@ | Brought to you by -- AY2122S1-CS2113-T13-4. | Manual: | content: set the content - | word: start a new word game - | time: start a new timer game <-t> to specify time <-sn> to start immediately + | game: start a new game | history: view past game records | clear: clear all game records | bye: exit typist From 63eb6d845b070ce93c40a95de18ca7c4078d4ece Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 29 Oct 2021 02:51:35 +0800 Subject: [PATCH 167/272] Update Utils.java --- src/main/java/seedu/typists/common/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index f364c721d2..9cba2bbb47 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -37,7 +37,7 @@ public static String[] getDisplayLines(ArrayList wordLists, int wordsPer } catch (IndexOutOfBoundsException e) { throw new ExceedRangeException(); } - + //remove null elements line = Arrays.stream(line) .filter(s -> (s != null && s.length() > 0)) From 7ba7d8ccf4a908aa233456bcb237b2d94d03e515 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 09:50:58 +0800 Subject: [PATCH 168/272] add time game sequence diagram --- docs/DeveloperGuide.md | 2 +- docs/uml/Style.puml | 1 + docs/uml/TimeLimitGame.puml | 65 +++++++++++++++++++++++++++++++++++++ seedu.typists.ui.TextUi.log | 2 +- src/META-INF/MANIFEST.MF | 3 ++ time-limited_records.txt | 12 ------- word-limited_records.txt | 2 -- 7 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 docs/uml/Style.puml create mode 100644 docs/uml/TimeLimitGame.puml create mode 100644 src/META-INF/MANIFEST.MF diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e51d6b8cd7..5327358f2c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -10,7 +10,7 @@ {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} * https://www.baeldung.com/java-testing-system-out-println -##Architecture +## Architecture (Some architecture diagram) diff --git a/docs/uml/Style.puml b/docs/uml/Style.puml new file mode 100644 index 0000000000..7df6dd88fa --- /dev/null +++ b/docs/uml/Style.puml @@ -0,0 +1 @@ +!define LOGIC_COLOR #3333C4 diff --git a/docs/uml/TimeLimitGame.puml b/docs/uml/TimeLimitGame.puml new file mode 100644 index 0000000000..009f30efb1 --- /dev/null +++ b/docs/uml/TimeLimitGame.puml @@ -0,0 +1,65 @@ +@startuml +!include Style.puml + +participant ":GameCommand" as command +participant "game:TimeModeGame" as game +participant "ui:GameUi" as ui +participant ":Util" as util + +-> command: run() +activate command + +create game +command -> game: createGame(...) +activate game +game -> util: splitStringIntoWordList(content) +activate util +util --> game: wordList +deactivate +game --> command: game +deactivate + +command -> game: runGame(); +activate game +game -> game: isReady(startNow) +activate game +game --> game: ready +deactivate +loop until TimeOver + alt Time Over + else + game -> util: getDisplayLines(wordList); + activate util + util --> game: display + deactivate + game -> ui: printLine(display) + activate ui + ui --> game + deactivate + end +end +game -> game: updateUserLines(userinput)) +activate game +game --> game +deactivate + +game --> command +deactivate + +command -> game: gameSummary() +activate game +game -> game: handleSummary(...,"Time-Limited") +activate game +game --> game: summary +deactivate +game -> game: handleStorage(summary) +activate game +game --> game +deactivate + +game --> command +deactivate +destroy game + + +@enduml \ No newline at end of file diff --git a/seedu.typists.ui.TextUi.log b/seedu.typists.ui.TextUi.log index dc4af883a7..493ac413b0 100644 --- a/seedu.typists.ui.TextUi.log +++ b/seedu.typists.ui.TextUi.log @@ -1,2 +1,2 @@ -Oct 28, 2021 3:08:47 AM seedu.typists.ui.SummaryUi setUpLog +Oct 28, 2021 12:10:42 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..bd3a68a258 --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: seedu.typists.Main + diff --git a/time-limited_records.txt b/time-limited_records.txt index 2a368dc8e6..e69de29bb2 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,12 +0,0 @@ -Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] -Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] -Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] -Time-limited|43.279|3|27|30|10.0|90.0|37.43154878809584|[salutation, language., salutation] -Time-limited|32.197|70|0|70|100.0|0.0|0.0|[IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV, JNBCFmK, SkaqR, wprOgJPRupQcQk, fCPjET, LBioiTKLO, UrUOrpZlyw, DioaqLva, nJcBVYrWf, EJfVzPipYIZLX, djiaicC, IuFcUUkKAd, caTzefb, KEQZczuUePDrP, jRNdf, KIzMp, xWRJHeCfXFyqcD, dRlhRklAoYEVDH, PmXegHtA, BufKD, JrUUsV] -Time-limited|30.176|20|20|40|50.0|50.0|39.76670201484624|[simply, printing, typesetting, typesetting, industry, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy, dummy] -Time-limited|37.245|3|27|30|10.0|90.0|43.49577124446235|[uncut, hair, grew] -Time-limited|30.143|2|28|30|6.666666666666667|93.33333333333333|55.734333012639745|[balloon, grew] -Time-limited|30.2|8|22|30|26.666666666666668|73.33333333333333|43.70860927152318|[fleshy, balloon, of, hair, and, the, that, grew] -Time-limited|36.219|7|23|30|23.333333333333332|76.66666666666667|38.10154891079268|[ipum, dummy, dummy, dummy, dummy, dummy, dummy] diff --git a/word-limited_records.txt b/word-limited_records.txt index 05740c23b8..e69de29bb2 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,2 +0,0 @@ -Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] -Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] From 6f2ab04089fb73170885dbcae7ad23385af42685 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 12:27:09 +0800 Subject: [PATCH 169/272] udpate DG --- docs/DeveloperGuide.md | 18 ++++++++++++------ docs/uml/TimeLimitGame.puml | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 5327358f2c..8de8a74cd5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,20 +1,27 @@ # Developer Guide * [Acknowledgements](#acknowledgements) -* [Design & Implementation](#design-&-implementation) - -* [Acknoledgements](#acknowledgements) +* [Design](#design) + * [Architecture](#architecture) +* [Implementation](#implementation) +* [Product Scope](#product-scope) +* [User Stories](#user-stories) +* [Non-functional Requirements](#non-functional-requirements) +* [Glossary](#glossary) ## Acknowledgements {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} * https://www.baeldung.com/java-testing-system-out-println -## Architecture + + +## Design +### Architecture (Some architecture diagram) -## Design & implementation +## Implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} @@ -85,7 +92,6 @@ Single Responsibility Principle. ## Product scope - Our product is a typing game, intent to provide enjoyment for people who are familiar with the CML. diff --git a/docs/uml/TimeLimitGame.puml b/docs/uml/TimeLimitGame.puml index 009f30efb1..7aba96e6a1 100644 --- a/docs/uml/TimeLimitGame.puml +++ b/docs/uml/TimeLimitGame.puml @@ -59,7 +59,7 @@ deactivate game --> command deactivate -destroy game +destroy game @enduml \ No newline at end of file From 7d40d1fae4074b63582891d6a987b01bb92bb6d2 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 16:35:49 +0800 Subject: [PATCH 170/272] fix display line problem for time game --- .../seedu/typists/command/GameCommand.java | 3 + src/main/java/seedu/typists/common/Utils.java | 64 +++++++++++++------ .../java/seedu/typists/game/ErrorGame.java | 5 ++ src/main/java/seedu/typists/game/Game.java | 4 ++ .../java/seedu/typists/game/TimeModeGame.java | 34 ++++++---- .../seedu/typists/game/WordLimitGame.java | 28 ++++---- src/main/java/seedu/typists/ui/GameUi.java | 7 ++ time-limited_records.txt | 7 +- 8 files changed, 104 insertions(+), 48 deletions(-) diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java index 0473e6c34d..ea6d6bd1db 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -5,6 +5,7 @@ import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; import seedu.typists.game.WordLimitGame; +import seedu.typists.ui.GameUi; import java.util.ArrayList; @@ -31,6 +32,8 @@ public void run(ArrayList args) { System.out.println("Please specify game type."); } catch (NullPointerException e) { //exit + } catch (StackOverflowError e) { + new GameUi().printResetContent(LINE_LENGTH); } } diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 9cba2bbb47..f746018e1f 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -19,14 +19,55 @@ public static ArrayList splitStringIntoWordList(String line) { return new ArrayList<>(Arrays.asList(line.split(" "))); } + /** group the word list into groups of x, where x is the number of words per line. */ + public static ArrayList getWordLines(String text, int lineLength) { + ArrayList wordList = splitStringIntoWordList(text); + ArrayList wordLines = new ArrayList<>(); + int j = 0; + String[] line = new String[lineLength]; + for (String w : wordList) { + if (j == lineLength - 1) { + line[j] = w; + wordLines.add(line.clone()); + j = 0; + } else { + line[j] = w; + j++; + } + } + return wordLines; + } - /** get one line that is supposed to be displayed at one time of game. **/ + /** + * get one line that is supposed to be displayed at one time of game. + * + * @param wordLists content in the form of arraylist of words + * @param wordsPerLine number of words to be displayed + * @param row current row in the content + **/ public static String[] getDisplayLines(ArrayList wordLists, int wordsPerLine, int row) throws ExceedRangeException { int startIndex = (row - 1) * wordsPerLine; assert startIndex >= 0 : "word index should be non-negative"; String[] line = new String[wordsPerLine]; + try { + for (int i = 0; i < wordsPerLine; i++) { + line[i] = wordLists.get(startIndex + i); + } + } catch (IndexOutOfBoundsException e) { + throw new ExceedRangeException(); + } + return line; + } + + /** same as getDisplayLines but added remove null feature **/ + public static String[] getDisplayLinesWithoutNull(ArrayList wordLists, int wordsPerLine, int row) + throws ExceedRangeException { + int startIndex = (row - 1) * wordsPerLine; + assert startIndex >= 0 : "word index should be non-negative"; + String[] line = new String[wordsPerLine]; + try { for (int i = 0; i < wordsPerLine; i++) { if (startIndex + i > wordLists.size() - 1) { @@ -37,7 +78,7 @@ public static String[] getDisplayLines(ArrayList wordLists, int wordsPer } catch (IndexOutOfBoundsException e) { throw new ExceedRangeException(); } - + //remove null elements line = Arrays.stream(line) .filter(s -> (s != null && s.length() > 0)) @@ -45,25 +86,6 @@ public static String[] getDisplayLines(ArrayList wordLists, int wordsPer return line; } - /** group the word list into groups of x, where x is the number of words per line. */ - public static ArrayList getWordLines(String text, int lineLength) { - ArrayList wordList = splitStringIntoWordList(text); - ArrayList wordLines = new ArrayList<>(); - int j = 0; - String[] line = new String[lineLength]; - for (String w : wordList) { - if (j == lineLength - 1) { - line[j] = w; - wordLines.add(line.clone()); - j = 0; - } else { - line[j] = w; - j++; - } - } - return wordLines; - } - /** same function as getWordLines, but the param is ArrayList not string. */ public static ArrayList getWordLineFromStringArray(List stringList) { ArrayList wordLines = new ArrayList<>(); diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java index d4e2fdeace..a21f0aee8f 100644 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -29,6 +29,11 @@ public boolean readyToStartGame() { return true; } + @Override + public void displayLines(int row) { + + } + public void runGame() { if (readyToStartGame()) { for (int i = 0; i < wordLines.size(); i++) { diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index 01c69f1ea2..a1bf57a3b5 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -1,5 +1,6 @@ package seedu.typists.game; +import seedu.typists.exception.ExceedRangeException; import seedu.typists.ui.GameUi; import seedu.typists.ui.SummaryUi; import seedu.typists.ui.TextUi; @@ -26,6 +27,9 @@ public double getDuration(long startTime, long endTime) { return (double) (endTime - startTime) / 1000; } + + public abstract void displayLines(int row); + public abstract void runGame(); public abstract void gameSummary(); diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 1f767392ab..55af2272e1 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -8,26 +8,26 @@ import java.util.Scanner; import static seedu.typists.common.Messages.MESSAGE_TIME_GAME_END; -import static seedu.typists.common.Utils.getWordLineFromStringArray; -import static seedu.typists.common.Utils.splitStringIntoWordList; import static seedu.typists.common.Utils.getDisplayLines; +import static seedu.typists.common.Utils.splitStringIntoWordList; +import static seedu.typists.common.Utils.getWordLineFromStringArray; public class TimeModeGame extends Game { - protected String targetWordSet; protected final int timeInSeconds; protected final ArrayList wordLists; + protected final boolean isReady; protected int wordsPerLine; protected double gameTime; - protected final boolean isReady; + protected int currentRow; public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean isReady) { super(); - this.targetWordSet = targetWordSet; assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); this.timeInSeconds = timeInSeconds; this.wordsPerLine = wordsPerLine; this.isReady = isReady; + this.currentRow = 1; } public boolean getReady(boolean isReady) { @@ -37,12 +37,24 @@ public boolean getReady(boolean isReady) { return true; } + + @Override + public void displayLines(int row) { + try { + String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); + ui.printLine(display); + displayedLines.add(display); + } catch (ExceedRangeException e) { + currentRow = 1; + displayLines(currentRow); + } + } + public void runGame() { Scanner in = new Scanner(System.in); List inputs = new ArrayList<>(); if (getReady(isReady)) { - int currentRow = 1; long beginTime = getTimeNow(); boolean timeOver = false; @@ -52,14 +64,8 @@ public void runGame() { gameTime = (double) currTime / 1000; timeOver = true; } else { - try { - String[] display = getDisplayLines(wordLists, wordsPerLine, currentRow); - ui.printLine(display); - displayedLines.add(display); - inputs.add(in.nextLine()); - } catch (ExceedRangeException e) { - currentRow = 0; - } + displayLines(currentRow); + inputs.add(in.nextLine()); currentRow++; } } diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index a29d83b471..ab0d547ef7 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.Scanner; -import static seedu.typists.common.Utils.getDisplayLines; +import static seedu.typists.common.Utils.getDisplayLinesWithoutNull; import static seedu.typists.common.Utils.getWordLineFromStringArray; import static seedu.typists.parser.StringParser.splitString; @@ -31,6 +31,19 @@ public WordLimitGame(String targetWordSet, int wordsPerLine) { this.wordLimit = getWordLimit(); } + + @Override + public void displayLines(int row) { + String[] displayed = new String[0]; + try { + displayed = getDisplayLinesWithoutNull(eachWord,wordsPerLine,row); + } catch (ExceedRangeException e) { + e.printStackTrace(); + } + displayedLines.add(displayed); + ui.printLine(displayed); + } + @Override public void runGame() { game(); @@ -74,14 +87,7 @@ public void game() { boolean isExit = false; while (!isExit) { row++; - String[] displayed = new String[0]; - try { - displayed = getDisplayLines(eachWord,wordsPerLine,row); - } catch (ExceedRangeException e) { - e.printStackTrace(); - } - displayedLines.add(displayed); - ui.printLine(displayed); + displayLines(row); //read user input String fullCommand = ui.readCommand(); @@ -100,8 +106,8 @@ public void game() { } public void gameSummary() { - double realGameTime = getDuration(beginTime, getTimeNow()); - HashMap summary = handleSummary(displayedLines, userLines, realGameTime, "Word-limited"); + gameTime = getDuration(beginTime, getTimeNow()); + HashMap summary = handleSummary(displayedLines, userLines, gameTime, "Word-limited"); handleStorage(summary); } diff --git a/src/main/java/seedu/typists/ui/GameUi.java b/src/main/java/seedu/typists/ui/GameUi.java index 3a6a3ed3ec..5fda06b979 100644 --- a/src/main/java/seedu/typists/ui/GameUi.java +++ b/src/main/java/seedu/typists/ui/GameUi.java @@ -31,4 +31,11 @@ public void printGameMode1Progress(int a, int b) throws InterruptedException { viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } + public void printResetContent(int n) { + printScreen( + "Please reset your content to more than " + + n + " words." + ); + } + } diff --git a/time-limited_records.txt b/time-limited_records.txt index 5cf8143b33..4dc2e5769b 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,6 +1,9 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] +Time-limited|32.909|3|15|18|16.666666666666664|83.33333333333334|27.348141845695707|[salutation, from, 1826.] +Time-limited|30.193|10|20|30|33.33333333333333|66.66666666666666|39.744311595402905|[English, language., Hello, salutation, the, English, language., Hello, English, language.] +Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] From 4993646c0d2209be56f80db20f3470f9aa1eaf3e Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 19:37:50 +0800 Subject: [PATCH 171/272] change error msg for timemode command --- .gitignore | 1 + src/main/java/seedu/typists/command/GameCommand.java | 4 ++-- time-limited_records.txt | 8 ++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 45f2d19a29..ce21e7dfce 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ time-limited_records.txt seedu.typists.ui.TextUi.log seedu.typists.ui.TextUi.log.1 seedu.typists.ui.TextUi.log.lck +time-limited_records.txt diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java index ea6d6bd1db..d14fa0acb5 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -66,13 +66,13 @@ public TimeModeGame createTimeLimitGame(ArrayList args, boolean isReady, } catch (InvalidCommandException e) { System.out.println( "Please enter time in multiple of 30 seconds.\n" - + "e.g. time -t 30 " + + "e.g. game -t 30 " ); } catch (IncompleteCommandException | IndexOutOfBoundsException e) { System.out.println( "Please specify duration of the game using " + TIME_SIGNIFIER + "\n" - + "e.g. time -t 60 " + + "e.g. game -t 60 " ); } catch (NumberFormatException e) { System.out.println("Duration should be a number"); diff --git a/time-limited_records.txt b/time-limited_records.txt index 4dc2e5769b..f81ca1c713 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,9 +1,17 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] +<<<<<<< Updated upstream Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] Time-limited|32.909|3|15|18|16.666666666666664|83.33333333333334|27.348141845695707|[salutation, from, 1826.] Time-limited|30.193|10|20|30|33.33333333333333|66.66666666666666|39.744311595402905|[English, language., Hello, salutation, the, English, language., Hello, English, language.] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] +======= +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] +Time-limited|33.079|7|23|30|23.333333333333332|76.66666666666667|41.71831071072281|[typesetting, dummy, dummy, dummy, dummy, dummy, dummy] +Time-limited|36.098|5|25|30|16.666666666666664|83.33333333333334|41.55354867305668|[Ishmael., nothing, particular, interest, shore,] +>>>>>>> Stashed changes From be720dbc445e8bca87d5a76245d182f90f93b8df Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 19:44:44 +0800 Subject: [PATCH 172/272] add gitignore --- .gitignore | 3 +++ time-limited_records.txt | 15 ++------------- word-limited_records.txt | 16 +++++++++++----- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index ce21e7dfce..fc4f1a4154 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ seedu.typists.ui.TextUi.log seedu.typists.ui.TextUi.log.1 seedu.typists.ui.TextUi.log.lck time-limited_records.txt +time-limited_records.txt +word-limited_records.txt +word-limited_records.txt diff --git a/time-limited_records.txt b/time-limited_records.txt index f81ca1c713..5cf8143b33 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,17 +1,6 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -<<<<<<< Updated upstream -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] -Time-limited|32.909|3|15|18|16.666666666666664|83.33333333333334|27.348141845695707|[salutation, from, 1826.] -Time-limited|30.193|10|20|30|33.33333333333333|66.66666666666666|39.744311595402905|[English, language., Hello, salutation, the, English, language., Hello, English, language.] -Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] -======= -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] -Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] -Time-limited|33.079|7|23|30|23.333333333333332|76.66666666666667|41.71831071072281|[typesetting, dummy, dummy, dummy, dummy, dummy, dummy] -Time-limited|36.098|5|25|30|16.666666666666664|83.33333333333334|41.55354867305668|[Ishmael., nothing, particular, interest, shore,] ->>>>>>> Stashed changes diff --git a/word-limited_records.txt b/word-limited_records.txt index c72a6f8dc4..b86e9ab19d 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,11 +1,17 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] +Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] +Word-limited|10.073|0|5|5|0.0|100.0|29.782587114067308|[] +Word-limited|16.059|1|10|11|9.090909090909092|90.9090909090909|37.36222678871661|[typesetting] +Word-limited|16.059|1|10|11|9.090909090909092|90.9090909090909|37.36222678871661|[typesetting] +Word-limited|16.039|0|10|10|0.0|100.0|37.40881601097325|[] +Word-limited|16.039|0|10|10|0.0|100.0|37.40881601097325|[] From 7f7ea0e477b9749bfc3f4bb269d2a6de572455e8 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 19:49:30 +0800 Subject: [PATCH 173/272] update checkstyle --- src/main/java/seedu/typists/common/Utils.java | 2 +- src/test/java/seedu/UtilsTest.java | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index f746018e1f..d0a705b3e1 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -61,7 +61,7 @@ public static String[] getDisplayLines(ArrayList wordLists, int wordsPer return line; } - /** same as getDisplayLines but added remove null feature **/ + /** same as getDisplayLines but added remove null feature. **/ public static String[] getDisplayLinesWithoutNull(ArrayList wordLists, int wordsPerLine, int row) throws ExceedRangeException { int startIndex = (row - 1) * wordsPerLine; diff --git a/src/test/java/seedu/UtilsTest.java b/src/test/java/seedu/UtilsTest.java index 86d2a6f752..cc18e2f98c 100644 --- a/src/test/java/seedu/UtilsTest.java +++ b/src/test/java/seedu/UtilsTest.java @@ -7,9 +7,8 @@ import java.util.Arrays; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.typists.common.Utils.getDisplayLines; import static seedu.typists.common.Utils.splitStringIntoWordList; +import static seedu.typists.common.Utils.getDisplayLinesWithoutNull; public class UtilsTest { private static final String SAMPLE = "this is test text here"; @@ -27,7 +26,7 @@ public void splitStringIntoWordList_sampleTxt_success() { @Test public void getDisplayLines_inRange_success() throws ExceedRangeException { - String[] displayed = getDisplayLines(places, 3, 3); + String[] displayed = getDisplayLinesWithoutNull(places, 3, 3); String[] result = { "is1", "test1", "text1"}; for (int i = 0; i < displayed.length; i++) { assertEquals(displayed[i], result[i]); @@ -36,7 +35,7 @@ public void getDisplayLines_inRange_success() throws ExceedRangeException { @Test public void getDisplayLines_outRange_success() throws ExceedRangeException { - String[] displayed = getDisplayLines(places, 6, 2); + String[] displayed = getDisplayLinesWithoutNull(places, 6, 2); String[] result = { "is1", "test1", "text1", "here1"}; for (int i = 0; i < displayed.length; i++) { assertEquals(displayed[i], result[i]); From 26cda9e41bdf25e618d1b6f8b4234e484228bab8 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 19:56:28 +0800 Subject: [PATCH 174/272] update sample txt --- .../java/seedu/typists/common/Messages.java | 21 +++++++------------ time-limited_records.txt | 5 +++-- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 794468692a..7d5f104916 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -78,17 +78,12 @@ public class Messages { public static String MESSAGE_TIME_GAME_END = "Timer's UP!"; //This sample text is gotten from https://www.lipsum.com/ - public static final String SAMPLE_TEXT = "lorem ipsum is simply dummy text of the printing and typesetting " - + "imply dummy text of the printing and typesetting industry ipum is simply dummy " - + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " - + "dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry " - + "industry industry industry industry industry industry industry industry industry industry industry "; + public static final String SAMPLE_TEXT = + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. " + + "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, " + + "when an unknown printer took a galley of type and scrambled it to make a type specimen book. " + + "It has survived not only five centuries, but also the leap into electronic typesetting, " + + "remaining essentially unchanged. It was popularised in the 1960s with the release of " + + "Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing" + + " software like Aldus PageMaker including versions of Lorem Ipsum."; } diff --git a/time-limited_records.txt b/time-limited_records.txt index 5cf8143b33..8eba4c3c6a 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,6 +1,7 @@ Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] +Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] +Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] +Time-limited|36.229|6|24|30|20.0|80.0|39.74716387424439|[and, typesetting, Lorem, industry's, standard, text] From 8038571a307de40342bcae29b3e13d85f75cb669 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Fri, 29 Oct 2021 20:36:36 +0800 Subject: [PATCH 175/272] Improve on word limit game -remove repeated summary -remove display text at beginning -updated UG --- docs/UserGuide.md | 26 ++++++++++++------- .../seedu/typists/game/WordLimitGame.java | 22 +++++----------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 646cca513a..fc7511a2b1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -38,15 +38,18 @@ e.g. `history -g time -h -n 10` will be interpreted as `history -h`. ### Usage ### Open Game -### {Feature name}: {`Keyword`} -Description of feature -Format: {format of command} -* Explanation 1 of format -* Explanation 2 of format - +### Set Content: `content` +Set the typing content before the game. +Format: `content` `1-3` `[optional]` + +After entering `content`, user can type an integer from 1-3 to choose from following: + +1. Opening of famous books +2. Wikipedia article +3. Random sentence of custom length + Examples -* command example 1 -* command example 2 +* `content` `1` `3` ### Open Game: `game` @@ -56,6 +59,9 @@ Format: `game GAME_MODE [-c]` * GAME_MODE * `-w` for game in Word Limit Mode * `-t` for game in Time Limit Mode +* For Word Limit Game: + * Format: `game -w [-c]` + * Exit: `Exit` allows user to terminate the current game. * For Time Limit Game: * Format: `game -t TIME_LIMIT [-sn] [-c]` * START_NOW `-sn` allows user to start the game immediately without the "ready to start?" prompt. @@ -107,7 +113,9 @@ List of the keywords are shown below: `content`-Set the content -`new`-Enter a word-limited game mode +`game -w`-Enter a word-limited game mode + +`game -w -c`-Enter a word-limited game mode with content setting >Exit word-limited game mode command: `Exit` diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index ab0d547ef7..dc183dc151 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -16,16 +16,15 @@ public class WordLimitGame extends Game { private ArrayList eachWord; protected ArrayList wordLines; protected int wordLimit; - private int gameIndex; private final int wordsPerLine; private final String content1; private long beginTime; + private String[] displayed; public WordLimitGame(String targetWordSet, int wordsPerLine) { super(); this.eachWord = new ArrayList<>(100); - this.gameIndex = 0; this.wordsPerLine = wordsPerLine; this.content1 = targetWordSet; this.wordLimit = getWordLimit(); @@ -34,22 +33,15 @@ public WordLimitGame(String targetWordSet, int wordsPerLine) { @Override public void displayLines(int row) { - String[] displayed = new String[0]; + displayed = new String[0]; try { displayed = getDisplayLinesWithoutNull(eachWord,wordsPerLine,row); } catch (ExceedRangeException e) { e.printStackTrace(); } - displayedLines.add(displayed); ui.printLine(displayed); } - @Override - public void runGame() { - game(); - gameSummary(); - } - public int getTotalSentence() { return eachWord.size(); } @@ -73,13 +65,9 @@ public void trimContent(int wordLimit) { e.printStackTrace(); } eachWord = new ArrayList<>(eachWord.subList(0, wordLimit)); - System.out.println("ori"); - for (String arr : eachWord) { - System.out.println(arr); - } } - public void game() { + public void runGame() { trimContent(wordLimit); beginTime = getTimeNow(); List inputs = new ArrayList<>(); @@ -87,13 +75,15 @@ public void game() { boolean isExit = false; while (!isExit) { row++; + //display a single line displayLines(row); - //read user input String fullCommand = ui.readCommand(); if (fullCommand.equals("Exit")) { break; } + //only add the line into displayedLines when the Command is not Exit + displayedLines.add(displayed); //update for summary inputs.add(fullCommand); From 30214d820254a3af788e2dc173919c0525bb7822 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 29 Oct 2021 20:46:03 +0800 Subject: [PATCH 176/272] update --- .../java/seedu/typists/game/WordLimitGame.java | 1 - time-limited_records.txt | 8 +------- word-limited_records.txt | 18 +++++++++++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index ab0d547ef7..459421f9c5 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -47,7 +47,6 @@ public void displayLines(int row) { @Override public void runGame() { game(); - gameSummary(); } public int getTotalSentence() { diff --git a/time-limited_records.txt b/time-limited_records.txt index 8eba4c3c6a..048e13f08f 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,7 +1 @@ -Word-limited|8.082|1|9|10|10.0|90.0|66.81514476614699|[dummy] -Word-limited|10.075|0|10|10|0.0|100.0|59.55334987593052|[] -Word-limited|11.066|1|9|10|10.0|90.0|48.79812036869691|[dummy] -Word-limited|10.052|2|8|10|20.0|80.0|47.751691205730204|[dummy, printing] -Time-limited|31.138|3|27|30|10.0|90.0|52.02646284282869|[typesetting, typesetting, industry] -Time-limited|31.34|0|70|70|0.0|100.0|134.01403956604977|[] -Time-limited|36.229|6|24|30|20.0|80.0|39.74716387424439|[and, typesetting, Lorem, industry's, standard, text] +Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] diff --git a/word-limited_records.txt b/word-limited_records.txt index b86e9ab19d..bf673b4479 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,12 +1,12 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] @@ -15,3 +15,11 @@ Word-limited|16.059|1|10|11|9.090909090909092|90.9090909090909|37.36222678871661 Word-limited|16.059|1|10|11|9.090909090909092|90.9090909090909|37.36222678871661|[typesetting] Word-limited|16.039|0|10|10|0.0|100.0|37.40881601097325|[] Word-limited|16.039|0|10|10|0.0|100.0|37.40881601097325|[] +Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] +Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] +Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] +Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s,, unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s,, unknown, printer, took] +Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] +Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] From 8670555cc82d03fa4214db33769794be30f95d91 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 1 Nov 2021 22:36:03 +0800 Subject: [PATCH 177/272] Address code review comment --- src/main/java/seedu/typists/game/SummaryManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/game/SummaryManager.java b/src/main/java/seedu/typists/game/SummaryManager.java index 049e610033..ea4c40aadd 100644 --- a/src/main/java/seedu/typists/game/SummaryManager.java +++ b/src/main/java/seedu/typists/game/SummaryManager.java @@ -58,7 +58,7 @@ private static ArrayList getErrorWords( int innerLoopCount = 0; for (String expectedWord : expectedLine) { - if (actualLine.size() == 0) { + if (actualLine.isEmpty()) { ArrayList remainingWords = new ArrayList<>( expectedLine.subList(innerLoopCount, expectedLine.size()) ); From 51d07efa947ce9c937e29faafe68969f59187871 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 1 Nov 2021 22:52:38 +0800 Subject: [PATCH 178/272] Add exception handling for non-positive integers user input in history command's number of game records argument. Fixes #122 --- src/main/java/seedu/typists/command/HistoryCommand.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/HistoryCommand.java index ff9d7b8f68..08be77f8da 100644 --- a/src/main/java/seedu/typists/command/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/HistoryCommand.java @@ -68,9 +68,14 @@ private void getNumberOfRecords() throws InvalidCommandException { try { totalNumberOfRecords = gameRecordsManager.getNumberOfGameRecords(gameMode); numberOfRecords = Integer.parseInt(args.get(indexNumberOfRecords + 1)); + if (numberOfRecords <= 0) { + throw new InvalidCommandException("Invalid argument for number of records option.\n" + + "Option only accepts positive integer values." + + "Input \"history -h\" for help\n"); + } } catch (NumberFormatException e) { throw new InvalidCommandException("Invalid argument for number of records option.\n" - + "Option only accepts integer values." + + "Option only accepts positive integer values." + "Input \"history -h\" for help\n"); } } From 19e7c36d79ce39964bd1b0631d3c0a0cc9a6bd33 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 1 Nov 2021 23:08:42 +0800 Subject: [PATCH 179/272] Add help display for history and clear command Fixes #102 Fixes #132 --- src/main/java/seedu/typists/ui/ClearCommandUi.java | 10 +++++++++- src/main/java/seedu/typists/ui/HistoryCommandUi.java | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/typists/ui/ClearCommandUi.java b/src/main/java/seedu/typists/ui/ClearCommandUi.java index 4fbb5aeab2..9e6e6e35cc 100644 --- a/src/main/java/seedu/typists/ui/ClearCommandUi.java +++ b/src/main/java/seedu/typists/ui/ClearCommandUi.java @@ -5,7 +5,15 @@ public class ClearCommandUi { public static void displayHelp() { - //update after finish UG + System.out.print("clear deletes all records for both games," + + " or either of the game types, depending on your choice.\n"); + System.out.print("The format of the command is 'clear [-g GAME_MODE]'\n"); + System.out.print("The arguments in the square brackets are optional." + + " If not inputted, the default is 'all' which means" + + "records from both the time- and word-limited will be cleared.\n"); + System.out.print("The possible values for GAME_MODE is 'all', 'time', and, 'word\n"); + System.out.print("'word' clears all game records for the word-limited mode\n" + + "'time' clears all game records for the time-limited mode.\n"); } public static void displaySuccess(String gameMode) { diff --git a/src/main/java/seedu/typists/ui/HistoryCommandUi.java b/src/main/java/seedu/typists/ui/HistoryCommandUi.java index 48a33a7f82..91aa60f303 100644 --- a/src/main/java/seedu/typists/ui/HistoryCommandUi.java +++ b/src/main/java/seedu/typists/ui/HistoryCommandUi.java @@ -28,6 +28,15 @@ public static void displayGameRecords(ArrayList gameRecords, int num public static void displayHelp() { //do after user guide - System.out.print("display help placeholder\n"); + System.out.print("history shows the game records for your past games.\n"); + System.out.print("The format of the command is 'history -g GAME_MODE [-n NUMBER_OF_RECORDS]'\n"); + System.out.print("Only the arguments in the square brackets are optional."); + System.out.print("GAME_MODE specifies which game mode records you want to view.\n" + + "The possible values for GAME_MODE are 'time' and 'word'\n"); + System.out.print("NUMBER_OF_RECORDS specifies the number of past records you want to view.\n" + + "Only positive integers are allowed.\n" + + "If not inputted, the default is the total number of game records " + + "you have for the selected game mode.\n"); + } } From 548c821bc85759588d48a3a8ce37ea832df5c15c Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 1 Nov 2021 23:18:56 +0800 Subject: [PATCH 180/272] Remove log of INFO level from terminal Fixes #118 --- src/main/java/seedu/typists/Main.java | 6 ++++++ src/main/java/seedu/typists/storage/Storage.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index 1f41bcbe38..e1e43f88f5 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -3,6 +3,7 @@ import seedu.typists.content.Content; import seedu.typists.command.Command; import seedu.typists.command.CommandFactory; +import seedu.typists.ui.SummaryUi; import seedu.typists.ui.TextUi; import seedu.typists.storage.Storage; @@ -52,11 +53,16 @@ public void runCommandLoop() { } while (!command.equals("bye")); } + private void setUpLogs() { + SummaryUi.setUpLog(); + Storage.setUpLog(); + } /** * Runs the program until termination. */ public void run() { + setUpLogs(); start(); runCommandLoop(); } diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java index 68f89065f2..417f35d6a3 100644 --- a/src/main/java/seedu/typists/storage/Storage.java +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -116,7 +116,7 @@ private static String getFileName(String gameMode) { } - private static void setUpLog() { + public static void setUpLog() { LogManager.getLogManager().reset(); LOGGER.setLevel(Level.ALL); From f02b89869eae8544a317de34796f51108ed0da70 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 1 Nov 2021 23:29:11 +0800 Subject: [PATCH 181/272] Edit start screen to make usage of clear and history commands clearer. Editted message such that gamers will know the command syntax for history and clear command Delete old showSummary() method --- .../java/seedu/typists/common/Messages.java | 4 ++-- src/main/java/seedu/typists/ui/TextUi.java | 18 ------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 794468692a..44ead18604 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -71,8 +71,8 @@ public class Messages { public static final String MESSAGE_HELP = "Manual:\n" + "content: set the content\n" + "game: start a new game\n" - + "history: view past game records\n" - + "clear: clear all game records\n" + + "history -g GAME_MODE [-n NUMBER_OF_RECORDS]: view past game records\n" + + "clear [-g GAME_MODE]: clear all game records\n" + "bye: exit typist"; public static String MESSAGE_TIME_GAME_END = "Timer's UP!"; diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index e7c494acec..ea9332cf60 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -168,24 +168,6 @@ public void showAnimatedError(ArrayList content, ui.showAnimatedSentenceErrorRateSummary(rounded); } - - /*public void showSummary(int errorWordCount, double errorPercentage, List errorWords, double wpm, - int totalWordTyped, double gameTime) { - assert errorWordCount >= 0; - assert errorPercentage >= 0; - assert totalWordTyped >= 0; - assert gameTime > 0; - assert wpm >= 0; - - out.print(SUMMARY + '\n'); - out.print("Number of Wrong Words: " + errorWordCount + "/" + totalWordTyped + '\n'); - out.print("Error Percentage of Wrong Words: " + String.format("%.2f", errorPercentage) + "%\n"); - out.print("Wrong Words:\n"); - printErrorWords(errorWords); - out.print("WPM: " + String.format("%.2f", wpm) + '\n'); - out.print("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds\n"); - }*/ - public void showAnimatedSummary(int errorWordCount, double errorPercentage, double wpm, int totalWordTyped, double gameTime) throws InterruptedException { out.print(SUMMARY + '\n'); From e3fc4541a03dd8acc0d0f259be8fe5466742979d Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Mon, 1 Nov 2021 23:38:14 +0800 Subject: [PATCH 182/272] Edit format of user error messages for clear and history command. --- src/main/java/seedu/typists/command/ClearCommand.java | 2 +- .../java/seedu/typists/command/HistoryCommand.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/typists/command/ClearCommand.java b/src/main/java/seedu/typists/command/ClearCommand.java index 580edabbce..3f47153df1 100644 --- a/src/main/java/seedu/typists/command/ClearCommand.java +++ b/src/main/java/seedu/typists/command/ClearCommand.java @@ -62,7 +62,7 @@ private void getGameMode() throws InvalidCommandException { } if (!gameMode.equals("time") && !gameMode.equals("word") && !gameMode.equals("all")) { throw new InvalidCommandException("Invalid argument for game mode option.\n" - + "Input \"history -h\" for help\n"); + + "Input \"clear -h\" for help.\n"); } else { if (gameMode.equals("all")) { gameMode = "all"; diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/HistoryCommand.java index 08be77f8da..45168c590b 100644 --- a/src/main/java/seedu/typists/command/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/HistoryCommand.java @@ -71,12 +71,12 @@ private void getNumberOfRecords() throws InvalidCommandException { if (numberOfRecords <= 0) { throw new InvalidCommandException("Invalid argument for number of records option.\n" + "Option only accepts positive integer values." - + "Input \"history -h\" for help\n"); + + "Input \"history -h\" for help.\n"); } } catch (NumberFormatException e) { throw new InvalidCommandException("Invalid argument for number of records option.\n" - + "Option only accepts positive integer values." - + "Input \"history -h\" for help\n"); + + "Option only accepts positive integer values.\n" + + "Input \"history -h\" for help.\n"); } } @@ -86,7 +86,7 @@ private void getGameMode() throws InvalidCommandException { int indexGameMode = args.indexOf("-" + GAME_MODE_OPTION); if (indexGameMode == -1) { throw new InvalidCommandException("Invalid command.\n" - + "Input \"history -h\" for help\n"); + + "Input \"history -h\" for help.\n"); } else { if (args.size() < indexGameMode + 2) { throw new InvalidCommandException("Missing argument for game mode option.\n"); @@ -96,7 +96,7 @@ private void getGameMode() throws InvalidCommandException { } if (!gameMode.equals("time") && !gameMode.equals("word")) { throw new InvalidCommandException("Invalid argument for game mode option.\n" - + "Input \"history -h\" for help\n"); + + "Input \"history -h\" for help.\n"); } else { gameMode = gameMode.substring(0, 1).toUpperCase() + gameMode.substring(1) + "-limited"; } From 64db1875c0c310ee9ffd745ea0312df547593849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:49:40 +0800 Subject: [PATCH 183/272] Update CommandFactory.java --- src/main/java/seedu/typists/command/CommandFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 1805399094..af89123b73 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -13,6 +13,8 @@ public Command getCommand(String commandType) { return new WordGameCommand(); case "content": return new ContentCommand(); + case "error": + return new ErrorCommand(); case "bye": return new ExitCommand(); default: From 89dd878a4b6222031c205f5f634466aa3d80e771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:50:53 +0800 Subject: [PATCH 184/272] Update TextUi.java --- src/main/java/seedu/typists/ui/TextUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index e23d0c004f..e2f075c506 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -101,7 +101,7 @@ public void showBye() { } public void printGameMode1Progress(int a, int b) throws InterruptedException { - printLine("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); + viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } public void printKeyboard() { From 2d14673e6274b9243d93d6bfb5196b5ee8b5b44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:51:25 +0800 Subject: [PATCH 185/272] Update TextUi.java --- src/main/java/seedu/typists/ui/TextUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index e2f075c506..0239e3d5c2 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -101,7 +101,7 @@ public void showBye() { } public void printGameMode1Progress(int a, int b) throws InterruptedException { - viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); + viewAnimateLeft("Your progress:" + String.valueOf(a) + "/" + String.valueOf(b)); } public void printKeyboard() { From 672bc569e5313ef713d2194864a4d135025c61f1 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:52:35 +0800 Subject: [PATCH 186/272] advad --- .../java/seedu/typists/game/ErrorGame.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/seedu/typists/game/ErrorGame.java diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java new file mode 100644 index 0000000000..d34e07e72c --- /dev/null +++ b/src/main/java/seedu/typists/game/ErrorGame.java @@ -0,0 +1,46 @@ +package seedu.typists.game; + +import seedu.typists.ui.TextUi; +import java.util.ArrayList; +import java.util.Scanner; + +import static seedu.typists.common.Utils.getWordLines; + +public class ErrorGame extends Game { + private final TextUi ui; + + protected ArrayList inputLines; + protected final ArrayList wordLines; + + public ErrorGame(String targetWordSet, int wordsPerLine) { + ui = new TextUi(); + inputLines = new ArrayList<>(); + wordLines = getWordLines(targetWordSet, wordsPerLine); + runGame(); + } + + public boolean readyToStartGame() { + Scanner in = new Scanner(System.in); + String command = ""; + while (!command.equals("yes")) { + ui.printScreen("Do you want to start now?"); + command = in.nextLine(); + } + return true; + } + + public void runGame() { + if (readyToStartGame()) { + for (int i = 0; i < wordLines.size(); i++) { + ui.printLine(wordLines.get(i)); + } + } + Scanner in = new Scanner(System.in); + for (int i = 0; i < wordLines.size(); i++) { + String userInput = in.nextLine(); + inputLines.add(userInput); + i++; + } + System.out.println("Game Finished."); + } +} \ No newline at end of file From d7a84e83f435b331604f9b8a61e837eae85af1a9 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:55:59 +0800 Subject: [PATCH 187/272] delete error --- .../seedu/typists/command/CommandFactory.java | 2 - .../java/seedu/typists/game/ErrorGame.java | 56 ------------------- 2 files changed, 58 deletions(-) delete mode 100644 src/main/java/seedu/typists/game/ErrorGame.java diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index f0643dc2d1..3ecc3af3c2 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -11,8 +11,6 @@ public Command getCommand(String commandType) { return new GameCommand(); case "content": return new ContentCommand(); - case "error": - return new ErrorCommand(); case "history": return new HistoryCommand(); case "clear": diff --git a/src/main/java/seedu/typists/game/ErrorGame.java b/src/main/java/seedu/typists/game/ErrorGame.java deleted file mode 100644 index a21f0aee8f..0000000000 --- a/src/main/java/seedu/typists/game/ErrorGame.java +++ /dev/null @@ -1,56 +0,0 @@ -package seedu.typists.game; - -import seedu.typists.ui.TextUi; -import java.util.ArrayList; -import java.util.Scanner; - -import static seedu.typists.common.Utils.getWordLines; - -public class ErrorGame extends Game { - private final TextUi ui; - - protected ArrayList inputLines; - protected final ArrayList wordLines; - - public ErrorGame(String targetWordSet, int wordsPerLine) { - ui = new TextUi(); - inputLines = new ArrayList<>(); - wordLines = getWordLines(targetWordSet, wordsPerLine); - runGame(); - } - - public boolean readyToStartGame() { - Scanner in = new Scanner(System.in); - String command = ""; - while (!command.equals("yes")) { - ui.printScreen("Do you want to start now?"); - command = in.nextLine(); - } - return true; - } - - @Override - public void displayLines(int row) { - - } - - public void runGame() { - if (readyToStartGame()) { - for (int i = 0; i < wordLines.size(); i++) { - ui.printLine(wordLines.get(i)); - } - } - Scanner in = new Scanner(System.in); - for (int i = 0; i < wordLines.size(); i++) { - String userInput = in.nextLine(); - inputLines.add(userInput); - i++; - } - System.out.println("Game Finished."); - } - - @Override - public void gameSummary() { - - } -} From 7a2e6f8cedba8580f22d06b6727dcd1c9be3210a Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 3 Nov 2021 20:32:08 +0800 Subject: [PATCH 188/272] Change application to not crash when record file is editted to an invalid format. Update user guide to fit the change in logic. Fixes #115 --- docs/UserGuide.md | 4 +- .../seedu/typists/storage/FileParser.java | 131 ++++++++++++------ .../java/seedu/typists/storage/Storage.java | 4 + 3 files changed, 93 insertions(+), 46 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index fc7511a2b1..11507a21e6 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -102,8 +102,8 @@ Typists automatically stores the updated game records into text files when gamer ### !Warning: Editing the data file Typists is a game application and only game records will be stored. Gamers should not edit the data it will manipulate the integrity of the records. -In the event where the data is editted and the wrong format is inputted, the game will crash when it tries to read the file. -The only way to make it run smoothly again is to delete the text files, hence losing all the game data. +In the event where the data is edited and the wrong format is inputted, the file contents will be cleared, +hence losing all the game data. diff --git a/src/main/java/seedu/typists/storage/FileParser.java b/src/main/java/seedu/typists/storage/FileParser.java index bf51fc10c1..56d673539c 100644 --- a/src/main/java/seedu/typists/storage/FileParser.java +++ b/src/main/java/seedu/typists/storage/FileParser.java @@ -8,69 +8,112 @@ public class FileParser { public static GameRecord convertStringToGameRecord(String gameRecordString) { - String[] gameRecordStats = gameRecordString.split("\\|"); - assert gameRecordStats.length >= 8; - String gameMode = getGameMode(gameRecordStats); - double timeElapsed = getTimeElapsed(gameRecordStats); - int errorWordCount = getErrorWordCount(gameRecordStats); - int correctWordCount = getCorrectWordCount(gameRecordStats); - int totalWordCount = getTotalWordCount(gameRecordStats); - double errorWordPercentage = getErrorWordPercentage(gameRecordStats); - double correctWordPercentage = getCorrectWordPercentage(gameRecordStats); - double wpm = getWpm(gameRecordStats); - ArrayList errorWords = getErrorWords(gameRecordStats); + try { + String[] gameRecordStats = gameRecordString.split("\\|"); + assert gameRecordStats.length >= 8; + String gameMode = getGameMode(gameRecordStats); + double timeElapsed = getTimeElapsed(gameRecordStats); + int errorWordCount = getErrorWordCount(gameRecordStats); + int correctWordCount = getCorrectWordCount(gameRecordStats); + int totalWordCount = getTotalWordCount(gameRecordStats); + double errorWordPercentage = getErrorWordPercentage(gameRecordStats); + double correctWordPercentage = getCorrectWordPercentage(gameRecordStats); + double wpm = getWpm(gameRecordStats); + ArrayList errorWords = getErrorWords(gameRecordStats); - GameRecord gameRecord = new GameRecord( - gameMode, - timeElapsed, - errorWordCount, - correctWordCount, - totalWordCount, - errorWordPercentage, - correctWordPercentage, - wpm, - errorWords - ); - return gameRecord; + GameRecord gameRecord = new GameRecord( + gameMode, + timeElapsed, + errorWordCount, + correctWordCount, + totalWordCount, + errorWordPercentage, + correctWordPercentage, + wpm, + errorWords + ); + return gameRecord; + } catch (Exception e) { + System.out.println("OOPS! Looks like you messed around with a record file.\n" + + "A brand new record file will be created!\n"); + return null; + } } - private static String getGameMode(String[] gameRecordStats) { - return gameRecordStats[0]; + private static String getGameMode(String[] gameRecordStats) throws Exception { + try { + return gameRecordStats[0]; + } catch (Exception e) { + throw new Exception(); + } } - private static double getTimeElapsed(String[] gameRecordStats) { - return Double.parseDouble(gameRecordStats[1]); + private static double getTimeElapsed(String[] gameRecordStats) throws Exception { + try { + return Double.parseDouble(gameRecordStats[1]); + } catch (Exception e) { + throw new Exception(); + } + } - private static int getErrorWordCount(String[] errorWordCountString) { - return Integer.parseInt(errorWordCountString[2]); + private static int getErrorWordCount(String[] errorWordCountString) throws Exception { + try { + return Integer.parseInt(errorWordCountString[2]); + } catch (Exception e) { + throw new Exception(); + } } - private static int getCorrectWordCount(String[] gameRecordStats) { - return Integer.parseInt(gameRecordStats[3]); + private static int getCorrectWordCount(String[] gameRecordStats) throws Exception { + try { + return Integer.parseInt(gameRecordStats[3]); + } catch (Exception e) { + throw new Exception(); + } } - private static int getTotalWordCount(String[] gameRecordStats) { - return Integer.parseInt(gameRecordStats[4]); + private static int getTotalWordCount(String[] gameRecordStats) throws Exception { + try { + return Integer.parseInt(gameRecordStats[4]); + } catch (Exception e) { + throw new Exception(); + } } - private static double getErrorWordPercentage(String[] gameRecordStats) { - return Double.parseDouble(gameRecordStats[5]); + private static double getErrorWordPercentage(String[] gameRecordStats) throws Exception { + try { + return Double.parseDouble(gameRecordStats[5]); + } catch (Exception e) { + throw new Exception(); + } } - private static double getCorrectWordPercentage(String[] gameRecordStats) { - return Double.parseDouble(gameRecordStats[6]); + private static double getCorrectWordPercentage(String[] gameRecordStats) throws Exception { + try { + return Double.parseDouble(gameRecordStats[6]); + } catch (Exception e) { + throw new Exception(); + } } - private static double getWpm(String[] wpmString) { - return Double.parseDouble(wpmString[7]); + private static double getWpm(String[] wpmString) throws Exception { + try { + return Double.parseDouble(wpmString[7]); + } catch (Exception e) { + throw new Exception(); + } } - private static ArrayList getErrorWords(String[] gameRecordStats) { - if (gameRecordStats[8].trim().equals("[]")) { - return new ArrayList<>(); + private static ArrayList getErrorWords(String[] gameRecordStats) throws Exception { + try { + if (gameRecordStats[8].trim().equals("[]")) { + return new ArrayList<>(); + } + String[] errorWords = gameRecordStats[8].substring(1, gameRecordStats[8].length() - 1).split(","); + return new ArrayList<>(Arrays.asList(errorWords)); + } catch (Exception e) { + throw new Exception(); } - String[] errorWords = gameRecordStats[8].substring(1, gameRecordStats[8].length() - 1).split(","); - return new ArrayList<>(Arrays.asList(errorWords)); } } diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java index 417f35d6a3..ce5f7525b3 100644 --- a/src/main/java/seedu/typists/storage/Storage.java +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -86,6 +86,10 @@ private static ArrayList convertToGameRecords(ArrayList game } else { for (String gameRecordString : gameRecordsStringArrayList) { GameRecord gameRecord = FileParser.convertStringToGameRecord(gameRecordString); + if (gameRecord == null) { + gameRecords = new ArrayList<>(); + return gameRecords; + } gameRecords.add(gameRecord); } return gameRecords; From 259c3ec97518c71edd3e3ebb9a1b72bdb03d943c Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Wed, 3 Nov 2021 20:49:04 +0800 Subject: [PATCH 189/272] Fix bug str1==str2 to str1.equals(str2) --- src/main/java/seedu/typists/storage/Storage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java index ce5f7525b3..dc532d4c69 100644 --- a/src/main/java/seedu/typists/storage/Storage.java +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -114,7 +114,7 @@ private static String convertGameRecordToString(GameRecord gameRecord) { private static String getFileName(String gameMode) { - assert ((gameMode == "Time-limited") || (gameMode == "Word-limited")); + assert ((gameMode.equals("Time-limited")) || (gameMode.equals("Word-limited"))); String filename = gameMode.toLowerCase(Locale.ROOT) + "_records.txt"; return filename; From d460dda37301fca0171f4543a8b1bd6f653e22d9 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 4 Nov 2021 00:01:34 +0800 Subject: [PATCH 190/272] move getReady method to superclass game --- .../seedu/typists/command/GameCommand.java | 8 ++-- src/main/java/seedu/typists/game/Game.java | 11 ++++- .../java/seedu/typists/game/TimeModeGame.java | 48 ++++++++++--------- .../seedu/typists/game/WordLimitGame.java | 3 +- src/main/java/seedu/typists/ui/GameUi.java | 7 ++- time-limited_records.txt | 6 ++- word-limited_records.txt | 19 +++++--- 7 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java index d14fa0acb5..bd8c2737f5 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -26,7 +26,7 @@ public void run(ArrayList args) { try { Game game = createGame(args, startNow, setContent); - game.runGame(); + game.run(); game.gameSummary(); } catch (IncompleteCommandException e) { System.out.println("Please specify game type."); @@ -42,18 +42,18 @@ public Game createGame(ArrayList args, boolean startNow, boolean setCont if (getBoolean(args, TIME_SIGNIFIER)) { return createTimeLimitGame(args,startNow, setContent); } else if (getBoolean(args, WORD_SIGNIFIER)) { - return createWordLimitGame(setContent); + return createWordLimitGame(startNow, setContent); } else { throw new IncompleteCommandException(); } } - public WordLimitGame createWordLimitGame(boolean setContent) { + public WordLimitGame createWordLimitGame(boolean isReady, boolean setContent) { uiBot.printKeyboard(); if (setContent) { content.setContent(); } - return new WordLimitGame(content.getContent(), 5); + return new WordLimitGame(content.getContent(), 5, isReady); } public TimeModeGame createTimeLimitGame(ArrayList args, boolean isReady, boolean setContent) { diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index a1bf57a3b5..ee47d4e3e8 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -10,6 +10,7 @@ public abstract class Game { protected final GameUi ui; + protected boolean isReady; public ArrayList displayedLines = new ArrayList<>(); public ArrayList userLines = new ArrayList<>(); @@ -19,6 +20,15 @@ public Game() { this.ui = new GameUi(); } + public void run() { + if (isReady) { + runGame(); + } else { + ui.readyToStartTimer(); + runGame(); + } + } + public long getTimeNow() { return System.currentTimeMillis(); } @@ -27,7 +37,6 @@ public double getDuration(long startTime, long endTime) { return (double) (endTime - startTime) / 1000; } - public abstract void displayLines(int row); public abstract void runGame(); diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 55af2272e1..70cefd087a 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -15,7 +15,6 @@ public class TimeModeGame extends Game { protected final int timeInSeconds; protected final ArrayList wordLists; - protected final boolean isReady; protected int wordsPerLine; protected double gameTime; protected int currentRow; @@ -30,11 +29,17 @@ public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, b this.currentRow = 1; } - public boolean getReady(boolean isReady) { - if (!isReady) { - return ui.readyToStartTimer(); + + public int getTimeLimit() { + Scanner in = new Scanner(System.in); + ui.printScreen("Enter how long (in seconds) you want the game to run: "); + + try { + return Integer.parseInt(in.nextLine()); + } catch (NumberFormatException e) { + System.out.println("Not a Number!"); + return getTimeLimit(); } - return true; } @@ -54,25 +59,24 @@ public void runGame() { Scanner in = new Scanner(System.in); List inputs = new ArrayList<>(); - if (getReady(isReady)) { - long beginTime = getTimeNow(); - boolean timeOver = false; - - while (!timeOver) { - long currTime = getTimeNow() - beginTime; - if (currTime >= timeInSeconds * 1000L) { - gameTime = (double) currTime / 1000; - timeOver = true; - } else { - displayLines(currentRow); - inputs.add(in.nextLine()); - currentRow++; - } + //game begins + long beginTime = getTimeNow(); + boolean timeOver = false; + + while (!timeOver) { + long currTime = getTimeNow() - beginTime; + if (currTime >= timeInSeconds * 1000L) { + gameTime = (double) currTime / 1000; + timeOver = true; + } else { + displayLines(currentRow); + inputs.add(in.nextLine()); + currentRow++; } - - updateUserLines(inputs); - endGame(); } + + updateUserLines(inputs); + endGame(); } public void endGame() { diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index dc183dc151..169ede8bd5 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -22,12 +22,13 @@ public class WordLimitGame extends Game { private String[] displayed; - public WordLimitGame(String targetWordSet, int wordsPerLine) { + public WordLimitGame(String targetWordSet, int wordsPerLine, boolean isReady) { super(); this.eachWord = new ArrayList<>(100); this.wordsPerLine = wordsPerLine; this.content1 = targetWordSet; this.wordLimit = getWordLimit(); + this.isReady = isReady; } diff --git a/src/main/java/seedu/typists/ui/GameUi.java b/src/main/java/seedu/typists/ui/GameUi.java index 5fda06b979..53289df74a 100644 --- a/src/main/java/seedu/typists/ui/GameUi.java +++ b/src/main/java/seedu/typists/ui/GameUi.java @@ -8,14 +8,13 @@ public void printEnd(String endMessage) { printScreen(endMessage); } - public boolean readyToStartTimer() { + public void readyToStartTimer() { Scanner in = new Scanner(System.in); String command = ""; - while (!command.equals("yes")) { - printScreen("Do you want to start now?"); + while (!command.equals("start")) { + printScreen("Timer will start once you entered \"start\": "); command = in.nextLine(); } - return true; } public void printOvershoot(double overshoot) { diff --git a/time-limited_records.txt b/time-limited_records.txt index 048e13f08f..6837f366b7 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1 +1,5 @@ -Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] +Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] +Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] +Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] +Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] +Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] diff --git a/word-limited_records.txt b/word-limited_records.txt index bf673b4479..66f37ee979 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,12 +1,12 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] @@ -19,7 +19,12 @@ Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s,, unknown, printer, took] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s,, unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] +Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] +Word-limited|12.048|0|10|10|0.0|100.0|49.800796812749006|[] +Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] +Word-limited|8.035|0|5|5|0.0|100.0|37.3366521468575|[] +Word-limited|9.04|0|5|5|0.0|100.0|33.18584070796461|[] From 9eb4ab9ddfa2ec2335e523872b69fcd91a167d36 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 4 Nov 2021 02:07:41 +0800 Subject: [PATCH 191/272] more OOP add seperate commands for the 2 game, if they specify number inline with the command, no get Limit promt. --- src/main/java/seedu/typists/Main.java | 4 +- .../seedu/typists/command/CommandFactory.java | 25 +++++- .../seedu/typists/command/GameCommand.java | 77 +++++-------------- .../typists/command/TimeGameCommand.java | 43 +++++++++++ .../typists/command/WordGameCommand.java | 32 ++++++++ .../java/seedu/typists/game/TimeModeGame.java | 12 +-- .../seedu/typists/game/WordLimitGame.java | 12 ++- time-limited_records.txt | 7 +- word-limited_records.txt | 22 +++--- 9 files changed, 150 insertions(+), 84 deletions(-) create mode 100644 src/main/java/seedu/typists/command/TimeGameCommand.java create mode 100644 src/main/java/seedu/typists/command/WordGameCommand.java diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index e1e43f88f5..d476c80a93 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -45,8 +45,8 @@ public void runCommandLoop() { do { String[] input = read().split(" "); command = input[0]; - ArrayList args = new ArrayList<>(Arrays.asList(Arrays.copyOfRange(input, 1, input.length))); - Command c = cmdFactory.getCommand(input[0]); + ArrayList args = new ArrayList<>(Arrays.asList(input)); + Command c = cmdFactory.getCommand(args); if (c != null) { c.run(args); } diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 3ecc3af3c2..9dd3e22439 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -1,14 +1,20 @@ package seedu.typists.command; +import seedu.typists.exception.IncompleteCommandException; import seedu.typists.ui.TextUi; +import java.util.ArrayList; + public class CommandFactory { + private static final String TIME_SIGNIFIER = "-time"; + private static final String WORD_SIGNIFIER = "-word"; TextUi ui = new TextUi(); - public Command getCommand(String commandType) { + public Command getCommand(ArrayList args) { + String commandType = args.get(0); switch (commandType) { case "game": - return new GameCommand(); + return parseGameCommand(args); case "content": return new ContentCommand(); case "history": @@ -22,4 +28,19 @@ public Command getCommand(String commandType) { return null; } } + + public GameCommand parseGameCommand(ArrayList args) { + if (args.contains(TIME_SIGNIFIER)) { + return new TimeGameCommand(); + } else if (args.contains(WORD_SIGNIFIER)) { + return new WordGameCommand(); + } else { + try { + throw new IncompleteCommandException(); + } catch (IncompleteCommandException e) { + ui.printScreen("Please specify game type: -time or -word"); + } + } + return null; + } } diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java index bd8c2737f5..fb789c67a9 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -3,7 +3,6 @@ import seedu.typists.exception.IncompleteCommandException; import seedu.typists.exception.InvalidCommandException; import seedu.typists.game.Game; -import seedu.typists.game.TimeModeGame; import seedu.typists.game.WordLimitGame; import seedu.typists.ui.GameUi; @@ -13,23 +12,19 @@ import static seedu.typists.Main.uiBot; import static seedu.typists.Main.LINE_LENGTH; -public class GameCommand implements Command { - private static final String TIME_SIGNIFIER = "-t"; - private static final String WORD_SIGNIFIER = "-w"; +public abstract class GameCommand implements Command { private static final String START_SIGNIFIER = "-sn"; private static final String CONTENT_SIGNIFIER = "-c"; @Override public void run(ArrayList args) { - boolean startNow = getBoolean(args, START_SIGNIFIER); + boolean isReady = getBoolean(args, START_SIGNIFIER); boolean setContent = getBoolean(args, CONTENT_SIGNIFIER); try { - Game game = createGame(args, startNow, setContent); + Game game = createGame(args, isReady, setContent); game.run(); game.gameSummary(); - } catch (IncompleteCommandException e) { - System.out.println("Please specify game type."); } catch (NullPointerException e) { //exit } catch (StackOverflowError e) { @@ -37,64 +32,28 @@ public void run(ArrayList args) { } } - public Game createGame(ArrayList args, boolean startNow, boolean setContent) - throws IncompleteCommandException { - if (getBoolean(args, TIME_SIGNIFIER)) { - return createTimeLimitGame(args,startNow, setContent); - } else if (getBoolean(args, WORD_SIGNIFIER)) { - return createWordLimitGame(startNow, setContent); - } else { - throw new IncompleteCommandException(); - } - } - - public WordLimitGame createWordLimitGame(boolean isReady, boolean setContent) { - uiBot.printKeyboard(); - if (setContent) { - content.setContent(); - } - return new WordLimitGame(content.getContent(), 5, isReady); - } - - public TimeModeGame createTimeLimitGame(ArrayList args, boolean isReady, boolean setContent) { - try { - int timeInSeconds = getTime(args, TIME_SIGNIFIER); - if (setContent) { - content.setContent(); - } - return new TimeModeGame(timeInSeconds,content.getContent(), LINE_LENGTH, isReady); - } catch (InvalidCommandException e) { - System.out.println( - "Please enter time in multiple of 30 seconds.\n" - + "e.g. game -t 30 " - ); - } catch (IncompleteCommandException | IndexOutOfBoundsException e) { - System.out.println( - "Please specify duration of the game using " - + TIME_SIGNIFIER + "\n" - + "e.g. game -t 60 " - ); - } catch (NumberFormatException e) { - System.out.println("Duration should be a number"); - } - return null; - } + public abstract Game createGame(ArrayList args, boolean isReady, boolean setContent); /** Determine whether the user command has the signifier. **/ public boolean getBoolean(ArrayList args, String key) { return args.contains(key); } - public int getTime(ArrayList args, String key) - throws InvalidCommandException, IncompleteCommandException { - if (!args.contains(key)) { - throw new IncompleteCommandException(); + /** Get the number after the game type indicator. The number will specify + * for time game: time limit (in seconds) + * for word game: word limit + **/ + public int getNumber(ArrayList args, String gameType) + throws InvalidCommandException { + if (!args.contains(gameType)) { + return -1; } - int index = args.indexOf("-t"); - int time = Integer.parseInt(args.get(index + 1)); - if (time % 30 != 0 || time == 0) { - throw new InvalidCommandException(); + //if number is negative or out of range, throw exception + int index = args.indexOf(gameType); + try { + return Integer.parseInt(args.get(index + 1)); + } catch (IndexOutOfBoundsException e) { + return -1; } - return time; } } diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java new file mode 100644 index 0000000000..4a5a6ac7c4 --- /dev/null +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -0,0 +1,43 @@ +package seedu.typists.command; + +import seedu.typists.exception.InvalidCommandException; +import seedu.typists.game.Game; +import seedu.typists.game.TimeModeGame; + +import java.util.ArrayList; + +import static seedu.typists.Main.LINE_LENGTH; +import static seedu.typists.Main.content; + +public class TimeGameCommand extends GameCommand { + private static final String TIME_SIGNIFIER = "-time"; + + @Override + public Game createGame(ArrayList args, boolean isReady, boolean setContent) { + try { + int timeInSeconds = getNumber(args, TIME_SIGNIFIER); + if (setContent) { + content.setContent(); + } + return new TimeModeGame(timeInSeconds, content.getContent(), LINE_LENGTH, isReady); + } catch (NumberFormatException e) { + System.out.println("Duration should be a number"); + } catch (InvalidCommandException e) { + System.out.println( + "Please enter time in multiple of 30 seconds.\n" + + "e.g. game -t 30 " + ); + } + return null; + } + + @Override + public int getNumber(ArrayList args, String gameType) + throws InvalidCommandException { + int n = super.getNumber(args, gameType); + if ((n % 30 != 0 || n == 0) && n != -1 ) { + throw new InvalidCommandException(); + } + return n; + } +} diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java new file mode 100644 index 0000000000..826a4ac440 --- /dev/null +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -0,0 +1,32 @@ +package seedu.typists.command; + +import seedu.typists.exception.IncompleteCommandException; +import seedu.typists.exception.InvalidCommandException; +import seedu.typists.game.Game; +import seedu.typists.game.WordLimitGame; + +import java.util.ArrayList; + +import static seedu.typists.Main.content; + +public class WordGameCommand extends GameCommand { + private static final String WORD_SIGNIFIER = "-word"; + + @Override + public Game createGame(ArrayList args, boolean isReady, boolean setContent) { + //ui.printKeyBoard + try { + int wordLimit = getNumber(args, WORD_SIGNIFIER); + if (setContent) { + content.setContent(); + } + return new WordLimitGame(wordLimit, content.getContent(), 5, isReady); + } catch (NumberFormatException e) { + System.out.println("Number of words be a number"); + } catch (InvalidCommandException e) { + //won't come here. + } + return null; + } + +} diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 70cefd087a..dd8953ca54 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -23,26 +23,28 @@ public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, b super(); assert targetWordSet != null : "text passed into Time Game should not be null."; this.wordLists = splitStringIntoWordList(targetWordSet); - this.timeInSeconds = timeInSeconds; + this.timeInSeconds = getTimeLimit(timeInSeconds); this.wordsPerLine = wordsPerLine; this.isReady = isReady; this.currentRow = 1; } + public int getTimeLimit(int timeInSeconds) { + if (timeInSeconds != -1) { + return timeInSeconds; + } - public int getTimeLimit() { Scanner in = new Scanner(System.in); - ui.printScreen("Enter how long (in seconds) you want the game to run: "); + ui.printScreen("Enter how long you want the game to run: "); try { return Integer.parseInt(in.nextLine()); } catch (NumberFormatException e) { System.out.println("Not a Number!"); - return getTimeLimit(); + return getTimeLimit(timeInSeconds); } } - @Override public void displayLines(int row) { try { diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 169ede8bd5..a36ebfcb3b 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -22,12 +22,12 @@ public class WordLimitGame extends Game { private String[] displayed; - public WordLimitGame(String targetWordSet, int wordsPerLine, boolean isReady) { + public WordLimitGame(int wordLimit, String targetWordSet, int wordsPerLine, boolean isReady) { super(); this.eachWord = new ArrayList<>(100); this.wordsPerLine = wordsPerLine; this.content1 = targetWordSet; - this.wordLimit = getWordLimit(); + this.wordLimit = getWordLimit(wordLimit); this.isReady = isReady; } @@ -47,7 +47,11 @@ public int getTotalSentence() { return eachWord.size(); } - public int getWordLimit() { + public int getWordLimit(int wordLimit) { + if (wordLimit != -1) { + return wordLimit; + } + Scanner in = new Scanner(System.in); ui.printScreen("Enter how many words you want the game to run: "); @@ -55,7 +59,7 @@ public int getWordLimit() { return Integer.parseInt(in.nextLine()); } catch (NumberFormatException e) { System.out.println("Not a Number!"); - return getWordLimit(); + return getWordLimit(wordLimit); } } diff --git a/time-limited_records.txt b/time-limited_records.txt index 6837f366b7..fa95c6756c 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,5 +1,6 @@ -Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] -Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] -Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] +Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] +Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] +Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] +Time-limited|16.053|11|9|20|55.00000000000001|45.0|33.63857222948981|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy] diff --git a/word-limited_records.txt b/word-limited_records.txt index 66f37ee979..ba76876ffe 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,12 +1,12 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] @@ -19,12 +19,16 @@ Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] -Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] +Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] Word-limited|12.048|0|10|10|0.0|100.0|49.800796812749006|[] -Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] +Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] Word-limited|8.035|0|5|5|0.0|100.0|37.3366521468575|[] Word-limited|9.04|0|5|5|0.0|100.0|33.18584070796461|[] +Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] +Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] +Word-limited|5.015|0|4|4|0.0|100.0|47.85643070787638|[] +Word-limited|7.033|0|4|4|0.0|100.0|34.12484003981231|[] From aa37f97d440ad1d45cccefe290606472c328fc8c Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 13:36:51 +0800 Subject: [PATCH 192/272] Improve 'clear' command logic Clears file immediately after gamer inputs command (previously clears file only after gamer enters the 'bye' command --- src/main/java/seedu/typists/game/GameRecordsManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/seedu/typists/game/GameRecordsManager.java b/src/main/java/seedu/typists/game/GameRecordsManager.java index 6a7532e704..a1cfc6e70a 100644 --- a/src/main/java/seedu/typists/game/GameRecordsManager.java +++ b/src/main/java/seedu/typists/game/GameRecordsManager.java @@ -107,11 +107,15 @@ public void clearAllRecords(String gameMode) { assert (gameMode.equals("Time-limited") || gameMode.equals("Word-limited") || gameMode.equals("all")); if (gameMode.equals("Word-limited")) { wordLimitedGameRecords.clear(); + Storage.writeGameRecords(wordLimitedGameRecords, "Word-limited"); } else if (gameMode.equals("Time-limited")) { timeLimitedGameRecords.clear(); + Storage.writeGameRecords(timeLimitedGameRecords, "Time-limited"); } else { wordLimitedGameRecords.clear(); timeLimitedGameRecords.clear(); + Storage.writeGameRecords(wordLimitedGameRecords, "Word-limited"); + Storage.writeGameRecords(timeLimitedGameRecords, "Time-limited"); } } } From e59ec3f22ba7d91b005eb2fbaba158361d7fcde6 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 13:37:25 +0800 Subject: [PATCH 193/272] Improve format of error message to user in history command --- src/main/java/seedu/typists/command/HistoryCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/HistoryCommand.java index 45168c590b..846b41553c 100644 --- a/src/main/java/seedu/typists/command/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/HistoryCommand.java @@ -70,7 +70,7 @@ private void getNumberOfRecords() throws InvalidCommandException { numberOfRecords = Integer.parseInt(args.get(indexNumberOfRecords + 1)); if (numberOfRecords <= 0) { throw new InvalidCommandException("Invalid argument for number of records option.\n" - + "Option only accepts positive integer values." + + "Option only accepts positive integer values.\n" + "Input \"history -h\" for help.\n"); } } catch (NumberFormatException e) { From 90b3f133c6dde8463955024a873b6e9115cf5bb6 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 14:46:47 +0800 Subject: [PATCH 194/272] Improve user guide Reformat user guide add summary feature explain command format more clearly --- docs/UserGuide.md | 77 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 11507a21e6..6b28a6df59 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -21,20 +21,22 @@ Typist is a CLI typing game. ### Notes about the command format: -* Words in UPPER_CASE are parameters to be supplied by the user. -e.g. in `history -g GAME_MODE`, `GAME_MODE` is a parameter which can be used as `history -g time`. +* Words in UPPER_CASE are arguments to be supplied by the user. +e.g. in `history -g GAME_MODE`, `GAME_MODE` is an argument which can be used as `history -g time`. * Items in square brackets are optional. e.g. `-g GAME_MODE [-n NUMBER_OF_RECORDS]` can be used as `-g time -n 9` or as `-g time` * Parameters can be in any order. e.g. if command specifies `history -g GAME_MODE [-n NUMBER_OF_RECORDS]`, `history [-n NUMBER_OF_RECORDS] -g GAME_MODE` -is also acceptable. -* If a parameter is expected only once in the command but you specified it multiple times, +is also acceptable. +Note: One parameter is defined as the option e.g. `-g` and its value (if there is such a field) e.g. `time` +* If a parameter is expected only once in the command, but you specified it multiple times, only the first occurrence of the parameter will be taken e.g. if you specify `history -g time -g time -n 10`, only `history -g time -n 10` will be taken. -* For commands which have a help parameter, if `-h` is among the parameters provided, -all other parameters will be ignored and the guide for that command will be displayed. -e.g. `history -g time -h -n 10` will be interpreted as `history -h`. - +* For commands which have a `-h` parameter, if `-h` is among the parameters provided, all other parameters will be +ignored and the guide for that command will be displayed. +e.g `history -g time -h -n 10` will be interpreted as `history -h`. +* All parameters which do not conform to the command syntax will be ignored. +e.g.2 `clear -gtime` will be interpreted as `clear` ### Usage ### Open Game @@ -82,7 +84,22 @@ Examples * `history -g time -n 10` * `history -g word` - +Example of usage +``` +history -g time -n 1 + __ _____________________ ______ __ + / / / / _/ ___/_ __/ __ \/ __ \ \/ / + / /_/ // / \__ \ / / / / / / /_/ /\ / + / __ // / ___/ // / / /_/ / _, _/ / / +/_/ /_/___//____//_/ \____/_/ |_| /_/ +Game Mode: Time-limited +WPM: 49.71 +Total Time taken for the game: 36.21 seconds +Number of Wrong Words: 0/30|0.00% +Number of Correct Words: 30/30|100.00% +Mistakes: No words typed wrongly. +================================================================== +``` ### Clear past records: `clear` Clear all past game records Format: `clear [-g GAME_MODE] [-h]` @@ -93,10 +110,45 @@ Examples * `clear -g time` * `clear` +Example of usage +``` +clear -g time + ________ _________ ____ ____ ________________ ____ ____ _____ + / ____/ / / ____/ | / __ \ / __ \/ ____/ ____/ __ \/ __ \/ __ \/ ___/ + / / / / / __/ / /| | / /_/ / / /_/ / __/ / / / / / / /_/ / / / /\__ \ +/ /___/ /___/ /___/ ___ |/ _, _/ / _, _/ /___/ /___/ /_/ / _, _/ /_/ /___/ / +\____/_____/_____/_/ |_/_/ |_| /_/ |_/_____/\____/\____/_/ |_/_____//____/ + +Successfully cleared Time-limited game records. +``` +### View summary of game +View summary of a just-played game. +Typists automatically generates and displays the summary after a game ends. +The summary consists of the following fields: +* Game mode +* Word per minute (WPM) +* Total time taken for the game +* Number of wrong words and its percentage +* Number of correct words and its percentage +* Wrongly and not typed words (Mistakes) + +Example of usage +``` + _____ __ ____ _____ ______ ______ __ + / ___// / / / |/ / |/ / | / __ \ \/ / + \__ \/ / / / /|_/ / /|_/ / /| | / /_/ /\ / + ___/ / /_/ / / / / / / / ___ |/ _, _/ / / +/____/\____/_/ /_/_/ /_/_/ |_/_/ |_| /_/ +Game Mode: Time-limited +WPM: 49.71 +Total Time taken for the game: 36.21 seconds +Number of Wrong Words: 0/30|0.00% +Number of Correct Words: 30/30|100.00% +Mistakes: No words typed wrongly. +``` ### Saving the data -Typists automatically stores the updated game records into text files when gamer enters the -`bye` command to exit Typists. +Typists automatically stores the game records (and any changes to them) into text files. ### !Warning: Editing the data file @@ -146,6 +198,9 @@ lorem ipsum is simply dummy text of the printing and typesetting imply dummy text of the printing and typesetting industry | Timer's UP! ``` + + + ## FAQ **Q**: How do I transfer my data to another computer? From 58edbf1fa2f3b36df4fc54409930b2a4e44b3aa3 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 4 Nov 2021 14:48:22 +0800 Subject: [PATCH 195/272] improve command parsing add seperate method in util to analyse if the time limit given is valid. now user can specify the time/word limit of game in either the command or into the game --- .../seedu/typists/command/CommandFactory.java | 8 +--- .../seedu/typists/command/GameCommand.java | 8 ++-- .../typists/command/TimeGameCommand.java | 22 ++++------ .../typists/command/WordGameCommand.java | 7 ++-- src/main/java/seedu/typists/common/Utils.java | 19 +++++++++ src/main/java/seedu/typists/game/Game.java | 19 +++++---- .../java/seedu/typists/game/TimeModeGame.java | 42 +++++++++---------- .../seedu/typists/game/WordLimitGame.java | 26 +++++------- time-limited_records.txt | 12 ++++-- word-limited_records.txt | 27 +++++++----- 10 files changed, 103 insertions(+), 87 deletions(-) diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 9dd3e22439..71fd51138b 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -1,6 +1,5 @@ package seedu.typists.command; -import seedu.typists.exception.IncompleteCommandException; import seedu.typists.ui.TextUi; import java.util.ArrayList; @@ -34,13 +33,8 @@ public GameCommand parseGameCommand(ArrayList args) { return new TimeGameCommand(); } else if (args.contains(WORD_SIGNIFIER)) { return new WordGameCommand(); - } else { - try { - throw new IncompleteCommandException(); - } catch (IncompleteCommandException e) { - ui.printScreen("Please specify game type: -time or -word"); - } } + ui.printScreen("Please specify game type: -time or -word"); return null; } } diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java index fb789c67a9..9d31ac21a7 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -44,16 +44,14 @@ public boolean getBoolean(ArrayList args, String key) { * for word game: word limit **/ public int getNumber(ArrayList args, String gameType) - throws InvalidCommandException { - if (!args.contains(gameType)) { - return -1; - } + throws InvalidCommandException, IncompleteCommandException { //if number is negative or out of range, throw exception int index = args.indexOf(gameType); try { return Integer.parseInt(args.get(index + 1)); } catch (IndexOutOfBoundsException e) { - return -1; + //no suffix after - + throw new IncompleteCommandException(); } } } diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 4a5a6ac7c4..9351b8e69b 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -1,5 +1,6 @@ package seedu.typists.command; +import seedu.typists.exception.IncompleteCommandException; import seedu.typists.exception.InvalidCommandException; import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; @@ -8,36 +9,29 @@ import static seedu.typists.Main.LINE_LENGTH; import static seedu.typists.Main.content; +import static seedu.typists.common.Utils.isValidTime; public class TimeGameCommand extends GameCommand { private static final String TIME_SIGNIFIER = "-time"; @Override public Game createGame(ArrayList args, boolean isReady, boolean setContent) { + try { int timeInSeconds = getNumber(args, TIME_SIGNIFIER); if (setContent) { content.setContent(); } - return new TimeModeGame(timeInSeconds, content.getContent(), LINE_LENGTH, isReady); - } catch (NumberFormatException e) { - System.out.println("Duration should be a number"); - } catch (InvalidCommandException e) { - System.out.println( - "Please enter time in multiple of 30 seconds.\n" - + "e.g. game -t 30 " - ); + return new TimeModeGame(content.getContent(), LINE_LENGTH, timeInSeconds, isReady); + } catch (NumberFormatException | IncompleteCommandException | InvalidCommandException e) { + return new TimeModeGame(content.getContent(), LINE_LENGTH, isReady); } - return null; } @Override public int getNumber(ArrayList args, String gameType) - throws InvalidCommandException { + throws InvalidCommandException, IncompleteCommandException { int n = super.getNumber(args, gameType); - if ((n % 30 != 0 || n == 0) && n != -1 ) { - throw new InvalidCommandException(); - } - return n; + return isValidTime(n); } } diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java index 826a4ac440..9c66dfa4e2 100644 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -20,11 +20,12 @@ public Game createGame(ArrayList args, boolean isReady, boolean setConte if (setContent) { content.setContent(); } - return new WordLimitGame(wordLimit, content.getContent(), 5, isReady); - } catch (NumberFormatException e) { - System.out.println("Number of words be a number"); + return new WordLimitGame(content.getContent(), 5, wordLimit, isReady); } catch (InvalidCommandException e) { //won't come here. + } catch (NumberFormatException | IncompleteCommandException e) { + //constructor without limit + return new WordLimitGame(content.getContent(), 5, isReady); } return null; } diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index d0a705b3e1..8c13bb10bf 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -2,6 +2,8 @@ import seedu.typists.exception.ExceedRangeException; import seedu.typists.exception.FaultyInputException; +import seedu.typists.exception.InvalidCommandException; +import seedu.typists.ui.TextUi; import java.util.ArrayList; import java.util.Arrays; @@ -95,4 +97,21 @@ public static ArrayList getWordLineFromStringArray(List string } return wordLines; } + + /** + * Return a valid duration of time mode game. + * @param n integer that specify the duration + * @return n only if n is valid + * @throws InvalidCommandException thrown when the n is not a valid game duration + */ + public static int isValidTime(int n) throws InvalidCommandException { + if (n < 0) { + new TextUi().printScreen("Duration should not be negative"); + throw new InvalidCommandException(); + } else if (n % 30 != 0 || n == 0) { + new TextUi().printScreen("Duration should be in multiple of 30 seconds."); + throw new InvalidCommandException(); + } + return n; + } } diff --git a/src/main/java/seedu/typists/game/Game.java b/src/main/java/seedu/typists/game/Game.java index ee47d4e3e8..c04cd0120f 100644 --- a/src/main/java/seedu/typists/game/Game.java +++ b/src/main/java/seedu/typists/game/Game.java @@ -1,9 +1,7 @@ package seedu.typists.game; -import seedu.typists.exception.ExceedRangeException; import seedu.typists.ui.GameUi; import seedu.typists.ui.SummaryUi; -import seedu.typists.ui.TextUi; import java.util.ArrayList; import java.util.HashMap; @@ -11,22 +9,29 @@ public abstract class Game { protected final GameUi ui; protected boolean isReady; + protected int wordsPerLine; + protected int limit; public ArrayList displayedLines = new ArrayList<>(); public ArrayList userLines = new ArrayList<>(); public double gameTime; - public Game() { + public Game(int wordsPerLine, boolean isReady) { this.ui = new GameUi(); + this.isReady = isReady; + this.wordsPerLine = wordsPerLine; + } + + public Game(int wordsPerLine, int limit, boolean isReady) { + this(wordsPerLine, isReady); + this.limit = limit; } public void run() { - if (isReady) { - runGame(); - } else { + if (!isReady) { ui.readyToStartTimer(); - runGame(); } + runGame(); } public long getTimeNow() { diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index dd8953ca54..b7e8275fac 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,6 +1,7 @@ package seedu.typists.game; import seedu.typists.exception.ExceedRangeException; +import seedu.typists.exception.InvalidCommandException; import java.util.ArrayList; import java.util.HashMap; @@ -8,41 +9,40 @@ import java.util.Scanner; import static seedu.typists.common.Messages.MESSAGE_TIME_GAME_END; -import static seedu.typists.common.Utils.getDisplayLines; -import static seedu.typists.common.Utils.splitStringIntoWordList; -import static seedu.typists.common.Utils.getWordLineFromStringArray; +import static seedu.typists.common.Utils.*; public class TimeModeGame extends Game { - protected final int timeInSeconds; protected final ArrayList wordLists; - protected int wordsPerLine; protected double gameTime; protected int currentRow; - public TimeModeGame(int timeInSeconds, String targetWordSet, int wordsPerLine, boolean isReady) { - super(); - assert targetWordSet != null : "text passed into Time Game should not be null."; + public TimeModeGame(String targetWordSet, int wordsPerLine, boolean isReady) { + super(wordsPerLine, isReady); + assert targetWordSet != null; this.wordLists = splitStringIntoWordList(targetWordSet); - this.timeInSeconds = getTimeLimit(timeInSeconds); - this.wordsPerLine = wordsPerLine; - this.isReady = isReady; this.currentRow = 1; + this.limit = getTimeLimit(); } - public int getTimeLimit(int timeInSeconds) { - if (timeInSeconds != -1) { - return timeInSeconds; - } + public TimeModeGame(String targetWordSet, int wordsPerLine, int timeInSeconds, boolean isReady) { + super(wordsPerLine, timeInSeconds, isReady); + assert targetWordSet != null; + this.wordLists = splitStringIntoWordList(targetWordSet); + this.currentRow = 1; + } + public int getTimeLimit() { Scanner in = new Scanner(System.in); ui.printScreen("Enter how long you want the game to run: "); - try { - return Integer.parseInt(in.nextLine()); + int n = Integer.parseInt(in.nextLine()); + return isValidTime(n); } catch (NumberFormatException e) { - System.out.println("Not a Number!"); - return getTimeLimit(timeInSeconds); + System.out.println("Invalid Number!"); + } catch (InvalidCommandException e) { + //repeat getTimeLimit } + return getTimeLimit(); } @Override @@ -67,7 +67,7 @@ public void runGame() { while (!timeOver) { long currTime = getTimeNow() - beginTime; - if (currTime >= timeInSeconds * 1000L) { + if (currTime >= limit * 1000L) { gameTime = (double) currTime / 1000; timeOver = true; } else { @@ -83,7 +83,7 @@ public void runGame() { public void endGame() { ui.printEnd(MESSAGE_TIME_GAME_END); - double overshoot = gameTime - timeInSeconds; + double overshoot = gameTime - limit; assert overshoot >= 0; if (overshoot > 0) { ui.printOvershoot(overshoot); diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index a36ebfcb3b..a574d0608a 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -15,22 +15,22 @@ public class WordLimitGame extends Game { private ArrayList eachWord; protected ArrayList wordLines; - protected int wordLimit; - private final int wordsPerLine; private final String content1; private long beginTime; private String[] displayed; - - public WordLimitGame(int wordLimit, String targetWordSet, int wordsPerLine, boolean isReady) { - super(); + public WordLimitGame(String targetWordSet, int wordsPerLine, boolean isReady) { + super(wordsPerLine, isReady); this.eachWord = new ArrayList<>(100); - this.wordsPerLine = wordsPerLine; this.content1 = targetWordSet; - this.wordLimit = getWordLimit(wordLimit); - this.isReady = isReady; + this.limit = getWordLimit(); } + public WordLimitGame(String targetWordSet, int wordsPerLine, int wordLimit, boolean isReady) { + super(wordsPerLine, wordLimit, isReady); + this.eachWord = new ArrayList<>(100); + this.content1 = targetWordSet; + } @Override public void displayLines(int row) { @@ -47,11 +47,7 @@ public int getTotalSentence() { return eachWord.size(); } - public int getWordLimit(int wordLimit) { - if (wordLimit != -1) { - return wordLimit; - } - + public int getWordLimit() { Scanner in = new Scanner(System.in); ui.printScreen("Enter how many words you want the game to run: "); @@ -59,7 +55,7 @@ public int getWordLimit(int wordLimit) { return Integer.parseInt(in.nextLine()); } catch (NumberFormatException e) { System.out.println("Not a Number!"); - return getWordLimit(wordLimit); + return getWordLimit(); } } @@ -73,7 +69,7 @@ public void trimContent(int wordLimit) { } public void runGame() { - trimContent(wordLimit); + trimContent(limit); beginTime = getTimeNow(); List inputs = new ArrayList<>(); int row = 0;// for method: getDisplayLines() diff --git a/time-limited_records.txt b/time-limited_records.txt index fa95c6756c..317827b066 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,6 +1,10 @@ -Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] -Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] -Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] +Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] +Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] +Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] -Time-limited|16.053|11|9|20|55.00000000000001|45.0|33.63857222948981|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy] +Time-limited|16.053|11|9|20|55.00000000000001|45.0|33.63857222948981|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy] +Time-limited|19.074|7|13|20|35.0|65.0|40.89336269267065|[the, printing, typesetting, industry., industry's, standard, dummy] +Time-limited|8.035|3|7|10|30.0|70.0|52.2713130056005|[the, printing, and] +Time-limited|21.076|4|16|20|20.0|80.0|45.549440121465175|[typesetting, industry., industry's, dummy] +Time-limited|15.048|10|0|10|100.0|0.0|0.0|[Lorem, Ipsum, is, simply, dummy, text, of, the, printing, and] diff --git a/word-limited_records.txt b/word-limited_records.txt index ba76876ffe..2c2a44cbbc 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,12 +1,12 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] @@ -19,16 +19,21 @@ Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] -Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] +Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] Word-limited|12.048|0|10|10|0.0|100.0|49.800796812749006|[] -Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] +Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] Word-limited|8.035|0|5|5|0.0|100.0|37.3366521468575|[] Word-limited|9.04|0|5|5|0.0|100.0|33.18584070796461|[] -Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] -Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] +Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] +Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] Word-limited|5.015|0|4|4|0.0|100.0|47.85643070787638|[] Word-limited|7.033|0|4|4|0.0|100.0|34.12484003981231|[] +Word-limited|5.016|1|1|2|50.0|50.0|11.961722488038278|[Ipsum] +Word-limited|11.045|2|8|10|20.0|80.0|43.45857854232684|[printing, and] +Word-limited|9.037|0|6|6|0.0|100.0|39.83622883700343|[] +Word-limited|3.01|2|0|2|100.0|0.0|0.0|[Lorem, Ipsum] +Word-limited|4.012|0|2|2|0.0|100.0|29.910269192422735|[] From 7e874070a9e61a7e566e879421ad88b6e3f79eee Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 14:57:18 +0800 Subject: [PATCH 196/272] Format help message for history and clear command --- src/main/java/seedu/typists/ui/ClearCommandUi.java | 9 +++++---- src/main/java/seedu/typists/ui/HistoryCommandUi.java | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/typists/ui/ClearCommandUi.java b/src/main/java/seedu/typists/ui/ClearCommandUi.java index 9e6e6e35cc..667980eaaf 100644 --- a/src/main/java/seedu/typists/ui/ClearCommandUi.java +++ b/src/main/java/seedu/typists/ui/ClearCommandUi.java @@ -8,11 +8,12 @@ public static void displayHelp() { System.out.print("clear deletes all records for both games," + " or either of the game types, depending on your choice.\n"); System.out.print("The format of the command is 'clear [-g GAME_MODE]'\n"); - System.out.print("The arguments in the square brackets are optional." - + " If not inputted, the default is 'all' which means" + System.out.print("The arguments in the square brackets are optional.\n" + + "GAME_MODE specifies which game mode's record(s) to clear.\n" + + "If not inputted, the default is 'all' which means " + "records from both the time- and word-limited will be cleared.\n"); - System.out.print("The possible values for GAME_MODE is 'all', 'time', and, 'word\n"); - System.out.print("'word' clears all game records for the word-limited mode\n" + System.out.print("The possible values for GAME_MODE is 'all', 'time', and, 'word'.\n"); + System.out.print("'word' clears all game records for the word-limited mode.\n" + "'time' clears all game records for the time-limited mode.\n"); } diff --git a/src/main/java/seedu/typists/ui/HistoryCommandUi.java b/src/main/java/seedu/typists/ui/HistoryCommandUi.java index 91aa60f303..e2b4d4c179 100644 --- a/src/main/java/seedu/typists/ui/HistoryCommandUi.java +++ b/src/main/java/seedu/typists/ui/HistoryCommandUi.java @@ -29,10 +29,10 @@ public static void displayGameRecords(ArrayList gameRecords, int num public static void displayHelp() { //do after user guide System.out.print("history shows the game records for your past games.\n"); - System.out.print("The format of the command is 'history -g GAME_MODE [-n NUMBER_OF_RECORDS]'\n"); - System.out.print("Only the arguments in the square brackets are optional."); + System.out.print("Command format: 'history -g GAME_MODE [-n NUMBER_OF_RECORDS]'\n"); + System.out.print("Arguments in the square brackets are optional.\n"); System.out.print("GAME_MODE specifies which game mode records you want to view.\n" - + "The possible values for GAME_MODE are 'time' and 'word'\n"); + + "The possible values for GAME_MODE are 'time' and 'word'.\n"); System.out.print("NUMBER_OF_RECORDS specifies the number of past records you want to view.\n" + "Only positive integers are allowed.\n" + "If not inputted, the default is the total number of game records " From 09ca4e3bf7402ed1ac18814f1dd00fcb22613b6a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 4 Nov 2021 15:07:00 +0800 Subject: [PATCH 197/272] pass test --- .gitignore | 5 +--- .../java/seedu/typists/common/Messages.java | 3 ++- .../java/seedu/typists/game/TimeModeGame.java | 6 ++++- text-ui-test/EXPECTED.TXT | 7 ++--- time-limited_records.txt | 16 ++++++------ word-limited_records.txt | 26 +++++++++---------- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index fc4f1a4154..37e259c9a3 100644 --- a/.gitignore +++ b/.gitignore @@ -15,11 +15,8 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT -time-limited_records.txt seedu.typists.ui.TextUi.log seedu.typists.ui.TextUi.log.1 seedu.typists.ui.TextUi.log.lck time-limited_records.txt -time-limited_records.txt -word-limited_records.txt -word-limited_records.txt +word-limited_records.txt \ No newline at end of file diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index c3efd1f766..1aef77881d 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -70,7 +70,8 @@ public class Messages { public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; public static final String MESSAGE_HELP = "Manual:\n" + "content: set the content\n" - + "game: start a new game\n" + + "game -time: start a new time game\n" + + "game -word: start a new word game\n" + "history -g GAME_MODE [-n NUMBER_OF_RECORDS]: view past game records\n" + "clear [-g GAME_MODE]: clear all game records\n" + "bye: exit typist"; diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index b7e8275fac..e4396089b1 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -9,7 +9,11 @@ import java.util.Scanner; import static seedu.typists.common.Messages.MESSAGE_TIME_GAME_END; -import static seedu.typists.common.Utils.*; +import static seedu.typists.common.Utils.getDisplayLines; +import static seedu.typists.common.Utils.splitStringIntoWordList; +import static seedu.typists.common.Utils.getWordLineFromStringArray; +import static seedu.typists.common.Utils.isValidTime; + public class TimeModeGame extends Game { protected final ArrayList wordLists; diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index bba842da2f..203766e94a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -10,9 +10,10 @@ | Brought to you by -- AY2122S1-CS2113-T13-4. | Manual: | content: set the content - | game: start a new game - | history: view past game records - | clear: clear all game records + | game -time: start a new time game + | game -word: start a new word game + | history -g GAME_MODE [-n NUMBER_OF_RECORDS]: view past game records + | clear [-g GAME_MODE]: clear all game records | bye: exit typist | =========================================================== Updating game records... diff --git a/time-limited_records.txt b/time-limited_records.txt index 317827b066..3b08b57b37 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,10 +1,10 @@ -Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] -Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] -Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] +Time-limited|33.092|12|18|30|40.0|60.0|32.63628671582255|[simply, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, text, printer] +Time-limited|33.134|9|21|30|30.0|70.0|38.02740387517354|[Lorem, Ipsum, typesetting, industry., industry's, standard, dummy, since, the] +Time-limited|30.119|8|22|30|26.666666666666668|73.33333333333333|43.826156246887344|[simply, printing, typesetting, industry., industry's, unknown, printer, took] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] Time-limited|0.0|0|0|0|NaN|NaN|NaN|[] -Time-limited|16.053|11|9|20|55.00000000000001|45.0|33.63857222948981|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy] -Time-limited|19.074|7|13|20|35.0|65.0|40.89336269267065|[the, printing, typesetting, industry., industry's, standard, dummy] -Time-limited|8.035|3|7|10|30.0|70.0|52.2713130056005|[the, printing, and] -Time-limited|21.076|4|16|20|20.0|80.0|45.549440121465175|[typesetting, industry., industry's, dummy] -Time-limited|15.048|10|0|10|100.0|0.0|0.0|[Lorem, Ipsum, is, simply, dummy, text, of, the, printing, and] +Time-limited|16.053|11|9|20|55.00000000000001|45.0|33.63857222948981|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy] +Time-limited|19.074|7|13|20|35.0|65.0|40.89336269267065|[the, printing, typesetting, industry., industry's, standard, dummy] +Time-limited|8.035|3|7|10|30.0|70.0|52.2713130056005|[the, printing, and] +Time-limited|21.076|4|16|20|20.0|80.0|45.549440121465175|[typesetting, industry., industry's, dummy] +Time-limited|15.048|10|0|10|100.0|0.0|0.0|[Lorem, Ipsum, is, simply, dummy, text, of, the, printing, and] diff --git a/word-limited_records.txt b/word-limited_records.txt index 2c2a44cbbc..b6387a9e4b 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,12 +1,12 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] @@ -19,21 +19,21 @@ Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] -Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] +Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] Word-limited|12.048|0|10|10|0.0|100.0|49.800796812749006|[] -Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] +Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] Word-limited|8.035|0|5|5|0.0|100.0|37.3366521468575|[] Word-limited|9.04|0|5|5|0.0|100.0|33.18584070796461|[] -Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] -Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] +Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] +Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] Word-limited|5.015|0|4|4|0.0|100.0|47.85643070787638|[] Word-limited|7.033|0|4|4|0.0|100.0|34.12484003981231|[] Word-limited|5.016|1|1|2|50.0|50.0|11.961722488038278|[Ipsum] -Word-limited|11.045|2|8|10|20.0|80.0|43.45857854232684|[printing, and] +Word-limited|11.045|2|8|10|20.0|80.0|43.45857854232684|[printing, and] Word-limited|9.037|0|6|6|0.0|100.0|39.83622883700343|[] -Word-limited|3.01|2|0|2|100.0|0.0|0.0|[Lorem, Ipsum] +Word-limited|3.01|2|0|2|100.0|0.0|0.0|[Lorem, Ipsum] Word-limited|4.012|0|2|2|0.0|100.0|29.910269192422735|[] From bbafe12fe8699be273f3c3ea012b5db594bfefbb Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 15:58:41 +0800 Subject: [PATCH 198/272] Correct developer guide uml images for view statistics feature Correct representation of array on object diagram Correct representation of static method in sequence diagram Fixes #85 --- docs/DeveloperGuide.md | 6 +++--- docs/uml/ViewStatistics-1.drawio | 1 - docs/uml/ViewStatistics-2.drawio | 1 - docs/uml/ViewStatistics-3.drawio | 1 - docs/uml/ViewStatistics-3.drawio.svg | 2 +- docs/uml/ViewStatistics-4.drawio | 1 - docs/uml/ViewStatistics-4.drawio.svg | 2 +- docs/uml/ViewStatistics-5.drawio | 1 - docs/uml/ViewStatistics-5.drawio.svg | 2 +- 9 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 docs/uml/ViewStatistics-1.drawio delete mode 100644 docs/uml/ViewStatistics-2.drawio delete mode 100644 docs/uml/ViewStatistics-3.drawio delete mode 100644 docs/uml/ViewStatistics-4.drawio delete mode 100644 docs/uml/ViewStatistics-5.drawio diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d6b7a91599..967c87f00e 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -69,9 +69,9 @@ Its key methods are: Given below is an example usage scenario and how the program implements the feature. -Step 1: The user launches the application (scenario assumes that there are several game records already stored in multiple files). +Step 1: The user launches the application (scenario assumes that there are several game records already stored in the text files). -Step 2: The user executes `view -m best -g time -n 9` to view his/her best statistics for the error game mode over the past 9 games. +Step 2: The user executes `view -m best -g time -n 4` to view his/her best statistics for the time-limited game mode over the past 4 games. Step 3: A ViewCommand object is then instantiated. @@ -83,7 +83,7 @@ Step 4. ViewCommand calls the retrieveStatistics() method of StatisticsManager. Step 5: StatisticsManager creates a GameRecordsManager object. * The constructor of GameRecordsManager calls the readGameRecords() method of the Storage class to retrieve the gamer's past game records from the text files. -![Alt text](uml/ViewStatistics-3.drawio.svg) +![Alt text](uml/ViewStatistics-3.drawio.svg) Step 6. StatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). * Calculated statistics is returned. diff --git a/docs/uml/ViewStatistics-1.drawio b/docs/uml/ViewStatistics-1.drawio deleted file mode 100644 index 3fd76a1942..0000000000 --- a/docs/uml/ViewStatistics-1.drawio +++ /dev/null @@ -1 +0,0 @@ -jZTNjpswEICfhmNWYCckOSYk7F4qtYq0PVYuTMCKYagxCdun7xgbEnYVqRcw3/wPMw54UvWvWjTlN8xBBSzM+4AfAsYituT0suTDkXW8dqDQMncovIOT/AvecqSdzKH1zCGDqIxs5jDDuobMzJjQGm9ztTOqfAYaUcAsDQtOmVDwRe2nzE3p6Iat7/wNZFGOkaN46yS/RXYpNHa1jxcwni7T6HB04kqMvnzcthQ53h4QPwY80YjGnao+AWV7O29b+kQ65a2hNv9jkJ77zaH/9R2bbvGja2N8b7cL7+UqVAdjGbEif/szklvqp8icIP7T2Uz3b6CuYGQm7ohOhX8Ppm0jaluw+VBzW+tz0Q4jsCOFKGz65166CfDdu4RbglUlqNleTIV2n02IudhfsKtmxGyWHStNpegU2dQvYDL730L6KEVWdhpeRUNgSaBBWRvQxyu1vPVK1nMqKqns/O90VkpDY9pShIPoaGxAe6UTdnroZWkMzTZb2R6s6HfZh1VoXwrEQoFoZPuSYTUIsnZQTc8uBB1nQVZs/zmM2zA25CaVSlChHurkKUuSTWqrNBov8CA5huvdKvUeHjjf8mQVTz27gjbQP52/aJpqui0AKzCaMg5Hg9gvgr8ophvgdl+7iHtWPqzcaCf8pheT6/u008EP/Ph5X6xB9nB78eM/ \ No newline at end of file diff --git a/docs/uml/ViewStatistics-2.drawio b/docs/uml/ViewStatistics-2.drawio deleted file mode 100644 index 2e4fb472d9..0000000000 --- a/docs/uml/ViewStatistics-2.drawio +++ /dev/null @@ -1 +0,0 @@ -7VdLc5swEP41PjoDyGD7aDsmmUkykxl3+jgqsAbFAlEh/Oiv7wqJl1u7TQ+ZHHoJ7LcvaffbNRmRVXa8k7RIn0QMfOQ58XFEbkeeN/WmDj40cjIImZKpQRLJYoM5HbBhP8CAboNWLIbSYgZSQnDFiiEYiTyHSA0wKqU4DM22gscDoKAJDI6hgU1EOfxi9oXFKjXozJt2+D2wJG0yu8HcaF5otEukqHKbb+SRcBK6t2ujzmgTy+YtUxqLQw8i6xFZSSGUecuOK+C6uMOyhRe07bkl5OpvHMLHh514We/gYbNm+WtVyHg8tlH2lFfQXCPgGG+5FRgW60kjowi+V/qky3vge1Asoh2kL6dOfGin/cdl3e4FGrhOcex7BIl+ViW23ibEk5ucRmWL1sb1IMa+WTEXOT6WdfVB389BqdyBilIrpDRKKwl3tEBggoCQKhWJyCl/FEKDLoKvoNTJcpJWSmhHlXGrhSNTX3vv33TsG99Kt0ebqhZOVtBXCGnGuAYWMkqZQtbiJR1MgCwCaY02opJ1aVOlkOqer8vkY/f0H21Q3iRCJBxowcqbSGS1Iipr03BrUuDrIInvLc/TmMu5gT5oHi/0xKAsCsg/pSzXZVNUtmYTY9YXy/qgzyBZBhh3U9CI5QlqZ6hE3wTUBSUSU56+NlXSQq+CWuxKWEunVopDxnnTViXFDlaCC1kTgayd6cIP7f16OJmTla/vyekL8GU7nj0TO6BkGdMyrYnjtlTT/Lo4Ws1mqq97ZZ68drBxY4LAokjskmPX5di5cf35xMSSwKli+2FOardZ0vq24Z4FqyeyiRU4xDdOdvWOvbnvDcPY3hnPbjcgC+ipZ1Zog/JqLse5kMuGxBcT9SxCk0JstyWoM49ejTqoXltvWGHeu60w73crrElWtQBZbBR2tmQqKp9ojj8gsrfjqnPHP+293kK6vuHqLoJc70E380OvI68+G854fza91WoW/tPAWwaAVHC8PsKXR9OfB8E5xWeWW4fuw8ANiMHS3kdB4Fye3gHd38pt8vG4/ZnBYSWyjOJ3z39Wf3RWB+58+o6sRrH7oDULvvu3gax/Ag== \ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio b/docs/uml/ViewStatistics-3.drawio deleted file mode 100644 index 7da7f2e5cd..0000000000 --- a/docs/uml/ViewStatistics-3.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-3.drawio.svg b/docs/uml/ViewStatistics-3.drawio.svg index d95c2d03c1..5028fc2356 100644 --- a/docs/uml/ViewStatistics-3.drawio.svg +++ b/docs/uml/ViewStatistics-3.drawio.svg @@ -1,4 +1,4 @@ -
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file +
:ViewCommand
:ViewCommand
Uses
Uses
:StatisitcsManager
:StatisitcsManag...
:GameRecordsManager
:GameRecordsMana...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
:Storage
:Storage
Creates
Creates
uses
uses
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-4.drawio b/docs/uml/ViewStatistics-4.drawio deleted file mode 100644 index dbb2a72940..0000000000 --- a/docs/uml/ViewStatistics-4.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-4.drawio.svg b/docs/uml/ViewStatistics-4.drawio.svg index 823fb246cc..a2af832b75 100644 --- a/docs/uml/ViewStatistics-4.drawio.svg +++ b/docs/uml/ViewStatistics-4.drawio.svg @@ -1,4 +1,4 @@ -
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
:GameRecords
:GameRecords
wordLimitedGameRecords
wordLimitedGameRecords
9
9
timeLimitedGameRecords
timeLimitedGameRecords
15
15
:GameRecords
:GameRecords
:Storage
:Storage
Uses
Uses
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
Viewer does not support full SVG 1.1
\ No newline at end of file +
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
:Storage
:Storage
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
uses
uses
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/uml/ViewStatistics-5.drawio b/docs/uml/ViewStatistics-5.drawio deleted file mode 100644 index c11d8a4f5e..0000000000 --- a/docs/uml/ViewStatistics-5.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/uml/ViewStatistics-5.drawio.svg b/docs/uml/ViewStatistics-5.drawio.svg index 89631fe5cd..3d0e9852b3 100644 --- a/docs/uml/ViewStatistics-5.drawio.svg +++ b/docs/uml/ViewStatistics-5.drawio.svg @@ -1,4 +1,4 @@ -:ViewCommand:StatisticsManagerretrieveStatistics(best, "Time-limited", 9)
calculateBestStatistics()
calculateBestStatistics()
bestStatistics
bestStatistics
bestStatisticsnew StatisticsManager():GameRecordsManager()gameRecordsnew GameRecordsManager():Storagenew Storage()timeLimitedGameRecords = readGameRecords("Time-limited")wordLimitedGameRecords = readGameRecords("Word-limited")new getGameRecords("Time-limited", 9):ViewCommandUinew ViewCommandUi()displayStatistics(statistics)executeCommand(best, "Time-limited", 9)
Viewer does not support full SVG 1.1
\ No newline at end of file +:ViewCommand<<class>>StatisticsManagerretrieveStatistics("best", "Time-limited", 4)
calculateBestStatistics(gameRecords)
calculateBestStatistics(gameRecords)
bestStatistics
bestStatistics
bestStatistics:GameRecordsManager()gameRecordsnew GameRecordsManager()<<class>>StoragetimeLimitedGameRecords = readGameRecords("Time-limited")wordLimitedGameRecords = readGameRecords("Word-limited")getGameRecords("Time-limited", 4)<<class>>ViewCommandUidisplayStatistics(bestStatistics)executeCommand("best", "Time-limited", 4)
Viewer does not support full SVG 1.1
\ No newline at end of file From 435ff624775b692deec8450a2debeff742794e32 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:07:22 +0800 Subject: [PATCH 199/272] Fix word mode negative number --- seedu.typists.ui.TextUi.log.1 | 2 +- .../seedu/typists/game/WordLimitGame.java | 25 ++++++++++++--- word-limited_records.txt | 31 +++++++++++-------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index 6087e49b35..e7d3a89772 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Oct 28, 2021 2:42:10 AM seedu.typists.ui.SummaryUi setUpLog +Nov 04, 2021 5:06:52 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index a574d0608a..c1b6c1cc1d 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -1,13 +1,16 @@ package seedu.typists.game; import seedu.typists.exception.ExceedRangeException; +import seedu.typists.exception.InvalidCommandException; import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.ui.TextUi; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Scanner; + import static seedu.typists.common.Utils.getDisplayLinesWithoutNull; import static seedu.typists.common.Utils.getWordLineFromStringArray; import static seedu.typists.parser.StringParser.splitString; @@ -50,15 +53,27 @@ public int getTotalSentence() { public int getWordLimit() { Scanner in = new Scanner(System.in); ui.printScreen("Enter how many words you want the game to run: "); - try { - return Integer.parseInt(in.nextLine()); + int n = Integer.parseInt(in.nextLine()); + return isValidWord(n); } catch (NumberFormatException e) { - System.out.println("Not a Number!"); - return getWordLimit(); + new TextUi().printScreen("Length should be a number!"); + //repeat getWordLimit + } catch (InvalidCommandException e) { + new TextUi().printScreen(e.getMessage()); + //repeat getWordLimit + } + return getWordLimit(); + } + + public static int isValidWord(int n) throws InvalidCommandException { + if (n <= 0) { + throw new InvalidCommandException("Length should be positive!"); } + return n; } + public void trimContent(int wordLimit) { try { eachWord = splitString(content1, " "); @@ -69,6 +84,7 @@ public void trimContent(int wordLimit) { } public void runGame() { + assert limit > 0 : "limit should be greater than 0"; trimContent(limit); beginTime = getTimeNow(); List inputs = new ArrayList<>(); @@ -76,6 +92,7 @@ public void runGame() { boolean isExit = false; while (!isExit) { row++; + assert row > 0 : "row is always a positive integer."; //display a single line displayLines(row); //read user input diff --git a/word-limited_records.txt b/word-limited_records.txt index b6387a9e4b..76a1ff2768 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1,12 +1,12 @@ Word-limited|8.037|0|10|10|0.0|100.0|74.65472191116088|[] Word-limited|30.191|0|20|20|0.0|100.0|39.74694445364513|[] -Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|22.8|10|5|15|66.66666666666666|33.33333333333333|13.157894736842104|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|46.031|0|5|5|0.0|100.0|6.517347005279051|[] -Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] -Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] -Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|14.678|5|5|10|50.0|50.0|20.438751873552256|[lorem, ipsum, is, simply, dummy] +Word-limited|109.671|10|5|15|66.66666666666666|33.33333333333333|2.735454222173592|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] +Word-limited|23.827|10|5|15|66.66666666666666|33.33333333333333|12.590758383346623|[lorem, ipsum, is, simply, dummy, lorem, ipsum, is, simply, dummy] Word-limited|22.787|0|15|15|0.0|100.0|39.496203975951204|[] -Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] +Word-limited|1176.443|5|5|10|50.0|50.0|0.25500597989022844|[lorem, ipsum, is, simply, dummy] Word-limited|4.037|0|5|5|0.0|100.0|74.31260837255388|[] Word-limited|12.101|0|12|12|0.0|100.0|59.49921494091397|[] Word-limited|10.02|0|5|5|0.0|100.0|29.940119760479043|[] @@ -19,21 +19,26 @@ Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|4.01|0|3|3|0.0|100.0|44.88778054862843|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] Word-limited|9.019|0|5|5|0.0|100.0|33.26311120966847|[] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] -Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] +Word-limited|38.126|9|21|30|30.0|70.0|33.048313486859364|[Lorem, typesetting, industry., industry's, standard, 1500s, , unknown, printer, took] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] Word-limited|11.024|1|4|5|20.0|80.0|21.770682148040642|[simply] -Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] +Word-limited|181.693|3|27|30|10.0|90.0|8.916138761537319|[typesetting, industry., industry's] Word-limited|12.048|0|10|10|0.0|100.0|49.800796812749006|[] -Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] +Word-limited|12.048|2|8|10|20.0|80.0|39.8406374501992|[simply, printing] Word-limited|8.035|0|5|5|0.0|100.0|37.3366521468575|[] Word-limited|9.04|0|5|5|0.0|100.0|33.18584070796461|[] -Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] -Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] +Word-limited|23.095|2|13|15|13.333333333333334|86.66666666666667|33.773544057155235|[typesetting, industry.] +Word-limited|14.049|6|5|11|54.54545454545454|45.45454545454545|21.353833013025838|[simply, dummy, text, printing, and, typesetting] Word-limited|5.015|0|4|4|0.0|100.0|47.85643070787638|[] Word-limited|7.033|0|4|4|0.0|100.0|34.12484003981231|[] Word-limited|5.016|1|1|2|50.0|50.0|11.961722488038278|[Ipsum] -Word-limited|11.045|2|8|10|20.0|80.0|43.45857854232684|[printing, and] +Word-limited|11.045|2|8|10|20.0|80.0|43.45857854232684|[printing, and] Word-limited|9.037|0|6|6|0.0|100.0|39.83622883700343|[] -Word-limited|3.01|2|0|2|100.0|0.0|0.0|[Lorem, Ipsum] +Word-limited|3.01|2|0|2|100.0|0.0|0.0|[Lorem, Ipsum] Word-limited|4.012|0|2|2|0.0|100.0|29.910269192422735|[] +Word-limited|3.034|0|0|0|NaN|NaN|0.0|[] +Word-limited|4.033|0|2|2|0.0|100.0|29.754525167369202|[] +Word-limited|4.046|0|2|2|0.0|100.0|29.658922392486406|[] +Word-limited|5.051|0|2|2|0.0|100.0|23.75767174816868|[] +Word-limited|3.031|0|3|3|0.0|100.0|59.38634114153744|[] From 7effb926ae959ab95094e561428a3527550cc432 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:13:18 +0800 Subject: [PATCH 200/272] Update -w to -word --- docs/UserGuide.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6b28a6df59..51c8867f68 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -59,18 +59,18 @@ Start a typing game. Format: `game GAME_MODE [-c]` * SET_CONTENT `-c` is optional, it allows user to set input content before game starts. * GAME_MODE - * `-w` for game in Word Limit Mode - * `-t` for game in Time Limit Mode + * `-word` for game in Word Limit Mode + * `-time` for game in Time Limit Mode * For Word Limit Game: - * Format: `game -w [-c]` + * Format: `game -word [-c]` * Exit: `Exit` allows user to terminate the current game. * For Time Limit Game: - * Format: `game -t TIME_LIMIT [-sn] [-c]` + * Format: `game -time TIME_LIMIT [-sn] [-c]` * START_NOW `-sn` allows user to start the game immediately without the "ready to start?" prompt. Examples -* `game -t 30 -sn` -* `game -w -c` +* `game -time 30 -sn` +* `game -word -c` @@ -165,9 +165,9 @@ List of the keywords are shown below: `content`-Set the content -`game -w`-Enter a word-limited game mode +`game -word`-Enter a word-limited game mode -`game -w -c`-Enter a word-limited game mode with content setting +`game -word -c`-Enter a word-limited game mode with content setting >Exit word-limited game mode command: `Exit` @@ -183,7 +183,7 @@ Statistics of game is shown automatically after a game is finished. ## Example of usage: ``` -game -w +game -word | Enter how many words you want the game to run: 5 | lorem ipsum is simply dummy @@ -191,7 +191,7 @@ lorem ipsum is simply dummy | Your progress:5/5 ``` ``` -game -t 30 -sn +game -time 30 -sn | lorem ipsum is simply dummy text of the printing and lorem ipsum is simply dummy text of the printing and | typesetting imply dummy text of the printing and typesetting industry @@ -211,6 +211,6 @@ typesetting imply dummy text of the printing and typesetting industry | Feature | Command | | ------------- | ------------- | -| Start Word Limit Game| `game -w [-c]` | -| Start Time Limit Game | `game -t TIME_LIMIT [-sn] [-c]` +| Start Word Limit Game| `game -word [-c]` | +| Start Time Limit Game | `game -time TIME_LIMIT [-sn] [-c]` | Get History | `history -h`| \ No newline at end of file From 77975e4dc175becb4e52e35f89d22851f63bf10f Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 17:15:01 +0800 Subject: [PATCH 201/272] Add content in PPP. --- docs/team/limjiajing.md | 58 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index 5b00fe8e74..86bebd54cd 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -1,6 +1,62 @@ # Lim Jia Jing - Project Portfolio Page ## Overview - +Typists is a command line interface typing game targeted at users who love to type and are +familiar with the command line interface. There are two game modes in types, time-limited +(aim to type as much as possible in a limited time) and word-limited (aim to type a chosen +number of words as fast as possible). ### Summary of Contributions +####Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/#breakdown=true&search=limjiajing) + +#### Contribution to code design +Suggest having all command classes implement a common interface and using factory +design pattern to create instantiate objects of classes which implement the interface +for code to have less coupling. + +####Enhancements implemented +1. New feature: Added the summary feature that will show the game's summary after a game finishes. + * What it does: Shows the summary of the game to gamers after they complete a game. + Fields in the summary - + `game mode`, `wpm`, `wrong word count`, `percentage of wrong words`, `correct word counts`, + `percentage of correct words` and `mistakes`. + * Justification: This feature improves the project significantly because gamers mostly + want to know how they did in a game. + * Highlights: The logic of getting the mistakes made was fairly complicated as it required taking into + considerations many conditions and scenarios. The implementation of this feature also affects the implementation + of the `view history` feature, hence the design had to be well-thought-out. + +2. New feature: Added the ability to view records of past games. + * What it does: Allows gamers to select which game mode's past records they want to view + and how many records (from the most recent) they want to view. Defaults to + all the records in the selected game mode if they do not specify the number to records to view. + * Justification: Gamers would want to view how they did in the past and see how they improved over time. + The gamers could also be typists who use this application to improve their typing. They might want to view + which words they type wrongly most often so that they can work on it. + * Highlights: The command related to this feature `history` has both optional and compulsory parameters. The parsing + for this command was hence rather complicated to implement. + +3. New feature: Added the ability to clear all past game records. + * What it does: Clear the past game records of a selected game mode. If the game mode is + not specified, game records from both game modes are wiped. + * Justification: Gamers would at times like to clear their past records so that they can start afresh. + +4. New feature: Added automatic storage of game records. + * What it does: Automatically stores changes in game records to the corresponding text file + (different text files for different game modes). + * Justification: This feature is required for the `view history` feature. + * Highlights: Extensive exception handling had to be done for the scenario where + the gamer modifies the text files to an unreadable format. + +####Documentation +* User Guide + * Added `Notes about command format` section. + * Added documentation for features `view game summary`, `view past records`, + `clear past records`and `automatic storage`. +* Developer Guide + * Added implementation details for the proposed `view statistics` feature. +####Project management +* Assigned issues created during practical examination dry-run to teammates responsible for those parts. +* Wrapped up milestones. +* Create issues for v1.0 user stories. + From 69e3ab93bc8c0884615366bdebdc837d2ca43776 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 17:24:39 +0800 Subject: [PATCH 202/272] Fix github pages rendering issues trial 1 --- docs/UserGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6b28a6df59..143ce5b39b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -100,6 +100,7 @@ Number of Correct Words: 30/30|100.00% Mistakes: No words typed wrongly. ================================================================== ``` + ### Clear past records: `clear` Clear all past game records Format: `clear [-g GAME_MODE] [-h]` @@ -111,6 +112,7 @@ Examples * `clear` Example of usage + ``` clear -g time ________ _________ ____ ____ ________________ ____ ____ _____ From d55313fe883b68707587a141a30c3b9df47b5d13 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 17:31:52 +0800 Subject: [PATCH 203/272] Fix github pages rendering issue trial 1 --- docs/team/limjiajing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index 86bebd54cd..ce6a09003f 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -7,14 +7,14 @@ familiar with the command line interface. There are two game modes in types, tim number of words as fast as possible). ### Summary of Contributions -####Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/#breakdown=true&search=limjiajing) +#### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/#breakdown=true&search=limjiajing) #### Contribution to code design Suggest having all command classes implement a common interface and using factory design pattern to create instantiate objects of classes which implement the interface for code to have less coupling. -####Enhancements implemented +#### Enhancements implemented 1. New feature: Added the summary feature that will show the game's summary after a game finishes. * What it does: Shows the summary of the game to gamers after they complete a game. Fields in the summary - @@ -48,14 +48,14 @@ for code to have less coupling. * Highlights: Extensive exception handling had to be done for the scenario where the gamer modifies the text files to an unreadable format. -####Documentation +#### Documentation * User Guide * Added `Notes about command format` section. * Added documentation for features `view game summary`, `view past records`, `clear past records`and `automatic storage`. * Developer Guide * Added implementation details for the proposed `view statistics` feature. -####Project management +#### Project management * Assigned issues created during practical examination dry-run to teammates responsible for those parts. * Wrapped up milestones. * Create issues for v1.0 user stories. From 8d9a9aa1926a06f26e5ec44b349cd41ed1c65e96 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 17:45:24 +0800 Subject: [PATCH 204/272] Fix github pages rendering issue trial 2 --- docs/UserGuide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 143ce5b39b..8328cfd3ab 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -112,7 +112,6 @@ Examples * `clear` Example of usage - ``` clear -g time ________ _________ ____ ____ ________________ ____ ____ _____ From a71a944b9a58f483b4100cce6fff14442e7c64f0 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 17:51:24 +0800 Subject: [PATCH 205/272] fix github pages rendering issue trial 2 --- docs/UserGuide.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8328cfd3ab..104581cef3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -49,9 +49,12 @@ After entering `content`, user can type an integer from 1-3 to choose from follo 1. Opening of famous books 2. Wikipedia article 3. Random sentence of custom length - + + + Examples * `content` `1` `3` + ### Open Game: `game` @@ -67,23 +70,31 @@ Format: `game GAME_MODE [-c]` * For Time Limit Game: * Format: `game -t TIME_LIMIT [-sn] [-c]` * START_NOW `-sn` allows user to start the game immediately without the "ready to start?" prompt. + + Examples * `game -t 30 -sn` * `game -w -c` + + ### View past records: `history` View past game records. Format: `history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` * NUMBER_OF_RECORDS defaults to all records if not provided * Possible arguments for GAME_MODE are - `word` or `time` - + + + Examples * `history -g time -n 10` -* `history -g word` - +* `history -g word` + + + Example of usage ``` history -g time -n 1 @@ -106,11 +117,15 @@ Clear all past game records Format: `clear [-g GAME_MODE] [-h]` * GAME_MODE defaults to `all` if not provided * Possible arguments for GAME_MODE are - `word`, `time` or `all` - + + + Examples * `clear -g time` * `clear` - + + + Example of usage ``` clear -g time @@ -133,7 +148,9 @@ The summary consists of the following fields: * Number of wrong words and its percentage * Number of correct words and its percentage * Wrongly and not typed words (Mistakes) - + + + Example of usage ``` _____ __ ____ _____ ______ ______ __ From 28b46c35f130302c236c7300f803e5da271adcbd Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 4 Nov 2021 20:13:13 +0800 Subject: [PATCH 206/272] update typist --- src/main/java/seedu/typists/common/Messages.java | 2 +- src/main/java/seedu/typists/game/TimeModeGame.java | 2 +- time-limited_records.txt | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 1aef77881d..2af0233d9d 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -5,7 +5,7 @@ */ public class Messages { public static final String LOGO = - " ______ _ __\n" + " ______ _ __\n" + " /_ __/_ ______ (_)____/ /_\n" + " / / / / / / __ \\/ / ___/ __/\n" + " / / / /_/ / /_/ / (__ ) /_\n" diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index e4396089b1..0d21356df4 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -42,7 +42,7 @@ public int getTimeLimit() { int n = Integer.parseInt(in.nextLine()); return isValidTime(n); } catch (NumberFormatException e) { - System.out.println("Invalid Number!"); + ui.printScreen("Invalid Number!"); } catch (InvalidCommandException e) { //repeat getTimeLimit } diff --git a/time-limited_records.txt b/time-limited_records.txt index 8b13789179..e69de29bb2 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1 +0,0 @@ - From fb64a69babf52a21eb75c630871e4ebb615a894d Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 21:06:41 +0800 Subject: [PATCH 207/272] Add user stories --- docs/DeveloperGuide.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 967c87f00e..f1edb32544 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -125,8 +125,11 @@ Our product is a typing game, intent to provide enjoyment for people who are fam |v1.0|user|customize the time limit to finish a game|train myself to type faster| |v1.0|user|customize the word limit, in multiples of 100|have an optimal gaming experience by being able to choose my preferred length of text for the game| |v1.0|user|choose text from famous books, randomly generated text or customized text for my game|make my gaming experience more fun and fulfilling| -|v2.0|user|view my game statistics after the game finishes|know how I fared| -|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| +|v1.0|typist|view my error rate|know on average, what my error rate is| +|v1.0|typist|see my word per minute after I've finished a game|know my typing speed| +|v2.0|gamer|view my past records|see how I have improved over time| +|v2.0|gamer|clear my past records|have a fresh start| +|v2.0|typist|see the words I typed wrongly after I've finished a game|know which words I have to practice more| ## Non-Functional Requirements From e88da31f685466ef1788cfa232c90de8ca22edb5 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 21:21:01 +0800 Subject: [PATCH 208/272] Edit ppp format for pdf conversion --- docs/team/limjiajing.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index ce6a09003f..2685b98bb9 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -16,16 +16,15 @@ for code to have less coupling. #### Enhancements implemented 1. New feature: Added the summary feature that will show the game's summary after a game finishes. - * What it does: Shows the summary of the game to gamers after they complete a game. - Fields in the summary - - `game mode`, `wpm`, `wrong word count`, `percentage of wrong words`, `correct word counts`, - `percentage of correct words` and `mistakes`. + * What it does: Shows the summary of the game to gamers after they complete a game. * Justification: This feature improves the project significantly because gamers mostly want to know how they did in a game. * Highlights: The logic of getting the mistakes made was fairly complicated as it required taking into considerations many conditions and scenarios. The implementation of this feature also affects the implementation of the `view history` feature, hence the design had to be well-thought-out. +

+ 2. New feature: Added the ability to view records of past games. * What it does: Allows gamers to select which game mode's past records they want to view and how many records (from the most recent) they want to view. Defaults to From 38400d2fbe19a2fb56b581106ea157a9d4dcc919 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 21:23:56 +0800 Subject: [PATCH 209/272] Edit ppp to fix github rendering trial 1 --- docs/team/limjiajing.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index 2685b98bb9..c3567c85c5 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -21,9 +21,7 @@ for code to have less coupling. want to know how they did in a game. * Highlights: The logic of getting the mistakes made was fairly complicated as it required taking into considerations many conditions and scenarios. The implementation of this feature also affects the implementation - of the `view history` feature, hence the design had to be well-thought-out. - -
+ of the `view history` feature, hence the design had to be well-thought-out. 2. New feature: Added the ability to view records of past games. * What it does: Allows gamers to select which game mode's past records they want to view From 97c8e5730d8b093e2182738e569870eca4414f7d Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 21:26:13 +0800 Subject: [PATCH 210/272] edit ppp format to fix github pages rendering issue --- docs/team/limjiajing.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index c3567c85c5..2035a0df90 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -15,15 +15,17 @@ design pattern to create instantiate objects of classes which implement the inte for code to have less coupling. #### Enhancements implemented -1. New feature: Added the summary feature that will show the game's summary after a game finishes. +* New feature: Added the summary feature that will show the game's summary after a game finishes. * What it does: Shows the summary of the game to gamers after they complete a game. * Justification: This feature improves the project significantly because gamers mostly want to know how they did in a game. * Highlights: The logic of getting the mistakes made was fairly complicated as it required taking into considerations many conditions and scenarios. The implementation of this feature also affects the implementation of the `view history` feature, hence the design had to be well-thought-out. - -2. New feature: Added the ability to view records of past games. + +
+ +* New feature: Added the ability to view records of past games. * What it does: Allows gamers to select which game mode's past records they want to view and how many records (from the most recent) they want to view. Defaults to all the records in the selected game mode if they do not specify the number to records to view. @@ -33,12 +35,14 @@ for code to have less coupling. * Highlights: The command related to this feature `history` has both optional and compulsory parameters. The parsing for this command was hence rather complicated to implement. -3. New feature: Added the ability to clear all past game records. + +* New feature: Added the ability to clear all past game records. * What it does: Clear the past game records of a selected game mode. If the game mode is not specified, game records from both game modes are wiped. * Justification: Gamers would at times like to clear their past records so that they can start afresh. -4. New feature: Added automatic storage of game records. + +* New feature: Added automatic storage of game records. * What it does: Automatically stores changes in game records to the corresponding text file (different text files for different game modes). * Justification: This feature is required for the `view history` feature. From 7b9bc7b5fb83a9203b6bca5cecab6d748df25612 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 21:29:25 +0800 Subject: [PATCH 211/272] Edit format to fix github pages rendering issue --- docs/team/limjiajing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index 2035a0df90..89a69a48f7 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -56,6 +56,7 @@ for code to have less coupling. `clear past records`and `automatic storage`. * Developer Guide * Added implementation details for the proposed `view statistics` feature. + #### Project management * Assigned issues created during practical examination dry-run to teammates responsible for those parts. * Wrapped up milestones. From f09e96bc2413508d21c749535cdc6b99037102cb Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Thu, 4 Nov 2021 21:35:05 +0800 Subject: [PATCH 212/272] Change RepoSense link to automatically how lim jia jing contributions --- docs/team/limjiajing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/team/limjiajing.md b/docs/team/limjiajing.md index 89a69a48f7..c6964a6d6d 100644 --- a/docs/team/limjiajing.md +++ b/docs/team/limjiajing.md @@ -7,7 +7,7 @@ familiar with the command line interface. There are two game modes in types, tim number of words as fast as possible). ### Summary of Contributions -#### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/#breakdown=true&search=limjiajing) +#### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&since=2021-09-25&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=LimJiaJing&tabRepo=AY2122S1-CS2113-T13-4%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false) #### Contribution to code design Suggest having all command classes implement a common interface and using factory From 04d4b4d9e714816798b71f27f282c791e6a90625 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Thu, 4 Nov 2021 23:55:45 +0800 Subject: [PATCH 213/272] update UG and fix -c bug --- docs/UserGuide.md | 140 ++++++++++++++---- src/main/java/META-INF/MANIFEST.MF | 3 + .../typists/command/TimeGameCommand.java | 7 +- .../typists/command/WordGameCommand.java | 6 +- time-limited_records.txt | 1 + 5 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 src/main/java/META-INF/MANIFEST.MF diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 51c8867f68..1685fe2bb0 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,23 +1,43 @@ # User Guide -* [Introduction](#introduction) -* [Quick Start](#quick-start) -* [Features](#features) -* [FAQ](#faq) -* [Command Summary](#command-summary) +1. [Introduction](#1-introduction) +2. [Quick Start](#2-quick-start) +3. [Features](#3-features) +4. [FAQ](#faq) +5. [Command Summary](#command-summary) -## Introduction +## 1. Introduction -Typist is a CLI typing game. +Welcome to Typist! The ultimate CLI typing game! +Go to [Quick Start](#quick-start) to get started! -## Quick Start +## 2. Quick Start -{Give steps to get started quickly} - -1. Ensure that you have Java 11 or above installed. -2. Down the latest version of `Typist` from [here](http://link.to/duke). -3. Navigate to the folder containing the jar file and run `java -jar tp.jar` +1. Ensure that you have Java 11 installed in your local environment. +2. Down the latest version of `Typist` from [here](https://github.com/AY2122S1-CS2113-T13-4/tp/releases). +3. Navigate to the folder containing the jar file and run `java -jar tp.jar`. +4. If everything goes well, the command interface should display the following: +``` + | Typist - Version 2.0 + | =========================================================== + | ______ _ __ + | /_ __/_ ______ (_)____/ /_ + | / / / / / / __ \/ / ___/ __/ + | / / / /_/ / /_/ / (__ ) /_ + | /_/ \__, / .___/_/____/\__/ + | /____/_/ + | Welcome to Typist -- the ultimate cli typing game. + | Brought to you by -- AY2122S1-CS2113-T13-4. + | Manual: + | content: set the content + | game -time: start a new time game + | game -word: start a new word game + | history -g GAME_MODE [-n NUMBER_OF_RECORDS]: view past game records + | clear [-g GAME_MODE]: clear all game records + | bye: exit typist + | =========================================================== +``` -## Features +## 3. Features ### Notes about the command format: @@ -37,10 +57,8 @@ ignored and the guide for that command will be displayed. e.g `history -g time -h -n 10` will be interpreted as `history -h`. * All parameters which do not conform to the command syntax will be ignored. e.g.2 `clear -gtime` will be interpreted as `clear` -### Usage -### Open Game -### Set Content: `content` +### 3.1 Set Content: `content` Set the typing content before the game. Format: `content` `1-3` `[optional]` @@ -54,23 +72,81 @@ Examples * `content` `1` `3` -### Open Game: `game` -Start a typing game. -Format: `game GAME_MODE [-c]` -* SET_CONTENT `-c` is optional, it allows user to set input content before game starts. +### 3.2 Open Game: `game` +Start a typing game. +Format: `game -GAME_MODE [GAME_LIMIT] [-c] [-sn]` + * GAME_MODE - * `-word` for game in Word Limit Mode - * `-time` for game in Time Limit Mode -* For Word Limit Game: - * Format: `game -word [-c]` - * Exit: `Exit` allows user to terminate the current game. -* For Time Limit Game: - * Format: `game -time TIME_LIMIT [-sn] [-c]` - * START_NOW `-sn` allows user to start the game immediately without the "ready to start?" prompt. + * `word` for game in Word Limit Mode + * `time` for game in Time Limit Mode +#### 3.2.1 Word Limit Game +* Format: `game -word [WORD_LIMIT] [-c] [-sn]` +* Example: `game -word` +* ``` + game -word + | Enter how many words you want the game to run: + 10 + | Timer will start once you entered "start": + start + | Lorem Ipsum is simply dummy + ``` +* Exit: `Exit` allows user to terminate the current game. + +#### 3.2.2 Time Limit Game +* Format: `game -time [TIME_LIMIT] [-c] [-sn]` +* Example: `game -time` +* ``` + game -time + | Enter how long you want the game to run: + 60 + | Timer will start once you entered "start": + start + | Lorem Ipsum is simply dummy text of the printing and + ``` + +#### Optional arguments +* SET_CONTENT `-c`: allows user to set input content before game starts. +* START_NOW `-sn`: allows timer to start immediately without the "start timer" prompt. +* GAME_LIMIT: integer that sets the word/time limit of the game + without the "enter limit" prompt. + > **NOTE**: + > if you want to specify GAME_LIMIT, it needs to be right after the GAME_MODE argument. + -Examples -* `game -time 30 -sn` -* `game -word -c` + +Example 1: `game -time 30` +Expected outcome: +``` +game -time 30 + | Timer will start once you entered "start": +start + | Lorem Ipsum is simply dummy text of the printing and +``` +Example 2: `game -time 30 -sn` +Expected outcome: +``` +game -time -sn + | Enter how long you want the game to run: +30 + | Lorem Ipsum is simply dummy text of the printing and +``` +Example 3: `game -word -c` +Expected outcome: +``` +(\ +\'\ + \'\ __________ + / '| ()_________) + \ '/ \ ~~~~~~~~ \ + \ \ ~~~~~~ \ + ==). \__________\ + (__) ()__________) + | Content selection (input 0 to go back): + | 1. Opening of famous books + | 2. Wikipedia article + | 3. Random sentence of custom length + | Enter your selection: +``` diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..69ea63b06f --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: seedu.typists.Main + diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index 9351b8e69b..a29426c975 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -16,12 +16,11 @@ public class TimeGameCommand extends GameCommand { @Override public Game createGame(ArrayList args, boolean isReady, boolean setContent) { - + if (setContent) { + content.setContent(); + } try { int timeInSeconds = getNumber(args, TIME_SIGNIFIER); - if (setContent) { - content.setContent(); - } return new TimeModeGame(content.getContent(), LINE_LENGTH, timeInSeconds, isReady); } catch (NumberFormatException | IncompleteCommandException | InvalidCommandException e) { return new TimeModeGame(content.getContent(), LINE_LENGTH, isReady); diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java index 9c66dfa4e2..d402a4e67b 100644 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -15,11 +15,11 @@ public class WordGameCommand extends GameCommand { @Override public Game createGame(ArrayList args, boolean isReady, boolean setContent) { //ui.printKeyBoard + if (setContent) { + content.setContent(); + } try { int wordLimit = getNumber(args, WORD_SIGNIFIER); - if (setContent) { - content.setContent(); - } return new WordLimitGame(content.getContent(), 5, wordLimit, isReady); } catch (InvalidCommandException e) { //won't come here. diff --git a/time-limited_records.txt b/time-limited_records.txt index e69de29bb2..cf129effb9 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -0,0 +1 @@ +Time-limited|39.172|9|1|10|90.0|10.0|1.5317063208414174|[Ipsum, is, simply, dummy, text, of, the, printing, and] From c8f677d3c61d6269477227a97a50e9076ff669f4 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 5 Nov 2021 00:17:31 +0800 Subject: [PATCH 214/272] Update UserGuide.md --- docs/UserGuide.md | 80 +++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1685fe2bb0..b866ea7e57 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -2,6 +2,14 @@ 1. [Introduction](#1-introduction) 2. [Quick Start](#2-quick-start) 3. [Features](#3-features) + 1. [Set Content](#31-set-content-content) + 2. [Open Game](#32-open-game-game) + 1. [Word Mode Game](#321-word-limit-game) + 2. [Time Mode Game](#322-time-limit-game) + 3. [View history](#33-view-past-records-history) + 4. [Clear history](#34-clear-past-records-clear) + 5. [Display Summary](#35-view-summary-of-game) + 6. [Save Data](#36-saving-the-data) 4. [FAQ](#faq) 5. [Command Summary](#command-summary) @@ -80,6 +88,9 @@ Format: `game -GAME_MODE [GAME_LIMIT] [-c] [-sn]` * `word` for game in Word Limit Mode * `time` for game in Time Limit Mode #### 3.2.1 Word Limit Game + In a Word-Limit game, user needs to specify the total number of words +they want to type. Game will terminate once they finish typing the specified +number of words. * Format: `game -word [WORD_LIMIT] [-c] [-sn]` * Example: `game -word` * ``` @@ -89,10 +100,18 @@ Format: `game -GAME_MODE [GAME_LIMIT] [-c] [-sn]` | Timer will start once you entered "start": start | Lorem Ipsum is simply dummy + lorem ipsum is simply dummy + | Your progress:5/10 ``` * Exit: `Exit` allows user to terminate the current game. #### 3.2.2 Time Limit Game +In a Time-Limit Game, user needs to specify the duration +they want to type. Timer will stop once the duration is reached +and terminates the game at the same time. +>**NOTE**: +> The time limit that user inputs needs to be a positive integer that represents time in seconds. +> It also needs to be multiple of 30. * Format: `game -time [TIME_LIMIT] [-c] [-sn]` * Example: `game -time` * ``` @@ -111,6 +130,7 @@ Format: `game -GAME_MODE [GAME_LIMIT] [-c] [-sn]` without the "enter limit" prompt. > **NOTE**: > if you want to specify GAME_LIMIT, it needs to be right after the GAME_MODE argument. + > If the GAME_LIMIT entered is invalid, game will still start but with the "enter limit" prompt. @@ -130,7 +150,7 @@ game -time -sn 30 | Lorem Ipsum is simply dummy text of the printing and ``` -Example 3: `game -word -c` +Example 3: `game -word 20 -sn -c` Expected outcome: ``` (\ @@ -150,7 +170,7 @@ Expected outcome: -### View past records: `history` +### 3.3 View past records: `history` View past game records. Format: `history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` * NUMBER_OF_RECORDS defaults to all records if not provided @@ -176,7 +196,7 @@ Number of Correct Words: 30/30|100.00% Mistakes: No words typed wrongly. ================================================================== ``` -### Clear past records: `clear` +### 3.4 Clear past records: `clear` Clear all past game records Format: `clear [-g GAME_MODE] [-h]` * GAME_MODE defaults to `all` if not provided @@ -198,7 +218,7 @@ clear -g time Successfully cleared Time-limited game records. ``` -### View summary of game +### 3.5 View summary of game View summary of a just-played game. Typists automatically generates and displays the summary after a game ends. The summary consists of the following fields: @@ -223,7 +243,7 @@ Number of Wrong Words: 0/30|0.00% Number of Correct Words: 30/30|100.00% Mistakes: No words typed wrongly. ``` -### Saving the data +### 3.6 Saving the data Typists automatically stores the game records (and any changes to them) into text files. @@ -233,48 +253,9 @@ Gamers should not edit the data it will manipulate the integrity of the records. In the event where the data is edited and the wrong format is inputted, the file contents will be cleared, hence losing all the game data. - - -### `Keyword` - Describe action - -List of the keywords are shown below: - -`content`-Set the content - -`game -word`-Enter a word-limited game mode - -`game -word -c`-Enter a word-limited game mode with content setting - ->Exit word-limited game mode command: `Exit` - -`time`-Enter a time-limited game mode - -`error`-Enter a error detecting game mode - -`bye`-Exit the program. - ### Showing summary of a game Statistics of game is shown automatically after a game is finished. -## Example of usage: - -``` -game -word - | Enter how many words you want the game to run: -5 - | lorem ipsum is simply dummy -lorem ipsum is simply dummy - | Your progress:5/5 -``` -``` -game -time 30 -sn - | lorem ipsum is simply dummy text of the printing and -lorem ipsum is simply dummy text of the printing and - | typesetting imply dummy text of the printing and typesetting industry -typesetting imply dummy text of the printing and typesetting industry - | Timer's UP! -``` - ## FAQ @@ -285,8 +266,11 @@ typesetting imply dummy text of the printing and typesetting industry ## Command Summary -| Feature | Command | +| Command | Action | | ------------- | ------------- | -| Start Word Limit Game| `game -word [-c]` | -| Start Time Limit Game | `game -time TIME_LIMIT [-sn] [-c]` -| Get History | `history -h`| \ No newline at end of file +|`content`| Set the content +|`game -word [WORD_LIMIT] [-sn] [-c]` | Start a word-limited game +|`game -time [TIME_LIMIT] [-sn] [-c]` | Start a time-limited game +|`history -h` | Get history +|`history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` | Clear history +|`bye`| Exit the program From a8101d836de21e9c042416874445899455a63c4a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 5 Nov 2021 00:22:12 +0800 Subject: [PATCH 215/272] Update TextUi.java --- src/main/java/seedu/typists/ui/TextUi.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index ea9332cf60..8c73676d76 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -37,9 +37,10 @@ public class TextUi { private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); - - //get current timestamp - //unused because it interferes with the EXPECTED.TXT in runtest + /** Get current timestamp. + * Unused because it interferes with the EXPECTED.TXT in runtest + * @return current time in yyyy-mm-dd hh:mm:ss format + */ public String getTimeStamp() { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); return timeFormatter.format(timestamp); From b5287af1914e31dc2e7ca7e721866181d8dcfc9c Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 5 Nov 2021 09:23:17 +0800 Subject: [PATCH 216/272] Update UserGuide.md --- docs/UserGuide.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b866ea7e57..3b4827aecf 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -253,11 +253,6 @@ Gamers should not edit the data it will manipulate the integrity of the records. In the event where the data is edited and the wrong format is inputted, the file contents will be cleared, hence losing all the game data. -### Showing summary of a game -Statistics of game is shown automatically after a game is finished. - - - ## FAQ **Q**: How do I transfer my data to another computer? @@ -270,7 +265,7 @@ Statistics of game is shown automatically after a game is finished. | ------------- | ------------- | |`content`| Set the content |`game -word [WORD_LIMIT] [-sn] [-c]` | Start a word-limited game -|`game -time [TIME_LIMIT] [-sn] [-c]` | Start a time-limited game -|`history -h` | Get history +|`game -time [TIME_LIMIT] [-sn] [-c]` | Start a time-limited game |`history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` | Clear history +|`clear` | Clear history |`bye`| Exit the program From 39265261d52418624ed275ac757da3040343ce44 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 5 Nov 2021 13:16:51 +0800 Subject: [PATCH 217/272] update UG --- docs/DeveloperGuide.md | 3 ++- docs/UserGuide.md | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d383f78bec..e0016f8b94 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,6 +1,7 @@ # Developer Guide * [Acknowledgements](#acknowledgements) +* [Setting Up, getting started](#setting-up-getting-started) * [Design](#design) * [Architecture](#architecture) * [Implementation](#implementation) @@ -15,7 +16,7 @@ * https://www.baeldung.com/java-testing-system-out-println * https://github.com/fastily/jwiki - +## Setting Up, getting started ## Design diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b9a0605ec5..2b8c7e2400 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -115,6 +115,7 @@ and terminates the game at the same time. >**NOTE**: > The time limit that user inputs needs to be a positive integer that represents time in seconds. > It also needs to be multiple of 30. + * Format: `game -time [TIME_LIMIT] [-c] [-sn]` * Example: `game -time` * ``` @@ -124,12 +125,19 @@ and terminates the game at the same time. | Timer will start once you entered "start": start | Lorem Ipsum is simply dummy text of the printing and + Lorem Ipsum is simply dummy text of the printing and + | Timer's Up! ``` + **Exceeding Time:** + When you are at the last sentence. Even though Timer is up, the game will wait + until you finish the last sentence to terminate. You will be informed of the exceeding time, + and it will count towards your game summary. + #### Optional arguments * SET_CONTENT `-c`: allows user to set input content before game starts. * START_NOW `-sn`: allows timer to start immediately without the "start timer" prompt. -* GAME_LIMIT: integer that sets the word/time limit of the game +* GAME_LIMIT: a positive integer that sets the word/time limit of the game without the "enter limit" prompt. > **NOTE**: > if you want to specify GAME_LIMIT, it needs to be right after the GAME_MODE argument. From 64a78b331025b24b6465439d02db1308518bf9c6 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Fri, 5 Nov 2021 23:33:33 +0800 Subject: [PATCH 218/272] rename uml folder into diagram --- docs/DeveloperGuide.md | 26 +++++++++++------- docs/{uml => diagrams}/Content.png | Bin docs/{uml => diagrams}/Style.puml | 0 docs/{uml => diagrams}/TimeLimitGame.puml | 0 .../ViewStatistics-1.drawio.svg | 0 .../ViewStatistics-2.drawio.svg | 0 .../ViewStatistics-3.drawio.svg | 0 .../ViewStatistics-4.drawio.svg | 0 .../ViewStatistics-5.drawio.svg | 0 docs/{uml => diagrams}/WordLimitMode.png | Bin docs/{uml => diagrams}/WordLimitMode.puml | 0 11 files changed, 16 insertions(+), 10 deletions(-) rename docs/{uml => diagrams}/Content.png (100%) rename docs/{uml => diagrams}/Style.puml (100%) rename docs/{uml => diagrams}/TimeLimitGame.puml (100%) rename docs/{uml => diagrams}/ViewStatistics-1.drawio.svg (100%) rename docs/{uml => diagrams}/ViewStatistics-2.drawio.svg (100%) rename docs/{uml => diagrams}/ViewStatistics-3.drawio.svg (100%) rename docs/{uml => diagrams}/ViewStatistics-4.drawio.svg (100%) rename docs/{uml => diagrams}/ViewStatistics-5.drawio.svg (100%) rename docs/{uml => diagrams}/WordLimitMode.png (100%) rename docs/{uml => diagrams}/WordLimitMode.puml (100%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e0016f8b94..1d944a456f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,5 +1,7 @@ - # Developer Guide +* Table of Contents + {:toc} + * [Acknowledgements](#acknowledgements) * [Setting Up, getting started](#setting-up-getting-started) * [Design](#design) @@ -12,14 +14,18 @@ ## Acknowledgements -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +{list here sources of all reused/adapted ideas, code, documentation, +and third-party libraries -- include links to the original source as well} * https://www.baeldung.com/java-testing-system-out-println * https://github.com/fastily/jwiki ## Setting Up, getting started - +{Instruction to set up project in intellij} ## Design + +:bulb: **Tip:** The `.puml` files used to create diagrams in this document +can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. ### Architecture (Some architecture diagram) @@ -42,7 +48,7 @@ There are 3 types: The following UML diagram illustrates the way content selection works in the program. -![](uml/Content.png) +![](diagrams/Content.png) There only exists one private content string for all sessions. Each time a set method is called, the string is changed depending on the choices that the user made throughout the process. Whenever the user starts a game, the getContent() @@ -54,7 +60,7 @@ Once the CommandFactory reads a 'word' command, a word limit game will begin. Gonna to change this .puml diagram later - zhansen -![](uml/WordLimitMode.png) +![](diagrams/WordLimitMode.png) ### Time Limit Game Sequence Diagram for Time Mode Game: @@ -83,24 +89,24 @@ Step 2: The user executes `view -m best -g time -n 4` to view his/her best stati Step 3: A ViewCommand object is then instantiated. -![Alt text](uml/ViewStatistics-1.drawio.svg) +![Alt text](diagrams/ViewStatistics-1.drawio.svg) Step 4. ViewCommand calls the retrieveStatistics() method of StatisticsManager. -![Alt text](uml/ViewStatistics-2.drawio.svg) +![Alt text](diagrams/ViewStatistics-2.drawio.svg) Step 5: StatisticsManager creates a GameRecordsManager object. * The constructor of GameRecordsManager calls the readGameRecords() method of the Storage class to retrieve the gamer's past game records from the text files. -![Alt text](uml/ViewStatistics-3.drawio.svg) +![Alt text](diagrams/ViewStatistics-3.drawio.svg) Step 6. StatisticsManager then calls getGamesRecords() method of GameRecordsManager() and self-invokes calculateBestStatistics(). * Calculated statistics is returned. Step 7. ViewCommand calls the displayStatistics() method of the ViewCommandUi class to display the statistics. -![Alt test](uml/ViewStatistics-4.drawio.svg) +![Alt test](diagrams/ViewStatistics-4.drawio.svg) The following sequence diagram shows how the above scenario is executed. -![Alt test](uml/ViewStatistics-5.drawio.svg) +![Alt test](diagrams/ViewStatistics-5.drawio.svg) diff --git a/docs/uml/Content.png b/docs/diagrams/Content.png similarity index 100% rename from docs/uml/Content.png rename to docs/diagrams/Content.png diff --git a/docs/uml/Style.puml b/docs/diagrams/Style.puml similarity index 100% rename from docs/uml/Style.puml rename to docs/diagrams/Style.puml diff --git a/docs/uml/TimeLimitGame.puml b/docs/diagrams/TimeLimitGame.puml similarity index 100% rename from docs/uml/TimeLimitGame.puml rename to docs/diagrams/TimeLimitGame.puml diff --git a/docs/uml/ViewStatistics-1.drawio.svg b/docs/diagrams/ViewStatistics-1.drawio.svg similarity index 100% rename from docs/uml/ViewStatistics-1.drawio.svg rename to docs/diagrams/ViewStatistics-1.drawio.svg diff --git a/docs/uml/ViewStatistics-2.drawio.svg b/docs/diagrams/ViewStatistics-2.drawio.svg similarity index 100% rename from docs/uml/ViewStatistics-2.drawio.svg rename to docs/diagrams/ViewStatistics-2.drawio.svg diff --git a/docs/uml/ViewStatistics-3.drawio.svg b/docs/diagrams/ViewStatistics-3.drawio.svg similarity index 100% rename from docs/uml/ViewStatistics-3.drawio.svg rename to docs/diagrams/ViewStatistics-3.drawio.svg diff --git a/docs/uml/ViewStatistics-4.drawio.svg b/docs/diagrams/ViewStatistics-4.drawio.svg similarity index 100% rename from docs/uml/ViewStatistics-4.drawio.svg rename to docs/diagrams/ViewStatistics-4.drawio.svg diff --git a/docs/uml/ViewStatistics-5.drawio.svg b/docs/diagrams/ViewStatistics-5.drawio.svg similarity index 100% rename from docs/uml/ViewStatistics-5.drawio.svg rename to docs/diagrams/ViewStatistics-5.drawio.svg diff --git a/docs/uml/WordLimitMode.png b/docs/diagrams/WordLimitMode.png similarity index 100% rename from docs/uml/WordLimitMode.png rename to docs/diagrams/WordLimitMode.png diff --git a/docs/uml/WordLimitMode.puml b/docs/diagrams/WordLimitMode.puml similarity index 100% rename from docs/uml/WordLimitMode.puml rename to docs/diagrams/WordLimitMode.puml From 75846baf30352be14a76de8669dbd26172d5bf98 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 00:05:36 +0800 Subject: [PATCH 219/272] delete MANIFEST, update DG --- docs/DeveloperGuide.md | 17 +++++++++++++++-- src/main/java/META-INF/MANIFEST.MF | 3 --- 2 files changed, 15 insertions(+), 5 deletions(-) delete mode 100644 src/main/java/META-INF/MANIFEST.MF diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1d944a456f..1895f1e49a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -24,10 +24,23 @@ and third-party libraries -- include links to the original source as well} ## Design -:bulb: **Tip:** The `.puml` files used to create diagrams in this document -can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. +> :bulb: **Tip:** The `.puml` files used to create diagrams in this document +> can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. + ### Architecture (Some architecture diagram) +The Architecture diagram above explains the high-level design of the Typists app. +Given below is a quick overview of main components and how they interact with each other. + +**Main Components of the architecture** +The `Main` class is the entry point of Typist. It is responsible for parsing and running various user's command. + +The other core components of Typist: +* `ui`: The Ui of the app. +* `command`: Consists of `CommandFactory` which parses user inputs, and various `command` objects. +* `common`: A collection of classes used by multiple other components. +* `` + ## Implementation diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF deleted file mode 100644 index 69ea63b06f..0000000000 --- a/src/main/java/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: seedu.typists.Main - From 2bdf0cc1301784496af4fa0c11fb58a605261f0c Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 00:06:09 +0800 Subject: [PATCH 220/272] delete data folder and gamerInfo --- src/main/java/seedu/typists/data/GamerInfo.java | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/main/java/seedu/typists/data/GamerInfo.java diff --git a/src/main/java/seedu/typists/data/GamerInfo.java b/src/main/java/seedu/typists/data/GamerInfo.java deleted file mode 100644 index e653a8e3c3..0000000000 --- a/src/main/java/seedu/typists/data/GamerInfo.java +++ /dev/null @@ -1,9 +0,0 @@ -package seedu.typists.data; - - -/** - * Contains the data of the entire game. - */ -public class GamerInfo { - -} From 5b6844319f69a7c6a83b1c5029537fc202c4fafa Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 00:15:31 +0800 Subject: [PATCH 221/272] move exception folder into common foler --- docs/DeveloperGuide.md | 3 ++- src/main/java/seedu/typists/command/TimeGameCommand.java | 4 ++-- .../typists/{ => common}/exception/ExceedRangeException.java | 2 +- .../typists/{ => common}/exception/FaultyInputException.java | 2 +- .../{ => common}/exception/IncompleteCommandException.java | 2 +- .../{ => common}/exception/InvalidArticleException.java | 2 +- .../{ => common}/exception/InvalidCommandException.java | 2 +- .../{ => common}/exception/InvalidStringInputException.java | 2 +- src/main/java/seedu/typists/content/WikiImport.java | 2 +- src/test/java/seedu/StringParserTest.java | 2 +- 10 files changed, 12 insertions(+), 11 deletions(-) rename src/main/java/seedu/typists/{ => common}/exception/ExceedRangeException.java (58%) rename src/main/java/seedu/typists/{ => common}/exception/FaultyInputException.java (78%) rename src/main/java/seedu/typists/{ => common}/exception/IncompleteCommandException.java (75%) rename src/main/java/seedu/typists/{ => common}/exception/InvalidArticleException.java (79%) rename src/main/java/seedu/typists/{ => common}/exception/InvalidCommandException.java (84%) rename src/main/java/seedu/typists/{ => common}/exception/InvalidStringInputException.java (81%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1895f1e49a..9707ee7330 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -39,7 +39,8 @@ The other core components of Typist: * `ui`: The Ui of the app. * `command`: Consists of `CommandFactory` which parses user inputs, and various `command` objects. * `common`: A collection of classes used by multiple other components. -* `` +* `content`: holds the content and logic for `content` command +* `exception`: holds the ## Implementation diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index a29426c975..ab41c674b1 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -1,7 +1,7 @@ package seedu.typists.command; -import seedu.typists.exception.IncompleteCommandException; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.IncompleteCommandException; +import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.Game; import seedu.typists.game.TimeModeGame; diff --git a/src/main/java/seedu/typists/exception/ExceedRangeException.java b/src/main/java/seedu/typists/common/exception/ExceedRangeException.java similarity index 58% rename from src/main/java/seedu/typists/exception/ExceedRangeException.java rename to src/main/java/seedu/typists/common/exception/ExceedRangeException.java index 73dfdcada5..17c9cf2809 100644 --- a/src/main/java/seedu/typists/exception/ExceedRangeException.java +++ b/src/main/java/seedu/typists/common/exception/ExceedRangeException.java @@ -1,4 +1,4 @@ -package seedu.typists.exception; +package seedu.typists.common.exception; public class ExceedRangeException extends Throwable { } diff --git a/src/main/java/seedu/typists/exception/FaultyInputException.java b/src/main/java/seedu/typists/common/exception/FaultyInputException.java similarity index 78% rename from src/main/java/seedu/typists/exception/FaultyInputException.java rename to src/main/java/seedu/typists/common/exception/FaultyInputException.java index d7c4e303b7..91bfc7a32d 100644 --- a/src/main/java/seedu/typists/exception/FaultyInputException.java +++ b/src/main/java/seedu/typists/common/exception/FaultyInputException.java @@ -1,4 +1,4 @@ -package seedu.typists.exception; +package seedu.typists.common.exception; public class FaultyInputException extends Exception { public FaultyInputException(String errorMessage) { diff --git a/src/main/java/seedu/typists/exception/IncompleteCommandException.java b/src/main/java/seedu/typists/common/exception/IncompleteCommandException.java similarity index 75% rename from src/main/java/seedu/typists/exception/IncompleteCommandException.java rename to src/main/java/seedu/typists/common/exception/IncompleteCommandException.java index becb0ed3af..9a47ea69b7 100644 --- a/src/main/java/seedu/typists/exception/IncompleteCommandException.java +++ b/src/main/java/seedu/typists/common/exception/IncompleteCommandException.java @@ -1,4 +1,4 @@ -package seedu.typists.exception; +package seedu.typists.common.exception; public class IncompleteCommandException extends Exception { //thrown when the command enter is missing key pointns diff --git a/src/main/java/seedu/typists/exception/InvalidArticleException.java b/src/main/java/seedu/typists/common/exception/InvalidArticleException.java similarity index 79% rename from src/main/java/seedu/typists/exception/InvalidArticleException.java rename to src/main/java/seedu/typists/common/exception/InvalidArticleException.java index 29d729d850..a18316ecf2 100644 --- a/src/main/java/seedu/typists/exception/InvalidArticleException.java +++ b/src/main/java/seedu/typists/common/exception/InvalidArticleException.java @@ -1,4 +1,4 @@ -package seedu.typists.exception; +package seedu.typists.common.exception; public class InvalidArticleException extends Exception { @Override diff --git a/src/main/java/seedu/typists/exception/InvalidCommandException.java b/src/main/java/seedu/typists/common/exception/InvalidCommandException.java similarity index 84% rename from src/main/java/seedu/typists/exception/InvalidCommandException.java rename to src/main/java/seedu/typists/common/exception/InvalidCommandException.java index c5c821c4af..5b851d86ab 100644 --- a/src/main/java/seedu/typists/exception/InvalidCommandException.java +++ b/src/main/java/seedu/typists/common/exception/InvalidCommandException.java @@ -1,4 +1,4 @@ -package seedu.typists.exception; +package seedu.typists.common.exception; public class InvalidCommandException extends Exception { public InvalidCommandException(String errorMessage) { diff --git a/src/main/java/seedu/typists/exception/InvalidStringInputException.java b/src/main/java/seedu/typists/common/exception/InvalidStringInputException.java similarity index 81% rename from src/main/java/seedu/typists/exception/InvalidStringInputException.java rename to src/main/java/seedu/typists/common/exception/InvalidStringInputException.java index 4e183fecd9..9b476fef86 100644 --- a/src/main/java/seedu/typists/exception/InvalidStringInputException.java +++ b/src/main/java/seedu/typists/common/exception/InvalidStringInputException.java @@ -1,4 +1,4 @@ -package seedu.typists.exception; +package seedu.typists.common.exception; public class InvalidStringInputException extends Exception { @Override diff --git a/src/main/java/seedu/typists/content/WikiImport.java b/src/main/java/seedu/typists/content/WikiImport.java index b24b09d492..f85bcc4f8d 100644 --- a/src/main/java/seedu/typists/content/WikiImport.java +++ b/src/main/java/seedu/typists/content/WikiImport.java @@ -1,7 +1,7 @@ package seedu.typists.content; import org.fastily.jwiki.core.Wiki; -import seedu.typists.exception.InvalidArticleException; +import seedu.typists.common.exception.InvalidArticleException; /** * Imports the first paragraph of a text from Wikipedia. diff --git a/src/test/java/seedu/StringParserTest.java b/src/test/java/seedu/StringParserTest.java index 58e2493986..909f7285b8 100644 --- a/src/test/java/seedu/StringParserTest.java +++ b/src/test/java/seedu/StringParserTest.java @@ -1,7 +1,7 @@ package seedu; import org.junit.jupiter.api.Test; -import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.common.exception.InvalidStringInputException; import seedu.typists.parser.StringParser; import java.util.ArrayList; From f3dd0ba8c0c86fc07866a68177859553fdb99b21 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 00:19:31 +0800 Subject: [PATCH 222/272] refactor packages move StringParser class to common folder. delete the parser folder which only had StringParser class inside. --- docs/DeveloperGuide.md | 3 ++- src/main/java/seedu/typists/command/ClearCommand.java | 2 +- src/main/java/seedu/typists/command/GameCommand.java | 7 ++----- src/main/java/seedu/typists/command/HistoryCommand.java | 2 +- src/main/java/seedu/typists/command/WordGameCommand.java | 4 ++-- .../seedu/typists/{parser => common}/StringParser.java | 4 ++-- src/main/java/seedu/typists/common/Utils.java | 7 ++----- src/main/java/seedu/typists/content/Content.java | 2 +- src/main/java/seedu/typists/game/TimeModeGame.java | 4 ++-- src/main/java/seedu/typists/game/WordLimitGame.java | 8 ++++---- src/test/java/seedu/StringParserTest.java | 2 +- src/test/java/seedu/UtilsTest.java | 2 +- src/test/java/seedu/WikiImportTest.java | 2 +- 13 files changed, 22 insertions(+), 27 deletions(-) rename src/main/java/seedu/typists/{parser => common}/StringParser.java (88%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9707ee7330..8c1436c7c2 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -40,7 +40,8 @@ The other core components of Typist: * `command`: Consists of `CommandFactory` which parses user inputs, and various `command` objects. * `common`: A collection of classes used by multiple other components. * `content`: holds the content and logic for `content` command -* `exception`: holds the +* `game`: game, game summary and game record executor. +* ## Implementation diff --git a/src/main/java/seedu/typists/command/ClearCommand.java b/src/main/java/seedu/typists/command/ClearCommand.java index 3f47153df1..5bdfb43470 100644 --- a/src/main/java/seedu/typists/command/ClearCommand.java +++ b/src/main/java/seedu/typists/command/ClearCommand.java @@ -1,6 +1,6 @@ package seedu.typists.command; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.GameRecordsManager; import seedu.typists.ui.ClearCommandUi; diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/GameCommand.java index 9d31ac21a7..b5322fbd8f 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/GameCommand.java @@ -1,15 +1,12 @@ package seedu.typists.command; -import seedu.typists.exception.IncompleteCommandException; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.IncompleteCommandException; +import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.Game; -import seedu.typists.game.WordLimitGame; import seedu.typists.ui.GameUi; import java.util.ArrayList; -import static seedu.typists.Main.content; -import static seedu.typists.Main.uiBot; import static seedu.typists.Main.LINE_LENGTH; public abstract class GameCommand implements Command { diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/HistoryCommand.java index 846b41553c..1041e081c8 100644 --- a/src/main/java/seedu/typists/command/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/HistoryCommand.java @@ -1,6 +1,6 @@ package seedu.typists.command; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.GameRecord; import seedu.typists.game.GameRecordsManager; import seedu.typists.ui.HistoryCommandUi; diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/WordGameCommand.java index d402a4e67b..d9170c5ef0 100644 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/WordGameCommand.java @@ -1,7 +1,7 @@ package seedu.typists.command; -import seedu.typists.exception.IncompleteCommandException; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.IncompleteCommandException; +import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.Game; import seedu.typists.game.WordLimitGame; diff --git a/src/main/java/seedu/typists/parser/StringParser.java b/src/main/java/seedu/typists/common/StringParser.java similarity index 88% rename from src/main/java/seedu/typists/parser/StringParser.java rename to src/main/java/seedu/typists/common/StringParser.java index da1d606c39..16f7228e26 100644 --- a/src/main/java/seedu/typists/parser/StringParser.java +++ b/src/main/java/seedu/typists/common/StringParser.java @@ -1,9 +1,9 @@ -package seedu.typists.parser; +package seedu.typists.common; import java.util.ArrayList; import java.util.Arrays; -import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.common.exception.InvalidStringInputException; public class StringParser { diff --git a/src/main/java/seedu/typists/common/Utils.java b/src/main/java/seedu/typists/common/Utils.java index 8c13bb10bf..b23a04cdc9 100644 --- a/src/main/java/seedu/typists/common/Utils.java +++ b/src/main/java/seedu/typists/common/Utils.java @@ -1,15 +1,12 @@ package seedu.typists.common; -import seedu.typists.exception.ExceedRangeException; -import seedu.typists.exception.FaultyInputException; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.ExceedRangeException; +import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.ui.TextUi; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Utility methods. diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index a3b730e50d..181f69e95a 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -1,6 +1,6 @@ package seedu.typists.content; -import seedu.typists.exception.InvalidArticleException; +import seedu.typists.common.exception.InvalidArticleException; import seedu.typists.ui.TextUi; import java.util.Random; diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeModeGame.java index 0d21356df4..69a79a417d 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeModeGame.java @@ -1,7 +1,7 @@ package seedu.typists.game; -import seedu.typists.exception.ExceedRangeException; -import seedu.typists.exception.InvalidCommandException; +import seedu.typists.common.exception.ExceedRangeException; +import seedu.typists.common.exception.InvalidCommandException; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index c1b6c1cc1d..5064b86207 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -1,8 +1,8 @@ package seedu.typists.game; -import seedu.typists.exception.ExceedRangeException; -import seedu.typists.exception.InvalidCommandException; -import seedu.typists.exception.InvalidStringInputException; +import seedu.typists.common.exception.ExceedRangeException; +import seedu.typists.common.exception.InvalidCommandException; +import seedu.typists.common.exception.InvalidStringInputException; import seedu.typists.ui.TextUi; import java.util.ArrayList; @@ -13,7 +13,7 @@ import static seedu.typists.common.Utils.getDisplayLinesWithoutNull; import static seedu.typists.common.Utils.getWordLineFromStringArray; -import static seedu.typists.parser.StringParser.splitString; +import static seedu.typists.common.StringParser.splitString; public class WordLimitGame extends Game { private ArrayList eachWord; diff --git a/src/test/java/seedu/StringParserTest.java b/src/test/java/seedu/StringParserTest.java index 909f7285b8..7298fa82b1 100644 --- a/src/test/java/seedu/StringParserTest.java +++ b/src/test/java/seedu/StringParserTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; import seedu.typists.common.exception.InvalidStringInputException; -import seedu.typists.parser.StringParser; +import seedu.typists.common.StringParser; import java.util.ArrayList; diff --git a/src/test/java/seedu/UtilsTest.java b/src/test/java/seedu/UtilsTest.java index cc18e2f98c..8a36b0f1f3 100644 --- a/src/test/java/seedu/UtilsTest.java +++ b/src/test/java/seedu/UtilsTest.java @@ -1,7 +1,7 @@ package seedu; import org.junit.jupiter.api.Test; -import seedu.typists.exception.ExceedRangeException; +import seedu.typists.common.exception.ExceedRangeException; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/seedu/WikiImportTest.java b/src/test/java/seedu/WikiImportTest.java index 75cb546e15..5683fc91dc 100644 --- a/src/test/java/seedu/WikiImportTest.java +++ b/src/test/java/seedu/WikiImportTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; import seedu.typists.content.WikiImport; -import seedu.typists.exception.InvalidArticleException; +import seedu.typists.common.exception.InvalidArticleException; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; From 1357e11869d384d62dd106dbbc194cdda89a7449 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Sat, 6 Nov 2021 16:32:03 +0800 Subject: [PATCH 223/272] Updates --- docs/DeveloperGuide.md | 13 +---- docs/team/williamwahyudi.md | 3 ++ src/main/java/seedu/typists/common/Error.java | 47 ------------------- .../java/seedu/typists/content/Animation.java | 24 ---------- .../java/seedu/typists/content/Content.java | 18 +++++-- src/main/java/seedu/typists/ui/TextUi.java | 47 ------------------- time-limited_records.txt | 3 +- word-limited_records.txt | 5 ++ 8 files changed, 27 insertions(+), 133 deletions(-) delete mode 100644 src/main/java/seedu/typists/common/Error.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d383f78bec..f1ceada99d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -16,8 +16,6 @@ * https://github.com/fastily/jwiki - - ## Design ### Architecture (Some architecture diagram) @@ -114,14 +112,13 @@ Single Responsibility Principle. ## Product scope Our product is a typing game, intent to provide enjoyment for people who are familiar with the CML. - ### Target user profile -{Describe the target user profile} +The target user profile includes bored people who are looking for a fun way to entertain themselves while working on the command line. ### Value proposition -{Describe the value proposition: what problem does it solve?} +It solves the lack of entertainment alternatives on the CLI. ## User Stories @@ -137,12 +134,6 @@ Our product is a typing game, intent to provide enjoyment for people who are fam |v2.0|gamer|clear my past records|have a fresh start| |v2.0|typist|see the words I typed wrongly after I've finished a game|know which words I have to practice more| -## Non-Functional Requirements - -{Give non-functional requirements} -### Animation - - ## Glossary * *glossary item* - Definition diff --git a/docs/team/williamwahyudi.md b/docs/team/williamwahyudi.md index 70abee6cbd..0a5fa8e598 100644 --- a/docs/team/williamwahyudi.md +++ b/docs/team/williamwahyudi.md @@ -4,3 +4,6 @@ ### Summary of Contributions +#### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&since=2021-09-25&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=maxwireddevs&tabRepo=AY2122S1-CS2113-T13-4%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false) + + diff --git a/src/main/java/seedu/typists/common/Error.java b/src/main/java/seedu/typists/common/Error.java deleted file mode 100644 index 93432ae250..0000000000 --- a/src/main/java/seedu/typists/common/Error.java +++ /dev/null @@ -1,47 +0,0 @@ -package seedu.typists.common; - -import java.util.ArrayList; - -import static java.lang.Math.abs; -import static java.lang.Math.min; - -/** - * Error rate calculator. - */ -public class Error { - public int wordLengthDifference(String word, String typed) { - return Math.abs(word.length() - typed.length()); - } - - public int wordCharacterDifference(String word, String typed) { - int charDiff = 0; - for (int i = 0; i < min(word.length(), typed.length()); i++) { - charDiff += (word.charAt(i) != typed.charAt(i) ? 1 : 0); - } - return charDiff + wordLengthDifference(word, typed); - } - - public double wordErrorRate(String word, String typed) { - return (double) wordCharacterDifference(word, typed) / word.length(); - } - - public int sentenceLengthDifference(ArrayList content, ArrayList typed) { - return abs(content.size() - typed.size()); - } - - public double sentenceErrorRate(ArrayList content, ArrayList typed) { - double temp = 0.0; - for (int i = 0; i < min(content.size(), typed.size()); i++) { - temp += wordErrorRate(content.get(i), typed.get(i)); - } - return temp / (double) min(content.size(), typed.size()); - } - - public int wrongWordCount(ArrayList content, ArrayList typed) { - int temp = 0; - for (int i = 0; i < min(content.size(), typed.size()); i++) { - temp += (content.get(i).equals(typed.get(i)) ? 0 : 1); - } - return temp; - } -} diff --git a/src/main/java/seedu/typists/content/Animation.java b/src/main/java/seedu/typists/content/Animation.java index 392771156b..632277a4e7 100644 --- a/src/main/java/seedu/typists/content/Animation.java +++ b/src/main/java/seedu/typists/content/Animation.java @@ -18,30 +18,6 @@ public void print(String line) { lastLine = line; } - private byte animWait; - - public void resetAnimWait() { - animWait = 1; - } - - public void animateWait(String s) { - switch (animWait) { - case 1: - print("[ \\ ] " + s); - break; - case 2: - print("[ | ] " + s); - break; - case 3: - print("[ / ] " + s); - break; - default: - animWait = 0; - print("[ - ] " + s); - } - animWait++; - } - private byte animLeft; private byte animRight; diff --git a/src/main/java/seedu/typists/content/Content.java b/src/main/java/seedu/typists/content/Content.java index a3b730e50d..06142791a6 100644 --- a/src/main/java/seedu/typists/content/Content.java +++ b/src/main/java/seedu/typists/content/Content.java @@ -71,7 +71,11 @@ private void setBooks() { } else { this.content = Books.getBook(selection - 1); assert this.content.length() > 0; - ui.printLine("Content set"); + try { + ui.viewAnimateLeft("Content set"); + } catch (InterruptedException e) { + e.printStackTrace(); + } } } @@ -92,7 +96,11 @@ private void setWikipedia() { articleNotFound = false; this.content = temp; assert this.content.length() > 0; - ui.printLine("Content set"); + try { + ui.viewAnimateLeft("Content set"); + } catch (InterruptedException e) { + e.printStackTrace(); + } } catch (InvalidArticleException e) { ui.printLine(e.getMessage()); } @@ -123,7 +131,11 @@ private void setRandomContent() { } this.content = s; assert this.content.length() > 0; - ui.printLine("Content set"); + try { + ui.viewAnimateLeft("Content set"); + } catch (InterruptedException e) { + e.printStackTrace(); + } } } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index ea9332cf60..a716e8a86e 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -1,10 +1,7 @@ package seedu.typists.ui; -import seedu.typists.common.Error; import seedu.typists.content.Animation; -import java.math.BigDecimal; -import java.math.MathContext; import java.sql.Timestamp; import java.text.SimpleDateFormat; @@ -17,13 +14,8 @@ import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; import static seedu.typists.common.Messages.MESSAGE_HELP; import static seedu.typists.common.Messages.MESSAGE_WELCOME; -import static seedu.typists.common.Messages.SUMMARY; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.List; -import java.util.ArrayList; import java.util.Scanner; @@ -139,43 +131,4 @@ public void viewAnimateRight(String string) throws InterruptedException { } System.out.println(""); } - - public void showAnimatedWordLimitSummary(int errorWordCount, int totalWordTyped) throws InterruptedException { - viewAnimateRight("Wrong Words: " + errorWordCount + "/" + totalWordTyped); - } - - public void showAnimatedSentenceErrorRateSummary(double sentenceErrorRate) throws InterruptedException { - viewAnimateRight("Sentence Error Rate: " + sentenceErrorRate); - } - - public void showAnimatedError(ArrayList content, - ArrayList typed, - int totalWord) - throws InterruptedException { - TextUi ui = new TextUi(); - out.println(SUMMARY); - Error error = new Error(); - - ui.showAnimatedWordLimitSummary( - error.wrongWordCount(content, typed), - totalWord - ); - - double sentenceErrorRate = error.sentenceErrorRate(content, typed); - BigDecimal bd = new BigDecimal(sentenceErrorRate); - bd = bd.round(new MathContext(3)); - double rounded = bd.doubleValue(); - ui.showAnimatedSentenceErrorRateSummary(rounded); - } - - public void showAnimatedSummary(int errorWordCount, double errorPercentage, double wpm, - int totalWordTyped, double gameTime) throws InterruptedException { - out.print(SUMMARY + '\n'); - viewAnimateRight("Wrong Words: " + errorWordCount + "/" + totalWordTyped); - viewAnimateRight("Error Percentage: " + String.format("%.2f", errorPercentage)); - viewAnimateRight("WPM: " + String.format("%.2f", wpm)); - viewAnimateRight("Total Time taken for the game: " + String.format("%.2f", gameTime) + " seconds"); - } - - } diff --git a/time-limited_records.txt b/time-limited_records.txt index cf129effb9..d4417b06bd 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1 +1,2 @@ -Time-limited|39.172|9|1|10|90.0|10.0|1.5317063208414174|[Ipsum, is, simply, dummy, text, of, the, printing, and] +Time-limited|39.172|9|1|10|90.0|10.0|1.5317063208414174|[Ipsum, is, simply, dummy, text, of, the, printing, and] +Time-limited|32.35|4|26|30|13.333333333333334|86.66666666666667|48.222565687789796|[the, and, industry's, dummy] diff --git a/word-limited_records.txt b/word-limited_records.txt index e69de29bb2..f0ea1861b1 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -0,0 +1,5 @@ +Word-limited|10.055|2|3|5|40.0|60.0|17.90154152163103|[simply, dummy] +Word-limited|16.25|4|6|10|40.0|60.0|22.153846153846153|[may, refer, to: + +Jaan, name) +Jaan] From 7c896ca16b9769355026a7357d181821223c88cf Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 16:36:47 +0800 Subject: [PATCH 224/272] rename TimeLimitGmae --- docs/DeveloperGuide.md | 34 +++++++++++++++---- .../typists/command/TimeGameCommand.java | 6 ++-- .../{TimeModeGame.java => TimeLimitGame.java} | 9 +++-- .../seedu/typists/game/WordLimitGame.java | 3 +- src/main/java/seedu/typists/ui/GameUi.java | 1 - src/test/java/seedu/DataProcessorTest.java | 1 - ...deGameTest.java => TimeLimitGameTest.java} | 8 ++--- time-limited_records.txt | 3 +- word-limited_records.txt | 2 ++ 9 files changed, 41 insertions(+), 26 deletions(-) rename src/main/java/seedu/typists/game/{TimeModeGame.java => TimeLimitGame.java} (90%) rename src/test/java/seedu/{TimeModeGameTest.java => TimeLimitGameTest.java} (68%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8c1436c7c2..683396fbc1 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -39,10 +39,34 @@ The other core components of Typist: * `ui`: The Ui of the app. * `command`: Consists of `CommandFactory` which parses user inputs, and various `command` objects. * `common`: A collection of classes used by multiple other components. -* `content`: holds the content and logic for `content` command -* `game`: game, game summary and game record executor. -* +* `content`: Holder for the content and logic for `content` command +* `game`: Game, game summary and game record executor. +* `storage`: Game storage executor. +### Command Component + +The Command Component contains different types of command actions. +The `Command Factory` is responsible for parsing the user input and returning the corresponding command class to be executed. + +* When `Main` calls the `.run(args)` method of a `Command` object, ... + +### Game Component + +**How the Game Component works:** +* When `.run(args)` of the `GameCommand` object is called, a corresponding `Game` object is created. +Immediately after, the `.run()` method of `Game` will be called, followed by `.gameSummary()`. + +For instance: +* When the `.run(args)` of `TimeGameCommand` is called, a `TimeLimitGame` object is created. +* Then, `.run()` method of `TimeLimitCommand` is executed, a Time Limit Game will start running +until game ends(i.e. timer's up). +* `.gameSummary()` method will then generate the summary of the game. + +### TimeLimitGame Class +Sequence Diagram for Time Mode Game: + + +The Sequence Diagram below illustrates the working process of the `TimeModeGame` class. ## Implementation @@ -77,10 +101,6 @@ Gonna to change this .puml diagram later - zhansen ![](diagrams/WordLimitMode.png) -### Time Limit Game -Sequence Diagram for Time Mode Game: -![image](https://user-images.githubusercontent.com/69776265/139190231-eb648329-517b-42dc-a088-fbce5c93c616.png) - ### \[Proposed\] View Statistics feature #### \[Proposed Implementation\] The top-level logic of view statistics feature resides in ViewCommand. It implements the Command diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/TimeGameCommand.java index ab41c674b1..67a37a3c17 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/TimeGameCommand.java @@ -3,7 +3,7 @@ import seedu.typists.common.exception.IncompleteCommandException; import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.Game; -import seedu.typists.game.TimeModeGame; +import seedu.typists.game.TimeLimitGame; import java.util.ArrayList; @@ -21,9 +21,9 @@ public Game createGame(ArrayList args, boolean isReady, boolean setConte } try { int timeInSeconds = getNumber(args, TIME_SIGNIFIER); - return new TimeModeGame(content.getContent(), LINE_LENGTH, timeInSeconds, isReady); + return new TimeLimitGame(content.getContent(), LINE_LENGTH, timeInSeconds, isReady); } catch (NumberFormatException | IncompleteCommandException | InvalidCommandException e) { - return new TimeModeGame(content.getContent(), LINE_LENGTH, isReady); + return new TimeLimitGame(content.getContent(), LINE_LENGTH, isReady); } } diff --git a/src/main/java/seedu/typists/game/TimeModeGame.java b/src/main/java/seedu/typists/game/TimeLimitGame.java similarity index 90% rename from src/main/java/seedu/typists/game/TimeModeGame.java rename to src/main/java/seedu/typists/game/TimeLimitGame.java index 69a79a417d..62aa825c3c 100644 --- a/src/main/java/seedu/typists/game/TimeModeGame.java +++ b/src/main/java/seedu/typists/game/TimeLimitGame.java @@ -15,12 +15,12 @@ import static seedu.typists.common.Utils.isValidTime; -public class TimeModeGame extends Game { +public class TimeLimitGame extends Game { protected final ArrayList wordLists; protected double gameTime; protected int currentRow; - public TimeModeGame(String targetWordSet, int wordsPerLine, boolean isReady) { + public TimeLimitGame(String targetWordSet, int wordsPerLine, boolean isReady) { super(wordsPerLine, isReady); assert targetWordSet != null; this.wordLists = splitStringIntoWordList(targetWordSet); @@ -28,7 +28,7 @@ public TimeModeGame(String targetWordSet, int wordsPerLine, boolean isReady) { this.limit = getTimeLimit(); } - public TimeModeGame(String targetWordSet, int wordsPerLine, int timeInSeconds, boolean isReady) { + public TimeLimitGame(String targetWordSet, int wordsPerLine, int timeInSeconds, boolean isReady) { super(wordsPerLine, timeInSeconds, isReady); assert targetWordSet != null; this.wordLists = splitStringIntoWordList(targetWordSet); @@ -36,10 +36,9 @@ public TimeModeGame(String targetWordSet, int wordsPerLine, int timeInSeconds, b } public int getTimeLimit() { - Scanner in = new Scanner(System.in); ui.printScreen("Enter how long you want the game to run: "); try { - int n = Integer.parseInt(in.nextLine()); + int n = Integer.parseInt(ui.readCommand()); return isValidTime(n); } catch (NumberFormatException e) { ui.printScreen("Invalid Number!"); diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 5064b86207..2b08180ee6 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -51,10 +51,9 @@ public int getTotalSentence() { } public int getWordLimit() { - Scanner in = new Scanner(System.in); ui.printScreen("Enter how many words you want the game to run: "); try { - int n = Integer.parseInt(in.nextLine()); + int n = Integer.parseInt(ui.readCommand()); return isValidWord(n); } catch (NumberFormatException e) { new TextUi().printScreen("Length should be a number!"); diff --git a/src/main/java/seedu/typists/ui/GameUi.java b/src/main/java/seedu/typists/ui/GameUi.java index 53289df74a..29ecc52572 100644 --- a/src/main/java/seedu/typists/ui/GameUi.java +++ b/src/main/java/seedu/typists/ui/GameUi.java @@ -36,5 +36,4 @@ public void printResetContent(int n) { + n + " words." ); } - } diff --git a/src/test/java/seedu/DataProcessorTest.java b/src/test/java/seedu/DataProcessorTest.java index 59d58d9b1d..756205dd6e 100644 --- a/src/test/java/seedu/DataProcessorTest.java +++ b/src/test/java/seedu/DataProcessorTest.java @@ -1,7 +1,6 @@ package seedu; import org.junit.jupiter.api.Test; -import seedu.typists.game.TimeModeGame; public class DataProcessorTest { private static final String TEST_TXT = " testing testing testing"; diff --git a/src/test/java/seedu/TimeModeGameTest.java b/src/test/java/seedu/TimeLimitGameTest.java similarity index 68% rename from src/test/java/seedu/TimeModeGameTest.java rename to src/test/java/seedu/TimeLimitGameTest.java index 249258ed5a..daf0517436 100644 --- a/src/test/java/seedu/TimeModeGameTest.java +++ b/src/test/java/seedu/TimeLimitGameTest.java @@ -1,20 +1,16 @@ package seedu; import org.junit.jupiter.api.Test; -import seedu.typists.game.TimeModeGame; - -import java.util.ArrayList; -import java.util.Arrays; import static org.junit.jupiter.api.Assertions.assertEquals; -public class TimeModeGameTest { +public class TimeLimitGameTest { private static final String TEXT_TXT = "this is test text"; //name: whatIsBeingTested_descriptionOfTestInputs_expectedOutcome @Test public void wordLines_sampleTxt_correct() { - //TimeModeGame g = new TimeModeGame(TEXT_TXT, 15); + //TimeLimitGame g = new TimeLimitGame(TEXT_TXT, 15); //should get an error cause the text is not enough words //need update } diff --git a/time-limited_records.txt b/time-limited_records.txt index cf129effb9..8355cadb21 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1 +1,2 @@ -Time-limited|39.172|9|1|10|90.0|10.0|1.5317063208414174|[Ipsum, is, simply, dummy, text, of, the, printing, and] +Time-limited|39.172|9|1|10|90.0|10.0|1.5317063208414174|[Ipsum, is, simply, dummy, text, of, the, printing, and] +Time-limited|38.126|5|25|30|16.666666666666664|83.33333333333334|39.34323034149924|[Some, little, purse,, nothing, shore,] diff --git a/word-limited_records.txt b/word-limited_records.txt index e69de29bb2..a456e5c9b0 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -0,0 +1,2 @@ +Word-limited|13.052|1|9|10|10.0|90.0|41.372969659822246|[hunting] +Word-limited|15.067|1|10|11|9.090909090909092|90.9090909090909|39.82212782903033|[balloon] From c1ea7ede455c83595997dc4089e950ccf8cdc2e0 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 17:25:16 +0800 Subject: [PATCH 225/272] refactoring create a new folder for commands inside command --- docs/DeveloperGuide.md | 3 +++ src/main/java/seedu/typists/Main.java | 2 +- src/main/java/seedu/typists/command/CommandFactory.java | 1 + .../seedu/typists/command/{ => commands}/ClearCommand.java | 2 +- .../java/seedu/typists/command/{ => commands}/Command.java | 2 +- .../seedu/typists/command/{ => commands}/ContentCommand.java | 4 +++- .../seedu/typists/command/{ => commands}/ExitCommand.java | 3 ++- .../seedu/typists/command/{ => commands}/GameCommand.java | 3 ++- .../seedu/typists/command/{ => commands}/HistoryCommand.java | 3 ++- .../seedu/typists/command/{ => commands}/TimeGameCommand.java | 2 +- .../seedu/typists/command/{ => commands}/WordGameCommand.java | 2 +- 11 files changed, 18 insertions(+), 9 deletions(-) rename src/main/java/seedu/typists/command/{ => commands}/ClearCommand.java (98%) rename src/main/java/seedu/typists/command/{ => commands}/Command.java (70%) rename src/main/java/seedu/typists/command/{ => commands}/ContentCommand.java (71%) rename src/main/java/seedu/typists/command/{ => commands}/ExitCommand.java (83%) rename src/main/java/seedu/typists/command/{ => commands}/GameCommand.java (95%) rename src/main/java/seedu/typists/command/{ => commands}/HistoryCommand.java (97%) rename src/main/java/seedu/typists/command/{ => commands}/TimeGameCommand.java (96%) rename src/main/java/seedu/typists/command/{ => commands}/WordGameCommand.java (96%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1d3b789ff9..0346e3e8cd 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -45,6 +45,9 @@ The other core components of Typist: ### Command Component +API: `C` +How the `command` component work: +1. When `command` is called upon The Command Component contains different types of command actions. The `Command Factory` is responsible for parsing the user input and returning the corresponding command class to be executed. diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index d476c80a93..a8b424b704 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -1,7 +1,7 @@ package seedu.typists; import seedu.typists.content.Content; -import seedu.typists.command.Command; +import seedu.typists.command.commands.Command; import seedu.typists.command.CommandFactory; import seedu.typists.ui.SummaryUi; import seedu.typists.ui.TextUi; diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 71fd51138b..5ce1f0a3d5 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -1,5 +1,6 @@ package seedu.typists.command; +import seedu.typists.command.commands.*; import seedu.typists.ui.TextUi; import java.util.ArrayList; diff --git a/src/main/java/seedu/typists/command/ClearCommand.java b/src/main/java/seedu/typists/command/commands/ClearCommand.java similarity index 98% rename from src/main/java/seedu/typists/command/ClearCommand.java rename to src/main/java/seedu/typists/command/commands/ClearCommand.java index 5bdfb43470..32eb84d5b2 100644 --- a/src/main/java/seedu/typists/command/ClearCommand.java +++ b/src/main/java/seedu/typists/command/commands/ClearCommand.java @@ -1,4 +1,4 @@ -package seedu.typists.command; +package seedu.typists.command.commands; import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.GameRecordsManager; diff --git a/src/main/java/seedu/typists/command/Command.java b/src/main/java/seedu/typists/command/commands/Command.java similarity index 70% rename from src/main/java/seedu/typists/command/Command.java rename to src/main/java/seedu/typists/command/commands/Command.java index ce16792cd2..4f58d011ad 100644 --- a/src/main/java/seedu/typists/command/Command.java +++ b/src/main/java/seedu/typists/command/commands/Command.java @@ -1,4 +1,4 @@ -package seedu.typists.command; +package seedu.typists.command.commands; import java.util.ArrayList; diff --git a/src/main/java/seedu/typists/command/ContentCommand.java b/src/main/java/seedu/typists/command/commands/ContentCommand.java similarity index 71% rename from src/main/java/seedu/typists/command/ContentCommand.java rename to src/main/java/seedu/typists/command/commands/ContentCommand.java index 82e5bb8e73..8e003b8aac 100644 --- a/src/main/java/seedu/typists/command/ContentCommand.java +++ b/src/main/java/seedu/typists/command/commands/ContentCommand.java @@ -1,7 +1,9 @@ -package seedu.typists.command; +package seedu.typists.command.commands; +import seedu.typists.command.commands.Command; + import java.util.ArrayList; import static seedu.typists.Main.content; diff --git a/src/main/java/seedu/typists/command/ExitCommand.java b/src/main/java/seedu/typists/command/commands/ExitCommand.java similarity index 83% rename from src/main/java/seedu/typists/command/ExitCommand.java rename to src/main/java/seedu/typists/command/commands/ExitCommand.java index 6138dd8f77..5968959669 100644 --- a/src/main/java/seedu/typists/command/ExitCommand.java +++ b/src/main/java/seedu/typists/command/commands/ExitCommand.java @@ -1,5 +1,6 @@ -package seedu.typists.command; +package seedu.typists.command.commands; +import seedu.typists.command.commands.Command; import seedu.typists.game.GameRecordsManager; import java.util.ArrayList; diff --git a/src/main/java/seedu/typists/command/GameCommand.java b/src/main/java/seedu/typists/command/commands/GameCommand.java similarity index 95% rename from src/main/java/seedu/typists/command/GameCommand.java rename to src/main/java/seedu/typists/command/commands/GameCommand.java index b5322fbd8f..acd27b09c6 100644 --- a/src/main/java/seedu/typists/command/GameCommand.java +++ b/src/main/java/seedu/typists/command/commands/GameCommand.java @@ -1,5 +1,6 @@ -package seedu.typists.command; +package seedu.typists.command.commands; +import seedu.typists.command.commands.Command; import seedu.typists.common.exception.IncompleteCommandException; import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.Game; diff --git a/src/main/java/seedu/typists/command/HistoryCommand.java b/src/main/java/seedu/typists/command/commands/HistoryCommand.java similarity index 97% rename from src/main/java/seedu/typists/command/HistoryCommand.java rename to src/main/java/seedu/typists/command/commands/HistoryCommand.java index 1041e081c8..2821a7f2a0 100644 --- a/src/main/java/seedu/typists/command/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/commands/HistoryCommand.java @@ -1,5 +1,6 @@ -package seedu.typists.command; +package seedu.typists.command.commands; +import seedu.typists.command.commands.Command; import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.GameRecord; import seedu.typists.game.GameRecordsManager; diff --git a/src/main/java/seedu/typists/command/TimeGameCommand.java b/src/main/java/seedu/typists/command/commands/TimeGameCommand.java similarity index 96% rename from src/main/java/seedu/typists/command/TimeGameCommand.java rename to src/main/java/seedu/typists/command/commands/TimeGameCommand.java index 67a37a3c17..d046eb8d6d 100644 --- a/src/main/java/seedu/typists/command/TimeGameCommand.java +++ b/src/main/java/seedu/typists/command/commands/TimeGameCommand.java @@ -1,4 +1,4 @@ -package seedu.typists.command; +package seedu.typists.command.commands; import seedu.typists.common.exception.IncompleteCommandException; import seedu.typists.common.exception.InvalidCommandException; diff --git a/src/main/java/seedu/typists/command/WordGameCommand.java b/src/main/java/seedu/typists/command/commands/WordGameCommand.java similarity index 96% rename from src/main/java/seedu/typists/command/WordGameCommand.java rename to src/main/java/seedu/typists/command/commands/WordGameCommand.java index d9170c5ef0..becc0d2c69 100644 --- a/src/main/java/seedu/typists/command/WordGameCommand.java +++ b/src/main/java/seedu/typists/command/commands/WordGameCommand.java @@ -1,4 +1,4 @@ -package seedu.typists.command; +package seedu.typists.command.commands; import seedu.typists.common.exception.IncompleteCommandException; import seedu.typists.common.exception.InvalidCommandException; From 744c05dde962043787cd5b0328bb919c8419a9c0 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sat, 6 Nov 2021 17:32:30 +0800 Subject: [PATCH 226/272] checkstyle update --- seedu.typists.ui.TextUi.log.1 | 2 +- src/main/java/seedu/typists/command/CommandFactory.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/seedu.typists.ui.TextUi.log.1 b/seedu.typists.ui.TextUi.log.1 index e7d3a89772..6ce50be5f0 100644 --- a/seedu.typists.ui.TextUi.log.1 +++ b/seedu.typists.ui.TextUi.log.1 @@ -1,2 +1,2 @@ -Nov 04, 2021 5:06:52 PM seedu.typists.ui.SummaryUi setUpLog +Nov 06, 2021 5:32:11 PM seedu.typists.ui.SummaryUi setUpLog INFO: Set up log in SummaryUi diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index 5ce1f0a3d5..eaffb4eb33 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -1,6 +1,13 @@ package seedu.typists.command; -import seedu.typists.command.commands.*; +import seedu.typists.command.commands.Command; +import seedu.typists.command.commands.ContentCommand; +import seedu.typists.command.commands.HistoryCommand; +import seedu.typists.command.commands.ClearCommand; +import seedu.typists.command.commands.ExitCommand; +import seedu.typists.command.commands.GameCommand; +import seedu.typists.command.commands.TimeGameCommand; +import seedu.typists.command.commands.WordGameCommand; import seedu.typists.ui.TextUi; import java.util.ArrayList; From b5c34aabbec2166ff65a58d25627bc3924b0b16f Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Sun, 7 Nov 2021 01:12:53 +0800 Subject: [PATCH 227/272] update command class diagram --- docs/DeveloperGuide.md | 17 +++++--- docs/diagrams/Style.puml | 1 - docs/diagrams/TimeLimitGame.puml | 2 +- docs/diagrams/command.puml | 62 ++++++++++++++++++++++++++ docs/diagrams/style.puml | 75 ++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 8 deletions(-) delete mode 100644 docs/diagrams/Style.puml create mode 100644 docs/diagrams/command.puml create mode 100644 docs/diagrams/style.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0346e3e8cd..24e8681176 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -44,14 +44,19 @@ The other core components of Typist: * `storage`: Game storage executor. ### Command Component +**API:** `CommandFactory.java` -API: `C` -How the `command` component work: -1. When `command` is called upon -The Command Component contains different types of command actions. -The `Command Factory` is responsible for parsing the user input and returning the corresponding command class to be executed. +The `Command` component implements the Factory Design Pattern to parse user commands. -* When `Main` calls the `.run(args)` method of a `Command` object, ... +Here’s a (partial) class diagram of the `Command` component: + + +How the `Command` component works: +1. Typists `Main` calls upon the `CommandFactory` class to parse the user input. +2. The `CommandFactory` returns a `Command` object (more precisely, an object that implements it e.g., `GameCommand`). +3. `Main` will then execute the `Command` by calling `.run(args)` method of the `Command`. + +The Sequence Diagram below illustrates the interactions between `main` and `Command` component for the `getCommand("game -time")` input. ### Game Component diff --git a/docs/diagrams/Style.puml b/docs/diagrams/Style.puml deleted file mode 100644 index 7df6dd88fa..0000000000 --- a/docs/diagrams/Style.puml +++ /dev/null @@ -1 +0,0 @@ -!define LOGIC_COLOR #3333C4 diff --git a/docs/diagrams/TimeLimitGame.puml b/docs/diagrams/TimeLimitGame.puml index 7aba96e6a1..75b39ab42a 100644 --- a/docs/diagrams/TimeLimitGame.puml +++ b/docs/diagrams/TimeLimitGame.puml @@ -1,5 +1,5 @@ @startuml -!include Style.puml +!include style.puml participant ":GameCommand" as command participant "game:TimeModeGame" as game diff --git a/docs/diagrams/command.puml b/docs/diagrams/command.puml new file mode 100644 index 0000000000..dcc64e4ee2 --- /dev/null +++ b/docs/diagrams/command.puml @@ -0,0 +1,62 @@ +@startuml +!include style.puml +skinparam arrowThickness 1.1 +skinparam arrowColor LOGIC_COLOR_T4 +skinparam classBackgroundColor LOGIC_COLOR + +package Storage { +} + +package Game { +} + +package Content { +} + +package Command { +Class CommandFactory + +package commands #F4F6F6{ +Class ClearCommand +Class ContentCommand +Class ExitCommand +Class HistoryCommand +Class "{abstract}\nGameCommand" as GameCommand +Class TimeGameCommand +Class WordGameCommand + +Interface Command <> +} +} + + +Class HiddenOutside #FFFFFF +HiddenOutside ..> CommandFactory + +CommandFactory ..> ClearCommand +CommandFactory ..> ContentCommand: creates > +CommandFactory ..> ExitCommand +CommandFactory ..> GameCommand +CommandFactory ..> HistoryCommand + +GameCommand --> Game +TimeGameCommand --> Game +WordGameCommand --> Game + +HistoryCommand --> Storage +ClearCommand --> Storage + +ContentCommand -up> Content + +ClearCommand ..|> Command +ContentCommand ..|> Command +ExitCommand ..|> Command +GameCommand ..|> Command +HistoryCommand ..|> Command + +TimeGameCommand -up-|> GameCommand +WordGameCommand -up-|> GameCommand + + + +@enduml \ No newline at end of file diff --git a/docs/diagrams/style.puml b/docs/diagrams/style.puml new file mode 100644 index 0000000000..2c46e043f2 --- /dev/null +++ b/docs/diagrams/style.puml @@ -0,0 +1,75 @@ +/' + 'Commonly used styles and colors across diagrams. + 'Refer to https://plantuml-documentation.readthedocs.io/en/latest for a more + 'comprehensive list of skinparams. + '/ + + +'T1 through T4 are shades of the original color from lightest to darkest + +!define UI_COLOR #1D8900 +!define UI_COLOR_T1 #83E769 +!define UI_COLOR_T2 #3FC71B +!define UI_COLOR_T3 #166800 +!define UI_COLOR_T4 #0E4100 + +!define LOGIC_COLOR #3333C4 +!define LOGIC_COLOR_T1 #C8C8FA +!define LOGIC_COLOR_T2 #6A6ADC +!define LOGIC_COLOR_T3 #1616B0 +!define LOGIC_COLOR_T4 #101086 + +!define MODEL_COLOR #9D0012 +!define MODEL_COLOR_T1 #F97181 +!define MODEL_COLOR_T2 #E41F36 +!define MODEL_COLOR_T3 #7B000E +!define MODEL_COLOR_T4 #51000A + +!define STORAGE_COLOR #A38300 +!define STORAGE_COLOR_T1 #FFE374 +!define STORAGE_COLOR_T2 #EDC520 +!define STORAGE_COLOR_T3 #806600 +!define STORAGE_COLOR_T2 #544400 + +!define USER_COLOR #000000 + +skinparam BackgroundColor #FFFFFFF + +skinparam Shadowing false + +skinparam Class { + FontColor #FFFFFF + BorderThickness 1 + BorderColor #FFFFFF + StereotypeFontColor #FFFFFF + FontName Arial +} + +skinparam Actor { + BorderColor USER_COLOR + Color USER_COLOR + FontName Arial +} + +skinparam Sequence { + MessageAlign center + BoxFontSize 15 + BoxPadding 0 + BoxFontColor #FFFFFF + FontName Arial +} + +skinparam Participant { + FontColor #FFFFFFF + Padding 20 +} + +skinparam MinClassWidth 50 +skinparam ParticipantPadding 10 +skinparam Shadowing false +skinparam DefaultTextAlignment center +skinparam packageStyle Rectangle + +hide footbox +hide members +hide circle \ No newline at end of file From 59c0cf7d72a02cf4e2310256278d0311f8bb0180 Mon Sep 17 00:00:00 2001 From: LimJiaJing Date: Sun, 7 Nov 2021 22:42:53 +0800 Subject: [PATCH 228/272] Correct format of UserGuide and DeveloperGuide. Correct bug in object diagram. --- docs/DeveloperGuide.md | 2 +- docs/UserGuide.md | 8 ++++---- docs/diagrams/ViewStatistics-3.drawio.svg | 2 +- docs/diagrams/ViewStatistics-4.drawio.svg | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1d3b789ff9..cab64f7785 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -16,7 +16,7 @@ {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} -* https://www.baeldung.com/java-testing-system-out-println +* [reference code for testing System.out.println()](https://www.baeldung.com/java-testing-system-out-println) * https://github.com/fastily/jwiki ## Setting Up, getting started diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2b8c7e2400..0cc8815fc1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -213,7 +213,7 @@ Mistakes: No words typed wrongly. ``` ### 3.4 Clear past records: `clear` -Clear all past game records +Clear all past game records. Format: `clear [-g GAME_MODE] [-h]` * GAME_MODE defaults to `all` if not provided * Possible arguments for GAME_MODE are - `word`, `time` or `all` @@ -239,7 +239,7 @@ Successfully cleared Time-limited game records. ``` ### 3.5 View summary of game -View summary of a just-played game. +View summary of a just-played game. Typists automatically generates and displays the summary after a game ends. The summary consists of the following fields: * Game mode @@ -288,6 +288,6 @@ hence losing all the game data. |`content`| Set the content |`game -word [WORD_LIMIT] [-sn] [-c]` | Start a word-limited game |`game -time [TIME_LIMIT] [-sn] [-c]` | Start a time-limited game -|`history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` | Clear history -|`clear` | Clear history +|`history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` | View past game records +|`clear` | Clear past game records |`bye`| Exit the program diff --git a/docs/diagrams/ViewStatistics-3.drawio.svg b/docs/diagrams/ViewStatistics-3.drawio.svg index 5028fc2356..2057f71a61 100644 --- a/docs/diagrams/ViewStatistics-3.drawio.svg +++ b/docs/diagrams/ViewStatistics-3.drawio.svg @@ -1,4 +1,4 @@ -
:ViewCommand
:ViewCommand
Uses
Uses
:StatisitcsManager
:StatisitcsManag...
:GameRecordsManager
:GameRecordsMana...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
:Storage
:Storage
Creates
Creates
uses
uses
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
Viewer does not support full SVG 1.1
\ No newline at end of file +
:ViewCommand
:ViewCommand
Uses
Uses
:StatisitcsManager
:StatisitcsManag...
:GameRecordsManager
:GameRecordsMana...
wordLimitedGameRecords
:GameRecord
wordLimitedGameR...
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
:Storage
:Storage
Creates
Creates
uses
uses
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
wordLimitedGameRecords
:GameRecord
wordLimitedGameR...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/diagrams/ViewStatistics-4.drawio.svg b/docs/diagrams/ViewStatistics-4.drawio.svg index a2af832b75..d18486c74f 100644 --- a/docs/diagrams/ViewStatistics-4.drawio.svg +++ b/docs/diagrams/ViewStatistics-4.drawio.svg @@ -1,4 +1,4 @@ -
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
:Storage
:Storage
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
uses
uses
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
TimeLimitedGameRecords
:GameRecord
TimeLimitedGameR...
WordLimitedGameRecords
:GameRecord
WordLimitedGameR...
Viewer does not support full SVG 1.1
\ No newline at end of file +
:StatisitcsManager
:StatisitcsManag...
:ViewCommand
:ViewCommand
:GameRecordsManager
:GameRecordsMana...
wordLimitedGameRecords
:GameRecord
wordLimitedGameR...
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
:Storage
:Storage
Creates
Creates
Uses
Uses
:ViewCommandUi
:ViewCommandUi
Uses
Uses
uses
uses
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
timeLimitedGameRecords
:GameRecord
timeLimitedGameR...
wordLimitedGameRecords
:GameRecord
wordLimitedGameR...
Viewer does not support full SVG 1.1
\ No newline at end of file From 069a65de0705b5167e9428ece8a5b69c083dedb8 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 00:29:20 +0800 Subject: [PATCH 229/272] Updates --- docs/UserGuide.md | 11 ++++++++++- docs/team/williamwahyudi.md | 16 +++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2b8c7e2400..1d726d43d2 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -279,7 +279,16 @@ hence losing all the game data. **Q**: How do I transfer my data to another computer? -**A**: {your answer here} +**A**: Copy and paste the save data under the same working directory. + +**Q**: The wiki page contains error messages. What should I do? + +**A**: Some characters might not be supported by the CLI. You can search for another page as an alternative. + +**Q**: Why does the time limit need to be a multiple of 30? + +**A**: It's a design choice. You can select the word limit game if you find it too restricting. + ## Command Summary diff --git a/docs/team/williamwahyudi.md b/docs/team/williamwahyudi.md index 0a5fa8e598..7d97c93730 100644 --- a/docs/team/williamwahyudi.md +++ b/docs/team/williamwahyudi.md @@ -1,9 +1,23 @@ # William Wahyudi - Project Portfolio Page ## Overview - +Typists is a command line interface typing game targeted at users who love to type and are +familiar with the command line interface. There are two game modes in types, time-limited +(aim to type as much as possible in a limited time) and word-limited (aim to type a chosen +number of words as fast as possible). ### Summary of Contributions #### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&since=2021-09-25&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=maxwireddevs&tabRepo=AY2122S1-CS2113-T13-4%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false) +#### Contribution to code design +Added content selection and a bit of effects. + +#### Documentation +* User Guide + * FAQ +* Developer Guide + * Details about the content selection feature and architecture diagram +#### Project management +* Merged pull requests +* Helped to fix the CI check errors \ No newline at end of file From b93c1ff3a3f6864c721ea907f5d8cca94230b188 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:11:00 +0800 Subject: [PATCH 230/272] Architecture --- docs/DeveloperGuide.md | 2 +- docs/diagrams/architecture.puml | 77 +++++++++++++++++++ .../java/seedu/typists/storage/Storage.java | 3 - src/main/java/seedu/typists/ui/TextUi.java | 13 ---- 4 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 docs/diagrams/architecture.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0db9681a3d..602ae26539 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -28,7 +28,7 @@ and third-party libraries -- include links to the original source as well} > can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. ### Architecture -(Some architecture diagram) +![](diagrams/architecture.png) The Architecture diagram above explains the high-level design of the Typists app. Given below is a quick overview of main components and how they interact with each other. diff --git a/docs/diagrams/architecture.puml b/docs/diagrams/architecture.puml new file mode 100644 index 0000000000..b87b29ea01 --- /dev/null +++ b/docs/diagrams/architecture.puml @@ -0,0 +1,77 @@ +@startuml +'https://plantuml.com/class-diagram + +class Main +interface Command +class ClearCommand +class ContentCommand +class ExitCommand +abstract class GameCommand +class HistoryCommand +class TimeGameCommand +class WordGameCommand +class CommandFactory +class Books +class Utils +class SummaryUi +class StringParser +class Content +class TimeLimitGame +class WordLimitGame +abstract class Game +class Storage +class Animation +class RandomGenerator +class WikiImport +class GameRecord +class GameRecordsManager +class SummaryManager +class FileParser +class ClearCommandUi +class GameUi +class HistoryCommandUi +class TextUi + +ClearCommand <.. Command +ContentCommand <.. Command +ExitCommand <.. Command +GameCommand <.. Command +HistoryCommand <.. Command +TimeGameCommand <|-- GameCommand +WordGameCommand <|-- GameCommand +TimeGameCommand <|-- Game +WordLimitGame <|-- Game +GameUi <|-- TextUi +SummaryUi <|-- TextUi +Storage *- Main +Content *-- Main +TextUi *-- Main +CommandFactory *-- Main +Command *- Main +Animation *-- TextUi +GameUi *-- Game +SummaryUi *-- Game +GameRecordsManager *-- Game +Game *-- GameCommand +GameUi *-- GameCommand +GameRecordsManager *-- ClearCommand +ClearCommandUi *-- ClearCommand +GameRecordsManager *-- ExitCommand +GameRecordsManager *-- HistoryCommand +HistoryCommandUi *-- HistoryCommand +TimeLimitGame *-- TimeGameCommand +WordLimitGame *-- WordGameCommand +TextUi *- CommandFactory +TextUi *-- Utils +TextUi *-- Content +WikiImport *-- Content +RandomGenerator *-- Content +Books *-- Content +Storage *-- GameRecordsManager +GameRecord *-- GameRecordsManager +TextUi *-- TimeLimitGame +TextUi *-- WordLimitGame +GameRecord *-- FileParser +GameRecord *-- Storage + +@enduml \ No newline at end of file diff --git a/src/main/java/seedu/typists/storage/Storage.java b/src/main/java/seedu/typists/storage/Storage.java index dc532d4c69..f011985b53 100644 --- a/src/main/java/seedu/typists/storage/Storage.java +++ b/src/main/java/seedu/typists/storage/Storage.java @@ -27,11 +27,9 @@ public class Storage { private static final Logger LOGGER = Logger.getLogger(TextUi.class.getName()); public static ArrayList readGameRecords(String gameMode) { - ArrayList gameRecordsStringArrayList = readFile(gameMode); ArrayList gameRecords = convertToGameRecords(gameRecordsStringArrayList); return gameRecords; - } public static void writeGameRecords(ArrayList gameRecords, String gameMode) { @@ -117,7 +115,6 @@ private static String getFileName(String gameMode) { assert ((gameMode.equals("Time-limited")) || (gameMode.equals("Word-limited"))); String filename = gameMode.toLowerCase(Locale.ROOT) + "_records.txt"; return filename; - } public static void setUpLog() { diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 7760553fba..b6f4fd7a41 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -24,7 +24,6 @@ */ public class TextUi { private final SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final String DIVIDER = "==========================================================="; private static final String LINE_PREFIX = " | "; private static final String LS = lineSeparator(); @@ -120,16 +119,4 @@ public void viewAnimateLeft(String string) throws InterruptedException { } System.out.println(""); } - - public void viewAnimateRight(String string) throws InterruptedException { - Animation animation = new Animation(); - animation.resetAnimRight(); - int k = 0; - while (k < 6) { - animation.animateRight(string); - Thread.sleep(300); - k++; - } - System.out.println(""); - } } From 999cbad9f99a9157ae6db46b836ef93a4ddb61a9 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:19:09 +0800 Subject: [PATCH 231/272] Architecture --- docs/diagrams/architecture.png | Bin 0 -> 65011 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagrams/architecture.png diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..a6da716850fd0ea03e6db6e741051cc072b2e4c8 GIT binary patch literal 65011 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 z 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 literal 0 HcmV?d00001 From f944e00093b94c2e89fdc7c87ffa7028c4441aa5 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:20:10 +0800 Subject: [PATCH 232/272] Architecture --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 602ae26539..1f113f0171 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -29,6 +29,7 @@ and third-party libraries -- include links to the original source as well} ### Architecture ![](diagrams/architecture.png) + The Architecture diagram above explains the high-level design of the Typists app. Given below is a quick overview of main components and how they interact with each other. From 54e337b47b9859aad9875dda15d901339a13c724 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:20:20 +0800 Subject: [PATCH 233/272] Architecture --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1f113f0171..a284398a56 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -28,6 +28,7 @@ and third-party libraries -- include links to the original source as well} > can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. ### Architecture + ![](diagrams/architecture.png) The Architecture diagram above explains the high-level design of the Typists app. From 7af5c2195ef3bc4cf3875229a6486796a690c451 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:23:14 +0800 Subject: [PATCH 234/272] Architecture --- docs/diagrams/architecture.puml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/diagrams/architecture.puml b/docs/diagrams/architecture.puml index b87b29ea01..76035f1505 100644 --- a/docs/diagrams/architecture.puml +++ b/docs/diagrams/architecture.puml @@ -51,6 +51,7 @@ Command *- Main Animation *-- TextUi GameUi *-- Game SummaryUi *-- Game +SummaryManager *-- Game GameRecordsManager *-- Game Game *-- GameCommand GameUi *-- GameCommand @@ -73,5 +74,6 @@ TextUi *-- TimeLimitGame TextUi *-- WordLimitGame GameRecord *-- FileParser GameRecord *-- Storage +StringParser *-- WordLimitGame @enduml \ No newline at end of file From 69f51fe226a36fa551e5a93655463f16e2254f65 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:25:56 +0800 Subject: [PATCH 235/272] Architecture --- docs/diagrams/architecture.puml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/diagrams/architecture.puml b/docs/diagrams/architecture.puml index 76035f1505..2ba54a2124 100644 --- a/docs/diagrams/architecture.puml +++ b/docs/diagrams/architecture.puml @@ -49,6 +49,7 @@ TextUi *-- Main CommandFactory *-- Main Command *- Main Animation *-- TextUi +Content *-- Animation GameUi *-- Game SummaryUi *-- Game SummaryManager *-- Game @@ -64,13 +65,13 @@ TimeLimitGame *-- TimeGameCommand WordLimitGame *-- WordGameCommand TextUi *- CommandFactory TextUi *-- Utils -TextUi *-- Content +TextUi *--- Content WikiImport *-- Content RandomGenerator *-- Content Books *-- Content Storage *-- GameRecordsManager GameRecord *-- GameRecordsManager -TextUi *-- TimeLimitGame +TextUi *--- TimeLimitGame TextUi *-- WordLimitGame GameRecord *-- FileParser GameRecord *-- Storage From 5dde00f66a0038fa8680304a6ef4269a660614b7 Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:26:17 +0800 Subject: [PATCH 236/272] Architecture --- docs/diagrams/architecture.png | Bin 65011 -> 52360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png index a6da716850fd0ea03e6db6e741051cc072b2e4c8..9c718cc2e503a71e78eb502fbe6bea263821bb3d 100644 GIT binary patch literal 52360 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
+QpWfeBdhB$Le}!Wo86yt=_laRt1eOV({KaO%f+ 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

%O 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 RV$c68EiNziTg1Tk{{cPZ|7-vN literal 65011 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 z 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 From 7dbba2139a8364bfb26c20a25aee91216091921c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:27:39 +0800 Subject: [PATCH 237/272] Delete architecture.png --- docs/diagrams/architecture.png | Bin 52360 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/diagrams/architecture.png diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png deleted file mode 100644 index 9c718cc2e503a71e78eb502fbe6bea263821bb3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52360 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

+QpWfeBdhB$Le}!Wo86yt=_laRt1eOV({KaO%f+ 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

%O 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 RV$c68EiNziTg1Tk{{cPZ|7-vN From de99568116b9324cbc33aa9a810248f8d676bcfa Mon Sep 17 00:00:00 2001 From: WDOneM <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 05:28:35 +0800 Subject: [PATCH 238/272] Architecture --- docs/diagrams/architecture.png | Bin 0 -> 133105 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagrams/architecture.png diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..3b5842fcb971b005b7a80ffcb9b905eee24ec67c GIT binary patch literal 133105 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 P{Hx?sIkEgF25 Date: Mon, 8 Nov 2021 05:30:32 +0800 Subject: [PATCH 239/272] Delete architecture.png --- docs/diagrams/architecture.png | Bin 133105 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/diagrams/architecture.png diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png deleted file mode 100644 index 3b5842fcb971b005b7a80ffcb9b905eee24ec67c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133105 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 P{Hx?sIkEgF25 Date: Mon, 8 Nov 2021 05:32:09 +0800 Subject: [PATCH 240/272] Add files via upload --- docs/diagrams/architecture.png | Bin 0 -> 133105 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagrams/architecture.png diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..3b5842fcb971b005b7a80ffcb9b905eee24ec67c GIT binary patch literal 133105 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 P{Hx?sIkEgF25 Date: Mon, 8 Nov 2021 05:33:29 +0800 Subject: [PATCH 241/272] Delete architecture.png --- docs/diagrams/architecture.png | Bin 133105 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/diagrams/architecture.png diff --git a/docs/diagrams/architecture.png b/docs/diagrams/architecture.png deleted file mode 100644 index 3b5842fcb971b005b7a80ffcb9b905eee24ec67c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133105 zcmaI7WmuKl8ZJB$5G6#Al2lr{K^mpILmCO`?i3ZJrMo301*9h>-Q6kO;H3MEscWsh z_d4hM_@j7vz3)4oyr28IN1&p-1O_T0Dg*+-kdhQthCuErLLi7d_wImy;Sc0_1pavD zB&O-~+Sbn9%EZ(OB4J`<;$Y}xV*JF&{mC0ACp%tdW;-iG8z*OLE2h`B)>tghi6M|X z(dMd}PJjP91OYt8EqPa?%Vvha+iW5>M4Kn5zT=}FnNW1Ekyp~7%BP6|E zm;-{qgJ>6c4-I079qbxy#IqVr9$T?y9u{%HS`1A%8q8HNdUB*L`BwS93!9IPb|`I{EnrXP%eA#H{otInkQr{Gy--R+j;)Q_W9VZ z5k`UW(&SJiUuA^+LSLPXr9^dQtFrL_Hv%u&reM!3!dGr z+c26~zn?P}lAEZfqn*khg{P!la{1z}fxniEp1*++-qN@20A22#TEhv9I-5!7+tp%i zH6f3>)jOo6wD}*gLYHQE2*rlR?n<3yu3T^h*hjazO5rs3S)tKia#kl6;eA`oR-9o` z(O~Y>)~ZjkWRZ|SnxKlxZ$oMzW=Rsdu|PO$4HLB!A5(0;ayBR4YY4y;{egj(k8@Uw z6n;h$Q=_W?geuYdZ>*T{-c;UU)B*(5Kafy=Y^j{O*vZVr2w4jp_0Amso2jCS%l zA^!afBq?JN`R`vWkdc}H{<|VQts6W|;6Hw^M4Hk5{1pNjMMc$vq!Z%SAaBawBtF7* z|8S%YN#{-ELf9sbuYvzBh7bPuki5HHl+X9C(w|5C+)-#mhU90NKl;}HHUa*eCS~w! zKZ{P-?kD!#;S`=N60BT>r`C6KhLZ1Vt~d3ZNC63zbfh*&L1f1V&-NQrJh%fHbF*&H)%%HWQ#hBpb0$oFqA~wI;i*j0{+^)2?TzY3hwbU;$e=e|%FI0QXIM0cIzl5EcAfvE9;)E% zHL?FtgY8=K5wPg@TO6q*+l7X{RR^s<4OgUeta^((k@r`>TNEfUQa^e8Qk>2A z&iHc{M|h}cVu0{b47E6fKYN)qxS9g*K)}8GITuMP|8fLc3N^EtTX*R9#{_xP_a$>8 z+ul=Er1=?BJ{~yuw?@mr46d!7pWSTHcurTPoAND_Q>lK0wm_ z4z(5$;h6cI$fC~5?%TsD(*HKk-5A?AjWhek;iB_0krLGAsi^UVexn`hW%!GSkeN#x zfg7BY{EX?#7+=%;D`e7PyAR7}#JzK$tq&6m-9R}H>yFRz&M*5sz0apyu60|eAKY&F z>Z`PfUYmX4BYH+%;ML$Wk|Q_ozMitym!zewuiS6CAlMnzm@ig}X3oy?kQ1Tn=%@Er z?e+VTmD$t=PTwW9J>T@i?pN6^n666K``>Z3D9hurV0UNzFE?P&EmZ21CREwfIh0+u zH8t$3ek3%ncUD-86@bmg3{21@aGl5TH~8Led?c%MaHthut+FNChw_@KqkrjZ5*|f5 zn*X+KP5oqQ{Bl)h^ZM-d?IRj4T%79M?5Pr6KG)-|scw~*AAW@mtE$;F|98gbdCgSc zqQ7ow{L0{QQ~QAu&3dl#IE=lH?2J&q@=U^Pe#PR@S|)3|^4)qT`&f=#QhdB*fo_@G z!Qy1;Ya)~IdgvZH3GX+x0=&6eXATw~T1!d=x5Kr!VI(t=4^am+wRFkrgA^j;)^l>X zi{+9qO?wHF()Otrq;DAW@YKOY?(So2OXCkO^1^mmtlv! z*)T?JJSCw37$$|M-=BJG@w?tCo^$0+vD~~wh!Ja?SP_Wya_|cM>axm$!LrIlR-9bd zP1-|CT}9d5K%36`F}_0ufPIoD$~1*!5KRF8)@r(NMSQemaiuV0qy$3eL4zL&c+x^qKi%$EOGrn_j>>7G;Dd-Rw^t(04LxFm(y z)NeY)Z8P(`#eI(p0HA`F4B?O^YVRhb6xF&WJvrrl#n#4tRc0SkBWv^9f zrXpTjJ*)V)eJMvI zstwIjXr4@|+uw=QtdO?dpI6&o|8D+>?Qw7re^+w;KS!#NbPDs@ z?upaC`dpC!{a3Eh@Ch!Sq==ggoqD_JqwidXMK)*oDiTwpa#j)M#qC*9D%emBSn5$W zQoS>|UkOd=;G3$l9oU=W+upYI&aG{&p6<}nk{`(pKVN(oyWo9l@+Pm;%P-^SPrdqD zZp-nb@_|~S$0Qo_ivFM*1Sa|!U)*a<)vLNM>2D1sCsbO# zGNz)3+7x(*S%3aezKF)4A~YympRdHxQMW73-X0GYJ0bt?NTxFK9YJ7s&s9(i{66$D zDtjjO_@-7NSe-GkaRE9Jmv#+Z#UIY&X}@eoPTDt>x~Xr)9JvGP{bv}`_ZyekgV`=# zP{DAgVoM(>;&E}spFSg&VSoqMFm3W)Gcl6K)_A4Ti222 z46W}%R;r>tH@Sq3@~>ve7Wh6*&S&JlWP4OmJU@cTP=hy-%1C+lE+>*H6L=t`01gB( zWXSO(HWt>sS*Cq=e+_@Pa<6k}ko)0!{QxxZ^S3!p%GW{Pyo~qqu4S6qb-TOh9N}NA zSn=qyELE_*(1g#O$OvQpmjCUEes@&~qTZY?GhdCrmYVPM^rb9W?eq)1C@a&bIIpZ8 zUNDC_fbM>lS|Zfj`m||O=@Nh9YY%AZe?5K>z?cL@^;a?$AXf<3BG3N=B;kck_}%AE zZ4qYAuPR@)4;1LaSe`PHg*=$`q8@71dcF|LuTVo~Gifqx8M(;d{rsu>rx$(owmK}^ z>{JHJOlveVl1Xph<}jk9Ae%9Q~YXv@@$UsA;W_moXU z^zxEDzrrOePJ-B3F!`J)46+(dm#)KJt805-N10c3iSJ`zImI{Ga_iOfQ(>}EznM8F zgjt(^x*kahy;HSQdhJuZ@!Fa#{z~RI{5;V9@$4=@)ai+6dc%rw{|mv=38}ggp5I_~ zt?elkCk2pJuhm^KPdrPqZqT;67+P6(-&ftX#p5+EI@I!DdDHQsgJ!S&aeOYHU@t}( zHIbmF9+o3`y`#u3}wht|&b;T1WN{hvtzjz;~~=;UPwU>?y;72$)8 z_|@kj9Xq-%FJlwD^JN_PM{J@11m9tEj~Xa@nSoL)a4zxLYAtpbUoSFRM5w30q!uON zH1U`6)b<=%h<2#7>yc-U)HxS8*OPxif8jngyx0|iASo`#;MyjPY5Qi&X0itq8VSeA z{qCm{BjMCD*Jr`t-3UqYAO&Pt%6eev&w^w!(w27lYp7SMNG*@%74?E6sIA*gc`kdV zIcXNer_s^BJpW%uoVVLVxQ8a*WQUlSS2D|;i4#CQ6=Y9fPSXnW-@uP|R3U;QKy=?Db=aA%x7 zeRC`HD?nXKFI-xse1q}vej5U{nL-Yq{U{&#K(gpGx@^|JjKLx%re|1bt9hl{vp5$w zYqtBHkR@%#>;0xg6p8rtR^5^vFauJtcbG5IV{zLq`9#P285}zI@5M{}YZOxq_0M~6 z?0EWVjxBfQx8vGVd^wlbIoS%6IVT+dFQGx4UCNuroR8O%0dbZrvHz4ZXPMh^z>RPp7`O-wZODiL12C}B|BlR{mw<_6ZiM-`=5l}3tlBg*-}{Fy*vD`nRq_r zOBo$E5ARK}$zp7I|D*9Fr}!ruUv}BdRTjq`ORIXzu7A)6OK(`G^D^6DyRPAM(T(wu z%cs5gf4B!KE@p$!g-$Wx;N|oD&Ec+*%^{Y${_P5@>%j6OR}}_+=@G{bjC2>{^U5_O zkW)BvN&igWu`im@{M1up;;h#2JPvASj;u}7wg`QB+I=QbZ;xqS-*9!Epmm%F9t`8B?vQfy2pObnl5(a{-;XypCp21s5c^a`y zri2ss;)RZ$NTVynRt_E&6tG??zzu+(Ni;BUZnElp<(mK5VN*9S`*bVAa#+5{eaW_& zkC_@qf|iNBF{G%#v5x)1e4qrW)tvRmL9U$Z5wk$fz zFM=|d9=Bdi_PrL^Tnmg`+s{*ws;2Bf*7L+Z+=^QR4dJ8JTIO%c1kPf-rOxkUChyXF ze6PD{L+F#Q*y~85qPmM7jMKJLw#D`ZLnkfjNLHiaATlt6vn5_;4JLbO zr*bU_`s|71{t_43&-0$v(NZPf_@Ybjj+bGS{deX2VJWR`a z*5dn^-?>jgSnK@5)w>chtwtUk9K3y9Rk$N-d}hp!wcDTY_6kj=iQQwDSyNlasGDmHIq$2!B0tBOw^j5#XmFeGz#_JwiX)YLB$+G$?AEcNtS$ z+lO<&Y$}6h;=Oyg(MCoSOPLqn($TX>H7-;BRXq(GtHCEF5zh-vF7hG04qpkk^&S3aERZ>&ZDD56hI!&+5 zw6&9kxDYnp43TMo(5G`i1Mf5_^U`+omrkM}{ZJ!6Bb}N5J=w=Hm11``rzM%@Dt4Dh z{1gGo`8zHCGB_$Sv%$yV(Ly8&zFTLS!i$0RD$;E>ca^i!8BjP|abu1Y4FZFpKhVv5 zwKUTj+6B^mT~8wbl@oPTmSHrZBp;PAd}drW)DY!l`?8~mPj#B%Ya#4a^?-fvR=2;= z#hm*I!`O7s)^-|c8VARIkr|(x)DFf_f%I#L^I-g=&+KN8ayJ#_>+HLAE71FGQF!_S z?B}oFj@T3q*0A^c!L2S1QaHYV=PBb&arS;U1)lf%!Hh+X+yb8cg-?G= zM@c;l>swfEZmuL{t?zAv$jjQ>bEm1NM3~cIHFXAPb91zvmXsyY(D~}>YO?`m{`JPa z_q&T!CJ8m8o=Y4y*3gWYqX^MRqs^bZ)&=Rytxb$(Xj%3h;(2Bmya*U^`yPWfg+G%q zPEmSuE-iNVV&5glQs@&qAI}fgv5ynY){0?TNRIvWj~&q+;I-%N`hhXIgK1 zkI&MxcOKVyo|c;@krZW%iiKscxmo1N!_S2ja@YY5(mtpKms2$x}?h;ReUDh@69hKX8%d zF{)m=M~oQNGd$9_NduYyp-J&Ef)W8QiRi=d|e6 zatxqkg(luF^jE{3tG_gXq;1hAz`q z29eKbI)}hVQiOv5!Z&vaH?0?)CVt*{t6XTVYh>xW3{hD0ZFGn+_vveKkc{)FR0sTK z1|T7TtIZ1#W$1@_;J9oAv}}yElZDw6R&iZ@dV91qi+x`JheO!Gfvt-Y5fM>9K!Ai0 z(s--GtLC$gVuQkX==^ab10xX13nT2Jrz+tV5=!%UWMunEwoai7BaA6T3dd=Wd?j*QW`5XV&dnzU3@$W@=O|OY)bLJ&4~BM7}gN zHH|c8V`5^;Zx9m88j02xJnITQ-$v_EMq-pP+JsuU~yCD)^Dk z-D3S*+8tHf>y}-h*bwUSdp3h0f>8>ixGbILt>r$z&E*QtVrjC6=c@)+0+z`ikwZ6! z8hk_Mi8ABqhbGz%A;d+ zO{t7|za%Hth8qJtl^DIwsl~oub#AxGNT{Fs<7Qi7nBq5Ge*+xKffMNMdt+*RWFE5KZ<*4NmKiRqviPT^H zO@Jc@6q^p#f_l8Yti3A5hcO28+6twsa=7i3ua0j6XLcH2a`t)led6z^_UD8b6BZOy zJ;k)vRa|oyK?I^>DI1Cls4gdwD-fMb$k~+RmrpJQPpz15 ziojn8xdj2SB_btlx`PpM)U8w0F^#GJ*yT*!#*Rbap75A44HtkT0SPqhT<>SoX>}$^ z2}MAzn>5xu^(+}A84ycd9-Y|y_<=PL&)YO2kYR(T^ay;cndw^;o?w0Y-eEmV++ z`*$j7L!=e=qaIsQ*MGY{vi1*qgvg!NJjANV?C>s2u1+Da{%Iy3PW6UW;lc=JfpiaY ziZi@ZJ%B&k&ldz<1vwMF0+;LQ`D(h<$NK=de;}*VCCJL4LNws(=Mx%~Bg_F6-|dtN zj0$GE7yuU#I)5V?EnygVXo#PJl!`d_i|ugU<5XoAJjV|#ZoQ1RzJn*bab0Nxq<7Hy^_>FKQ*Qp$G_&?R(? zxtBPf=;_?|!}Cr@Fr)hBc0ZPU(f%iDRkO$&X+bACB0sWjf3Bc;yOQ|O)g7_otv@~$ z&66Ll=lWp6pASAYyL>-92Psj%;uv$B*DFsQvE=D2ctY0k+uzb52R*mx_vhJU{iz%Mnj=#*O)&RaeIKw{5iFXz;|HUx!cr7n{goR zL~wOd9WQ3^9b^<4RgW`5Qkj8YC)WncY52jkOEE210x3k1L@I`74OM?qZ2jj}*6P%G zkZ!~}56EA-%F(!Fzk7!RrjfVbolxMP4?)#SlvUP>0UfmBjS#?Caa~DE7)AL(G9Uvi z!1qtn2FX2`_R$-ZnsMI3+q^zjRPlS&i5bpm!zn$f#Rp#FbE*fxIK_ay9;v2n;oaT= zJB+_fu6QsktCjkc67lKt!0UsUp*Xi{P0lwsI8cj{{O|lHu?e7+uhk!uAMMAiFA|&O zNj2TQ1|9s6w2dcB_w{uj9KZ~3WR@$vVz(v;S0KD7=8>&}BSc90Vzv^DtV7^pIbW;f zaqRV407)$z#fL)%A+&B|B9#hxfVcq8Y@mMtpzh!tWFR$$(j*?tF^w%!cLtgZ*PRC3 zJwdQP`y}n=ZdLzGs*A&1h%_$w_uA5g*6nL!h+IskI~qD;*`(MOrcz)yzyD zKL?XQu*b$UhVIQ#LufVBpA>DI ztQyEp^lCwI{ZO{RE6>BgL;?EBkMKDrxxP#Zh#xi% zlu#9v=8d z6Px4W>s1$;0A~MnOcosIfZ3H7)AOQ7c>ZqyXXYuY($ZgTB<;i27)$Z~$t^#7x4^ke9WP ztq0&i8W9=(k*t z3FJUhzuDQ~aS4^W{3SBekK49m0{$Ac9Y7rF8DUc?U(6!jGklxs52MnTkr z>Z_Y;CC}yROC2#t;fDc8n2^CniK={gdExi&WCFFg@XzAFMb!&YA&4UQCXxm)L(<+j z2On825oG=Wsvi1NCi-x8mMRixE3`_l^;rvySSR|koWm7`D4BxEG}&v0hWM0SeEHwm z?+1p8U=cQ*J0PyO&4mQ*4j(7)APx#E9vCHBr77;WU4o$Y(je}?|0%uhZG;ZBZBRpN zmbTh1n7ZCoru>yS6d)HpuuFL&_TKurAi#lYW;`JmG@8EH&Ja2D{9swxjMO6)xgc)ZGVu3){QfD`1?*%(Rzpw@$z$9 zTL6K;!$R*MGjny@oxqu{FV}9j3-YT%VOez_AmvDj;qjluYs_>Sz)0SWJd zfL4r*#`+Tl`#~+pO84OhBnP=vK>7R-IO&5f&GS%wFf_L-@rTNhm!8|Oy034#1h@k} zYhmm4U&#k7La1*4f^cegt!fN)GB3P<8Ic7T+=`|+&+DRT+~-Vsh-TzRIAOHO${p{yP+~VmOpd={*w()8rjRPQJD2>*Qy; zV-NS^_q#YV4&NU;(U)ss>U`cL75$TL?ZVC5)>5rYJcy1;n7Xd@DS({>9%DfV*dZO> z$OAgp>e}$q27>qx)5)v+ND(TinMznLRpXpBq|mMpJr>v4|MD3+Xmir}6>*@AoKUEn zdLWH>Lz*OM-OQsIN+k5qZWh7xc6t2fcWhNWbbh;?Qx{`n0tGz+yg7O79^7B0iU;{w z#JBfA0x@3p$zj(Hf@gs8X`ViOl>Duw3RH{=vQoC@PI(~DOj2=nq2n!Z(# zVzXg{d4wy>0>Jvw#w1X}R|hyb^^e>8{QM_~9>!_BC*yqRluQ6UG!pZ{0=Z%3=a0Yg zvE#f%$b8rb+L1i>mLQUU2{^5=GLBgt{J=LZ3OV##-C<~4xo!V`NGgud4dgl zC4M{QFgO`0pa5k}45dcJQdcz&0lo^a`B4G}UWqr*!FLn&zJkJ4WkH}M!3nHCj{$K~ zujiv#xID>8NdabntV@WWHK5i|&#hc1X3U2TUo_qIp0&~_Ca)46luFw5UA{l*#0zT2 zUrvGmfTpaaiT(YWe`-0rp|xeT7BY$mrj??|FCm}nHQwtw!BGvRQ?r>*=f3YH9F>*H z)kZY}IQO4N=sg>nR66S7*r)Q1%~^;0=oPJ-2nLwm6!vE({~;6@UcMB%?J0-J^2*YJ z*yNiOSEj;q8fKE0%=+ETgy%pyg#OqN1%rh8^}1R0UAR#kz@w~J?uuU&^Z&3dSgm;D zTd6=hSG4Evs^?X`#xvI~4_H=l-IbvtxU19m6c0QCt25b-7M;PS0V@}sDn<=N@HaAW zD9_dB$XFMry_XwPSNrReNv3Mqt4H^oRTEQR14{u6HrFgKb;m6C*Y=-It>{YYc1_d6 zHwuV-z^4a48rc+tDB{z)H4{YvFfQ=FU_4!~)AHzc7iX^fm0DZ&71uH-1b-$eMN3*Y zDX=dBv@7>6*YoDiusuY`vA;k5sFspW(2hKHu?knNrW=2h^w%)edGK>_i!m14@L?TH-GH%jA_Lin15NjdF&>`a3s5C;rrkz>8xuuRVhJiy5aT2voH>EWCEb~kpfrB+*jQ>}f?%`)`5>X6 zD1$s+O|9%S>XW*Jo>DI`k;L#z$>bj%(a(e##8sEp2kYv znItj~BR1XZTmR4+@5>bhYQZ4-R%z=u0fIWwJ9(@abZ&w4bnjgCIIiC~L=Juc-VFtF zCI=vV$^hRC=8DQQFZI^VOAvoY_o%iaLOV~^iWKw@kB-pM(L;iQq~+!N2h3WXuloeY z`T(H^yv5;fJm97lvGI@vMU{riV3jFo!4<@oc`C1HS@RHhZ*OuiGFw{mMMvJAdJh=au`@(Oa8Y7T7U&AzEmQY0H6)*FZx=d77@Zh zgsRu{5R|4;?mjCNX4d_p)3YyzWnT*%xLzn@{YMG;_})KCNDadmKMv~80VD->g!|W7 z!@4=x8Sdhrz{RhWTl_WD?7xCJc^nZRN0bVl_P@Zva=K11z|LK9(C|(S+_s`JT#_mg z!YaJK+|-Z~6GL7d*|jjOUhlNu57_U+r^!L%m5=^|6Dx9b4vdzuTTTqlK-$NS7A>kh zJRh}a@&Y|zi9;NchX)QJ`;|*jm20V^zI`*J?=-KCY##TIaxy=Nsq)8Fz5BLEFq?os z{Dc4Vyc_U5pV9n9Fw)R&d?9gE6Ly6_uD~#3Kut&VtmI(XCtLeaOid5hznrG1F-47; zdyJ0xRL!RFX?!C$8FYI%%Uk336We>K0z!Y~^kf>b_=2n#vQR#V{M6Q5#|(D#sfP!w zb10B>$e+jFXRWgybxm~0Y5ui5pv~T>9UlIdtj2m`fzxW~pycM1lT&uoSG=}7V(07p z*DzR^Tg6a`KJ$5$qAm;w1=sfbqE4swI`rYix?8a8&)GqXI=#kLTbq{R zHuB3C_EXAV_{#!5GY320TZ8Ae1PQ8M404-Itu~2x2~$sR_9XNpn7-E zP#=Ztz|D0$mM+sfTl47Vd>!*VE+XQ`YL8hbshP=hxfI?q=WTUkxvqYf*b+i+Thfim zQpWok2O%+I**0^$T-MXAt)h*wh|qsjo?qsg7Sp}xy|0VvJ)AX&6C!@{*vy`;pj5k9 z>sR!|^5=WY!(KJq)Vk)%@AmfgcX35WKrgaM{x9KX3>i*)5EZs?-?zF&F~K@8ricNE z0c=|WkRIGO1b^u_S!;oQb4PZc_p}b$#xwZ+bi%uVcr={wnbTst569c-q+FL@+%`H7 ziF+BJ{c3RC?>yO+k(ALS@EuHV_+qlyG(bU)6qH1pi!$a?YGj+b!*#~M2M6PMC3kg= zYMnM8k}zhD-_t78=04q-+C@g*ySUJvC{Cfbq+BrBRGz!?;$}K+ty=J@@x3iE_ACAM z6=+~b9fTWw>fNAG#uc?b-o71S)~nh@`a&h&24C8*z*gCrbS7is*2PIx>#Vx6rq@SD zh+LOisp$)3>OFmBtuOQATsDXIl8NI;_+mfn{jCA*^3W;;&F(QCKGf)j3(I9l3cyW( z+w{Or7@nFxIf&YQY117-P7|RLfPZReSFLl1zZ>t6gc-Nrp;EV5c6KykgNy64BBD0d zG9b9kWJx*o185n!Z1p6qGm}YGXFyn-`{yAIb*R7-7#eS5p?pJJx+v#Jn3lMr}% zoJ_)3DW~A7xD(?#b~QXZXDb)a@}57Q-~D~jF0K|ceJsEkE&cv+qS(;w$Ts|PwAa|1 zOb|apz<>9Ono!L4zv}k&@dYB%u6_<~zkcQDmg$(wX$oi}w=MO;vMpRI%F3oJ*$@)S znagE9mj7X?=&L05i&xQUv5cOFYiWJGXx=a2KK%-ODtM8nq8u4|B~v=7ua`-VCZ{&` z5|&;D%UD9tS@N}ob~2svQa22OWH^);1UNq5!D zWLV$o)BXJO?1*9o!Oh6jy}=sC%VA|(EoNwu&lZ#} zd535*x9YAur3Izelsi*NzSV1PK&Alb9$`7o4QzJbhOi}0XmWC~_wkrnSqGW#Y<7B+ zE)1GHnk|E}s+Kj~F~&tFNWDFJbKUq#Q|I1;wQ(q})@ElFHD;<{MZU`ykeU7cDKkA> zaUY@E70lLcK?#l5CsD*LL3= z=xl)ENS_=JOxci%zuZjuNB6o)0CcZo^Xxtc8)P^i17GwN-QCLOBkFQ3i*aqG8eryQ z^S+436nt|&=c*qNKq!;CkgeqM70Ys4CWTpXu!g&q*)F7l@Ef04cy*{=Q&Y^#+fwVYYX{W&782c{ zPKAWvoa`^;%EUdu!^1abgqi%RU=H=Ngqi3he}I0_BRBDVgz77MTM0?O`IfU7Lxx9x zVN5754DqW1Bp_jy@Xll(!GcIi;{iF zX($@kLSN*SCqi^PdRx7FOP{a9Jehn$bbFl;m_pVhT1S|*or%S-6D@Yd-~m8!tZ6if z`nbXI%1oa*1FY8}m>S6w& zBorm!V+j3pmF;T_5A{;9(naU>6?b_uU7MuRi`QOP}E&J{xE ze2pLSe3X7fpmWVv2#(>mB;g3QBiMhUAm)?K zs+J>v4L|~=N4X@XV1jci(!k%UmK6Gl{u*52;eK54Y5)8}=m#HCe57it^Oi$d49v%6 zxm9KFcwLS0Vv?zCk(0~@a4HUbcisv=A>^2B0ArWlm0aFCyxcCu)rAMQ?^pp@5SL>* zbcq5vz$4H-kmhi~aT)JFx|ajm(^e2X8I&uKnY#|(ulx+qrLL#G-=C`5FKql2mGiX0 zzPWH9+Ap+DH7N)RI2i)*+tVyS!9Z`f>{;t5bNVzDY=_}hQ>#l2w zH@*u;5j8RF9b-p1mwQ5m4S-m5;d;cB4_g|T(511PFIXFxpmf_0|4wq{XegU`^&yy^ z4tHCztn&mzrBE$G5}QZmxDaS+>F}U0PV_S9jQXdEaAZu?5!dL)M?-`Niq78MuiNOX z>lI4+TAi`|y(mbb;7l%y$!=9hA+t2=Dz^`Y9?=-P)avwMfgR$9`ukjN_R_Bll*UMZ zwz=yaU^@-Rk|JIEzI?AsqvgXHUMQl6c6xs65>&_ohM36rOn?q6Yn&Qvd=1Ha@Dfe$ zK0gXu*Wn8zK#zbB0rNb;*EK6qLZe$Jv#cgYPpif>`U}k@bZYoLH8BrQH`7@b8K1Y< zE$&G?a{AL5+!u{cp|M%y1N;V^V%uo~jZ|TP+U_Ea%Q5MZQT?D0sh3}oP}^PbigH1b z!R@?+?9n(f`_iO!t>hN!p!ASgL!PEg`W?gIjV+p*Ccn+PEVAa{hV`vPk4#5+y! zTg)xLd-#ojDx=`>Dn1fKQ2?Idq|C9MBod@v#g_}ZA-5P&C(Ckm@~A>Cb#OYQ8}Q1g zwGo`4WI{l|laTDJn#lT^Jjw>1;3U(r~YR&xXQc=nHAM=4=sL+^tE8|i> zXVmaVFz@tw`3gmsdRZSL*G5k&3m~M=xxt<+#`_e|uT$Zw5&ELHt&nuQ-<-)+mFPUw zS-~tuDHy8^)6OO;1LPYGA)ho|!N$UDK}7S4Bj1Ps?ORJS_cal)Jq6sZ9YK8}1Csba zI8Hg~_f8WS^+Jq9=f}n)_J!sWu($TXgE#}BheqVrf^Wg{VM6k{cm3`H!h|Kt!(Oura)(`bs|RE`ARa*DkQjHd`jJ?AiOJ;?rPF{DvE|+s;fa4NYZGN z5x^_qG>b(b$F$Su5u^80+-PNFf;qm1wnZEQG&E1hr+OLJ@)w613RXsvydq_8Wnp{a zV3D2NUUI7IPI>jIStZQ6QsIr3_=9=@zgh$JX8NgFU9c^mVNM1`Ht%=2`zpZ&dO|gv z2qFZPE!bsH^u%mmYnNsmf&jWsF<`=zbF_79grI5n}~2 zvat!9UXN1QkH=GAqbfiUJtbjx3AKXn4?9!eLvPD+MjyZisa;RQcT`Ko%K) zCuyE(;P#O!L=&AOBME#5ly;3Jr;h*jGnGC}3NWAuxK>#=( z7n9>KzFeEvXDTCZ%fywzWFQStKn=RTRCK1%{c`@IW{kyrlx!4LBb%PTxSemQpy@O# z`?gI9Q?fdoGXne8kDwC2T^AO74FoKkj0o|e&yY)Inow(QC1hIgYfTbum@m3+~e2!X*tbE3eQex zCp*nl1-F9R&3EpT*vE6II~uVOS#Ih%g+Hk3XoL^?gM%buwJ_ps#~o{dA+&fcroBaA9?go-0EfH?4}LL`F&l|uY7nMi6QtE~q_(d;*EIaw__Oc@D8T(HLk z_T7W7t5|gzfE25cB;N?LOW7&^G!&zNWyep9aWNRS>u0Z~t2)*evONCU%5eiL@VG|?X zYeodZ_}@v&#S~GYgp-zNyhR8ET&G%mj2Hbsf!h7BG0j_pIE=re%kF*?=VOryRh@(U zPI}5ZG-EPx6AU2>LfvpzzToDk9Q6};Leaavago9EI z4+{2q@~^f#WzzvxAp~o-^jARl1%woxFns%NmRtK|sIEX6mik_w3?=n$M^+9bR8~h1 z=wFl{o~wEgCsb%8zjg0jpoWbwn&4BHgF74NBF0cWitISbOAAtS*92%_$kVz(WBzl> zh%^%^LFGgL<%S<6r+>ByONM}+G5euWNKfYQaLzq(ZaWK&`WxBQ&mdjXddvCCbt+n6zQQ^)6ToG{j zlirFjL`z8o1PHWI@xtxPyXUw?`LOB(6};-IvpyWNVIswxN4T&`e0^w<>v#jpJ%P|`{p zI%TFWiyE4dLv*^vF5qvC!knRv!0{4@XOwiL zV<)nlXl}uc2cXdzmI=3x*7N9f|KV|INZ$)ATs20nlC)C~N>damCs?^2-QBOn@i_1R zVMM;5nfnS!*>~Cy;Pk5#wg_$1sjPYMZak! zk!E^kO7TG{z8?1X@N9Df*(Tj7Z~Faw0ejT~|9-Hbhk2M!_bvm*_%58M1c*~tOY?;* z#Lpk-uE4r)Q|a}KIB;zO+<|%8c*|H%dD}}e{D|(dAIqC9)a%aYsiUROrKOgVwqTdJ zITbx2_sH#m@eCk}bl6IMb)o9rqej|}mBgj{cN$qdhpJOIjIaP>$;lwaV% z;uvAwqFQQI}J8 zVB2=0YabsH$ZLz^I^*v}uy$8G(##FWWfU-+vwx>uy$t0epj&F6f9QVeCG0^TUL3{0 zz8l(Ll}v^w6OQPnl?Cd8QEB-}0J!i4$H?vQWlzIWD@Ro2ay7Uss8JV^h>mf6c){*m z(+WqI1NEX1A;&g=J|b)XUE)V*%}MJ>nJ|k zr7Lei41$s@qmVi4y$N&!_IKBS-1a#FRyD8m?pOHqVz7_h#bLbHF;{t@<AVT-9^VYPhJjiPE~TC7`?4K1RZMD|0;OqL&#p#H^pHY+#P2k74KyxWYCUp$Ne@~$ z2z71{skUPglo@EnN)U%ojRSzNSat=oIXHviVJZrCeiT4{6H?n$u_d$s>#4!Y-H$U{ z@2LYil6$q13hNpE3=tNeL%+G&rmnz+>~LR(TGHfKfSpJz}m{&mQFPQsm>YrCqs*v&* zIR*f{(;`o2mmCY+m?AW$D4b8KI(K0`KL)GtCI`@h%34~1{2HVx{Hmjl=MNxo-TZJO zlx6~MHRW|FZU#oRXw(kO{yg1Q+GI5XgIeEQxp&LxT0<1A8|zcedeJf&HGA`*4=4$n z0P+H{#j);<#+`wTvh;XT6vA{?RK2A#hnZ#>Aa{XNC1Nf^ZcD zV^3#>1i!>d6%q*zh+DAxR}8nJoLVY|6;L!=3uc1R$%l`i-S)T?zI~*J-V=ol%P*}Qo)GVpGkQ5X)0Mcm|*es zCo6|j1?;}{kCVm`r-^Kv6EmY|Jl6cE)EGd<+KCbJ1?BC9MTox!nDv0_0#0M(H-TQZ zr55J0s`wz)++4a`X|B?aK8iyQM`W0lu&@X5Vy9u#wec> zjuV?LpLd_V8v?9ww4UfrZaqL7U1ljedQp^p#dJ*BX)Bw znrqH6#~5>Ml$0;j^8-ZZLeKCYdr_3Gb#a_(sWeAHF!B*x-eD&1grs}UkVVD-jHFrA{1vmj_Phd#i6Uf{4XJcdm z0tVEtWKoXtn%$m;By35~_3U_hUeSGl(b)M1`|4o2Wi~ptuVG_ z)R|=+JH5(^v(h_QjJ1nWn2iSYa*fRM7k+fN!G{KO%Mx)~@~V!gSZ9pYE~UwGaoS{z zHkxqC92o|keFP`^S>0qebIEH5t~C}9Kd|K!S>zn`UBsECiUU&7ruh^1Z244e*HI}l?{ z(j=Sk9Ox%+dJD7wIIjC18Isax+M=v#kHA<41{+{)B-!mCz2Q!{_|A>yN-qWD%Rt%> z)2)2QF5^gXMwXzg8GG7jW$D(R9UgWE~ix)9#Xk-|^T}e#>J|kJy;n`CUAtY6Lal0H2_d1VU8;);0Kyzgn#7m{MQs*9S&7rF7$v+8!8^A0l zlOo>dv-;QpbYSyH<5h`+3OQxvkgP1$;oHQ%B4gu?+|1%HLmwm_c$1ywemUV0t4OvA zh=Fg6>Hd}|MkTMxf&^3E2@|if%1g1T*9{VcrNuH6DE;rTq=Tx?yVq}Wn>b*M7&%Cr z<#hs#v*~~}&%!uWbAkbcC-}?&LW;#W2ocAb$94sUgyTuNn)srr+}q%DxM;Tgc*^pW z&CKcVGxl7+F%R(cf##YNn)Q>niSo*yoq91`mCX-7^B=Bu;i7^R-l*~zY;hw;4b21U z%nhT(j+#7txkA_+Y$gmG0KBmPLbZ)0Gi+XP^b{N>glV2FmcPIqQI&7S%;FjpC94W- zW@L#6;@{nt_CFh0zN_3*nwRqaDcD;w1;q6}s#=!OD2W@Ac74TW{j& zTU}7^a%o=ueE;MFKo@AEz^>MW8hDNqM|g5bR6jb8DL}!0_bZn}R9Vz4Sx9h;0-GB| z_Gz_5izrqqAk_=f-wDAZNsqu;-Gj6HxhIj}mf825otYsgUYlp6n67tm6YnsEiyJJEOY*P;NM z?bJ;Y`ctgzV@0O*Y=eIfimsUU)WEhdV*!jHDsD}DgQ--`H36?d{W&wYCb-^JD&mW( z4L%iy(3Mk^pAh!`*;@ks9%jo>F+m}jRtM?aWWN&iaKq_&5qRjqr{yOQBQ-z)WdZiw zIs5`N1~Hh)mnn+l;xC{Q(w^t{gUZnjUa!I5nuJKanWt~pn%xtQS%FPzahFX&sk?7M zx|@UfRctLM@Y{h=9;Ve9p!5W!7TD0c0d}CYK2Qjka&Q8pS`*&V)AQF~v(vw!Ccvl% zN5+y`p$5@kTw7G7dnnsVxACKXArD;Qivs-)&MzG)Q4Z@kNocL1mj*;D{|EcUzRs3L zvAmtAG{jc3zW9JFfJ7KDp!@AACnO@Ob063{Oc-Z_{7GqT7ikxH`hE?Ye5+PwPiqrQ z^weel3Wf==5DM5tD!gaXmM5Gx#v3XQbox*I6=TlzX-0EtGYiKie+EDJ z_l?}d&d$a@f5d`tidmU1H5E_Y>g(X-v(66ufZwuAH%H0^CmiZ#>e%Gd2-!B@N0L|l zl=p3wncH$ko+W$z;dvhPB3VCHVzB$srUuv{vjjrZlyY&jJd`Z+x*HjI`s~m3uvc#J z+i|%J>b6}WIlX-{xE9u1eVRBusN>E}D$N+gTKS$_U~)R0+czb)Z^7iSOg;`zmIdic z7P%_G)oy>|FO1Cyk!DZTzaflgXdI|*eSNE}?D?-F!;pemW*&yok?2t)slx{A=(1-n zWsC_*Nc69wwz$YR{+bcTNPN2dlRWXDo67y4GkI%Qcsac1eH*WNb0)QW-)eG@1?}=) zO7iydc6OclqoPm20m7;=n|+#{RL>~dljJ6uciF~o7tBg6%Z^?NpBmZaJN=31l2Dg$ zUW`!6kf%RxA5&Q*{p$UZ#rQ)tj_iAZ-nK2+gnPGMZR#hFw0Zof;3}^0AEVD`c3jUm z?@GyAxhcH#Fn#4$MEHAy2MEOPY7dgc zICI|cS^pq&JFYVyW)hy`bfI~gpgv6|JA2RK7xw)}%x}t0W$e8&c|8Zy=$20NHvORh z_PjW|dopOzS5#VY{NrMkU!7I!a-k9Kcz1B3t|el?=I#4^%}hYlDL6Gre0s#Ast&mXE)vr;zkr`M3UJ zgETA2r)5ZaP_cEKK11<>D<%4t+v)vZ;LaAJVV^FF!m(?ncCJ-t^^`qDYk)1ZJ$+jl z+bqX^KV^JA1hbAkRCPuk-F+A0lTco88b4y1$5FJfpiG3JMiXJt)8?V3{+|4R?E$lP zHH@OOUn4GGl%*zI*m8DGerI4CO_a0bY^X&#k&vh0K?r}hEYh__1-$)bBuK{nZ&SMw zTH)G0Sjum?hJNupyp@%N*H`;cjY-jxJ_;$~Z0dtoTE5FQQvlcL8jY!O+E>YTJqNlN zSHkks)RokE2)qP*`y$7}BJD|S(5$d&L8-Ie^D;;21eO5AT~%emJTVtHMPvYBWo15A`$bg)yr(RAQZ zOrb&8Dyh?imzFuyMcUgxOWPr`RV@QdxCz>9)OOcb)H|bF9|ZAOrH~-5DN)A22r{V>dz9kyc+seC{>-FgNf8?mu5Lhw+zM zi+VJK`)Qr52SkL8P{jKg#lPh)a+9pNu9i{buW!Zv9!)6Jm2>;cisMV7+z$sYl(M`d zt-n7Z)ckqlD@D?CE94#HZ>2aoixRa~L*;zDf_!i`zpmow|cGT{c@f_5|uiBzLgsq5pPu+P%2D2qIkJl&HLo!-AsY6RxeMR# zkYi+K1yymV7hPO_t$o9{&mJ$~1p6g_Mp0tIt|H?SX$S}C9dSkHk^Ia)%cKc*TGPAi zZODXiCxy2a@3&$L$g*JESBQk;H+P9v>?frF^ndHt$95n0$_ywfV^+AV)lR!lO2{`* zsT><&tWMe42pMFp>PM(uz$4;oTaOosP>T%PJal13Z6ggPj*hbO6yd6%8Q03KiY^uU zmRiEC?0-IySG&uytQ|?=uT~q3&}3xVlXJ433E<<~XxY9@hM+1B(`l&ZX1RUN65QD?wKY+Q$`;eq z%|pAFHN;y3=i=7&HQz~V#!^{UFj{w0SRAALyn*(-8wvlJ#0}zdhF|fid|SJ>$~tAE z#hK(POw!jLy$kWGldc-4J>N}rcQ_GNC9gH(rJW7b{(E|cWL}FSdc3u&1lj(VwS2eY zbxPGp5vIbU_a24bzt}-LVZd5BWFtswl(hmv_TI7hwun&{itOIIgUH{_&PC zx3^)?Nv3NUgVnbVz=hYJY9v3@6EY@bpt^yi=*)1+{zdfC?s!f3V5VsG#lf#9;lvxPKl0N7ZEE7oF^3f*QH>KvE?{4;?~PbIom>@kQMyKRXJn1T`; z@+gcU*req8`N^!ds}^bHwE3}%j;QkWs2KD<x^kz#2QM$VJn<(lNvY7%-C=?@7z~d|8l;O zgY|9}jf1GvyVPIXckrp$N9&sqxv(@cX~xZ0jq@MMU6S9`qB05MHr!q*bOS&#SDE=& zpE+0V!P?xO;7lS}&hA$|<-Bc)>u#ExIksB$W1hprlauA2kaV>ACL_+bS^USJ^Vrc~ zgbqiCMsbGhcJZdW1xZC5t+!9rMRO||=ju8p^I&Pu_|NI?vOf-Y&4YY6jzTTr-YfEE z%@oLZ;5~+H{|}WmX51TjQhB&r*R6{c0SO^+Zw?G3n$sTziB2VW;=NcHf?Js~alAM_ zXgv(B(b4{991ItA*?icytbF(cygQ=>Jx%EK$DQ)G0!GQ%n}=psU5Ud ze2(8G2)m^ktGQ~J-MmMVxBN?nPwZaE)Har!C1YkC`tlYaH-KJ)PvsquK|4+LI>DTM zzvgG2gi4C&uN*Y^E|YD+$`Ems&qZxND!qo!sBHMR`tG>AQt3>_9#D_Q>TQ;c%tlT0 zID~(2@q>e|Dc>6g|Qsxg3hqU^#G zhpBM8#Jow$XYj^xHJvWw-Vb)n1Di2T>CY=3SGGyL#i(C6ogA)m!G2w>o3VM}H&#dz zN-=kz!me++kEG4?u6_P1zp3Mice@;yi`S(p)w=bIaa;Zv0XD4Wp5Lo`BC+bt;Y_DS z8`FEyEo&BYMx{803P~SxW*X?qIS}pb3?;TyRU@!UXj}LikQAEW(yxPr$|DFR*j)~; zVNF~c6LOefl*JKk=YYh?YgX^dZHG_s_*sCBo4!B9WEQvs1zaZ`+r*yxxisE%L0k#< zN(md!Yo8(K%EX0~M#}PAC*gD(jHr{dka=G8cB8Z3g5msgMiUU9eZXo(0h8<3l1$%gFFQ<6ej zqN|hQ8+lc6ly&D=j`=-ygF)%$_GkZIdz=Cr^;EbEJ?q(98kAZh=l>#q1o8mI$m`-XqK$_-`93rpoe?Esa+2JcSFI1Vtq*ROde7+9sMMz=ooNLQXK#M6+kFsqfNF7nFf=LUZ}-=v&{=Y8R`JwnF`TKwyw1|U@H z4<&G(uv1nw%cWtr!Yg&(aMiJIwN3ih|0*_iY`HBBjm+)|A79)9f7;upXcW8^sV};W z*a4U4iFjcBU8(bzeR5(MpVR%}Zoz&j4o9J@rB+Io13sMJ&BUiHxGsM%+9o@fIPT6H z+ zWQbt!|24?UI~mL8p}hn)h^92g`?K@5W^jt?Fv#r8K@YeND(UAe$H&3hg#xB0hI06x z`A%bYRdb2ycuYucm$JAa-pkY^^$~-058G^6$ub9ENg5~jUad0 z#QWXR;yY~LYdwRRIl;o?JX=ziC%>i9h3QMPm&^=3ciXw9#aR1av!2g@TrbZn&ckmp z9B!Mlf4ha?c`aNjfQ#41g+*{PU6;|0;kayfuNUP!N(b)X4ti?oluGFL>NPge^kyE| zSp;!;pCa@ErN=Zt5mfywyB_7anJwqLOe(AvolR!`lJw4(MjOU}jn);*j5S@y1g0=^ z%P2y?=BEHD07nk|;qk_FUY6DT&tiyd?&*@=yageBQVb9EoUJESJ=t3AZTX>GP7z1z zJ2#I@260f=D^ElHmU#(QbK7ZCt}YDc^0aW7khUJMg==`D^NmTTAA4`f@lj9H-dAY& zx4Ab4SL##0Em9`MwC4jiKW;$<5p8P5^XBwd_v+AvI6w#QSSp5i5Np9t3_v->=lTt)PUOE!r{*8qd@J0s zg&c-}l}L!b`7kuniy|3*uD03VxVNxzp{rB$)}E{BbQBGLF(S3Hd+9`Uaef+2wiPhM z4a_VIiu)Ov0qj+6OC~?In&c`4MqAn~|FImAqSgZMtK;;nTS3Vfc0KhT{Smq)z7g(C zKkbk3|23iiWLcRtl(?KR;pHKEO7PAzc)o?_Dsj2;{WLS7;egi8w~#@$8Y%l0!l#&< z;(wQq*f-!UP=)oC)3oj_&110g5<)wtla8Ut`zP+kZCHsKW#HWQ?8{EUfo2wEUCOXU zz7Ja~p!XmUr375qfC&=|b?xr(c%S@KZ1OYU=A^8NaD+3e9BI3fB`L$*FP(&uwa7o1 zXs1(;LXsY@tJ5uRceBcc4Qhw~8DJo4Y*5|we5ve7t!*bgXbOuQyd3 z^99B9(9#n4&f-nZ?sK--Z#EjtDG*2eUDCV9D=m=@al?6Wl<9wR!$U5$m1UQM)Be!$ zov&pGpqAuq({ex!2qF7~($89jYMZ$apteKqucxZe1x(9zB}64M#yiLjh!Y9hR@-({ zH>l|8?&IU`ZMxg&2>0dJ)i_Fbg8|bqrLWM$n*4Kc*4^&hhtF8QHGq^G6PlpX2vga@ zk`u?KrtJFW+=vL69Goc-y7l2zOu1|CkTyM3wpr9`L+(#tt8&zkP{>c8vjO$yKjL~< zjyVO(SAi(+g7|=K+x1IE@;*uVOUpcT63V}*bBTCeEiKj86|&XT0ry;I@^=o_hQd5h zn1Aq7QuJz?#eZr4c){8>`kpOt5Y1=8g@3(EyPVkAC%d%6)#tYb2|wY)Z4?^3r(-B% zIu_^zZS&mzPr{rdXJ1RAi7N`SIr2168|#vHc2DYsPH=Q8+3em3*j{!Q@VC=ZnK`B) zs)xf?ld{vBvB;PJ=hLF$4wfAKk^HIw{>0Xy1#VykiWkZuiE{fT3iZ<4l5c_ULr%(s zCGfmn7s%%@*-!7cgPsuW^ID@DJ8}3d z{G&L!1|TR&Bc5K^y(h~H0{(GTw`e67XN#CdHBx%llT{4WK?I4|CsKm^G>90w9vw7E#Zvi8hOc{J_H4lxr-s> zh})G-w~{V=tsZU>@~AsGm+{CEwH5bZ$$Bdt*=0*kr-gKDl;Lwmi|Ah=V%!Gag~x^| zZf&CV!srxq%ft?!E+LY-%&W~bxt6bEcE01|e@EY2BuS6^Z?d_+4y zBz(?C`Ph<5Cmo0%W||Ard;J`ts<{HuJ}L=XkM&zI1)sLVx@M&K_VavFuJj_Tyr|QHkF>V~==ZoNN( z`-J)Z$4N8P!B`OVbG_xWGA`*@H4?KDUng*IGV8+D|M(brq?ocnqPWF!)dGTvG}1`3 zmWy`JLzaqt%|kS-wtNz%zsIN;WfO*;`j5p_+Z4?L6^CoWkd)R8CB zaWgoirFa5#_xzCKRKfLa3iMUX$g6FWlL`ucji^;@mbMhc88%^Ia4EEKmC+o&)enkD99X5>*mAn6IPaLOCgMYr{SBeUdw1o@Hxa%C0Jx%q+NoZDMa4zE zB0R=G$IRt8$RQ{HLcU^eIP8y&6o!Z`?nfN_X8~GTk&;QgR3yb$txsfrcMcA#s41G> zDg8&JgOmT@e8>~jjLne&$UDUWn)8rS9YhEz;qwsg)V?$U8!HyYKSxIy0CRh!X_TYg zLkpQ6a(PEual)g*VlcVvq4v$+dt-O)5^9kH$5wYm5BPLwJphrVu7#&7L5!Z z;u2bZ^a0f{JieP~ukG3D6sVwNl5}#|kG8X~ID>Pj3R9%`6TZW4IH)$=FR{f#&B9R! zi0LSuV18HK$h{gb!dM21P|JL7o= zkIe?Gr=dg;I#F#zcEJg1eN`~9UH?NPt-}QvGJ$0cKHA;K?Tr;OguBm5+UOy{|Ev zIVYP#zZ~J0^4mzjHvd9Dtivsy7%DUr2}tA-z)6Kz%ocz+E$tQ>aG>l&(XYoxW`gA;Z5Pn|n zF)8Xrx4I14^HOLjLi5GT*DPbd!#Pn%1}tNt0~u$_fF&IHRXAzr5xE|-2dt&LBZKm5KX$B{@?%!_qYpV$reC zc}r>=At$v^sO+L6*%aFdY*J7MzhRAi!<^a-i5I6hWhWLiE!!AbL+C}bc;lC-{@A8? zN(F?lw`%WV9|CyC}k@I6i0Ahxq9Db!ZMz6)>{IYS(HX+Q<^0! zrY!wR%}W9u+u3M!3jc8j(wvo`cK(M=1|L&kui4Y#b>~#)>PNuqeigU-&na)g?F@Vt zurSMJO9qlD@FS0Adp3#l;WXX9Exb7AV*%0N$90Af5h*s#6dZf>D_5u=JWzW1a(jC_ zEiG-c=oe+5f1&m+=@;H|n`?b@0(!CwJzI8$=WFhSb>D9{Mo2x{x|649d|)JZ|7}9B z2iiT|Yby>THoSWL12Tzny^@M<(xHdqW&YYrz`0d=3R0ri343#c652zxx#hkN=MHKg z=~~f$mK%tp1EF-8IOJ?8DyU}zDXis|f*$T)U)blAD$)1FQWlG+c^Q$TPQlYTyEQgG z{z6z-p-1)QOOGnrJt8OZ;?w*aSr{V=K=ZJuY0@u4oI%euz57_AtkEkyuUX;$f2G}h zVZyQ9c)Fc?hZeHxk0rBWI&Stq90qyychM`Pka!3ya_g9E@a^0zidlBK%7lbxzxXP% zI@zt4T;4Dmyxbyga~D{C#*d3LF1!hPUaW{;tx|MsY39VcolIYqPG4qjrB2_)Cuz_3 z82pL`H3Hw7yKQi9ogP_pM*0U8HZ?Vsm-C%6|E72B+yjLRiiOK_X?!ET!bUTWG(M*8 zc_TIuO*4F4eH-ui3YQ65Uw?8dTDc58PVy#ct=sD60_Vy!U04rVml^d5uhNDs?>3)K zmpS6*z|NW-ugX4ejbnzomz+W0t2N{9sW9LSp%kH5Sfh>Kave3b?hK$?0BsN8D#_eskAh*rgp4=ngFbz7X;eK{?uM@0=V>D& z5Y`<}D+i30IrVHQC|8OHf+TVtk6DM77`maa;20^)3~4-9?87V&S-Wk`)J|;D@YZ3I zyk&?|(AC_~aDII~CMcn~HA;=%aQj%!E4F+|r1i`hZ?e{`ATg(y4>;TWOdv3~?galQ zP+unmn^++F2D~@J-sLLjAztA>zA>B~Oo{HE9b=g}`mkt{V8Ea~)1H*A(Nz3P*kuXm z`}T-|E#PdWQ0(c;E=3ykotL>&Ui+^CCI_Zafr}HNy_wd@>MOYKJ~%l9A`b|24bcB9 z-HkNm8lrLRw3QuyByK|J`&9TuQaZDNB^x(eRfc?v@U_22!v09dgMyHpX6a{p&z#Th zmJ{EkUaHw?$|Tv+uwdNs{{SY0@ap8{5OcnU8$=^#Kb5ZiSbP(L=RR_LGjfvnw*bPt zfq9o*~kk&UfweH~TsG!(3> z)8pgV&ktXmBMhKROd8i?+q{|2!E98z7pY1d;f~dp_(S9$4}Za`_(~RNwRybQF9$DT_jZ#__>WXCyx=#l>tKo2IkS#Yrsii1CU^Kd$&55g|iu@bbul{Nz=buuluh@&-B zC4YPQ1-E(pKN_e+3(tiKA36VHqlcywj7=z)4MSJN_9l&-eC-tyic^{A%^qq1$)E+f z%;-22+MA{fOw!MeuDP)DTx8SiacaJ5-91UxTmIk&gfpJT2Z^zvPmSzo($rtdnKHde zAJO>`#}`@;c5IA;p>4v&sH>}*w`1d6#jR~n@J4M!{6a$2J$N^6tAXs*3~l-myfXC4 zU*F&;VeM->h~m9+oA*OO!vVc=OGCflv}UVjCrtO*dPVi8UTN&1Ged#HsS4~{t`ahD z9bBsPg(K9%~yWYt6e5KdMldG98tGPrRmC@*^BOe z(0*eWvDlj;t`qZRH>Y4vy>FV6bK%!TTc`cnXi>_q_McV$-`{>YwS!EFJ-RXBdNL_^ z#?HjFS~5dsS(ZAq1{X6=IK||Bh7=AOo2PkMd3^j)_8N5+f$!MMmos$Fx9drOpSkZw znbp~Q8eSmuoAAO|4j!^pZ4{u(%cO}Qlv+XOx)0(?(3 zDs4ak0J-bYBRpvXpGVqhW=+Qbc<#Ej7QS5)abtjxpKEb1-Jm@FJ6Ege$hC*e8tp?@ zLpgxzL|e(^0Z_ZZW6G_Qjsq?E$1ix>$7BmbUCwABP2*L?Lk0)$^12hNRK^NaShwA> zZ(&gMR$iQ!EmkdV?JUq=?8M^p@ozA4_KGQwhQxQ12FLlwE zp?>S=w6&+PHSBHx8P}CFwPSf@L8pD1qoPx>mFQkEi3g(R8@C2_KCRgo6reQ*SSq;W zsHnbii-$lA;CN&cf!Ub$DfQWlIK-Dn_=^eILjgNt?2KzBeAs z?{iWgir7M86HqGrH+*#2_2aCuAUTLa>7yLYxrXXMl<12r+$0!^0MrP1?dTgCQYbN- zrsrLqOk_$?cHjH+V=o5lsD^b)QwHLO@52+FbYA8vl%Y}D&A|2pF=Zl- zhyBH}Y1P4mllbwo$D7zZLnl+72aX5p`-|NK>L)u3?eNQZo_21;>GM-c+sjRx0fMf_ zi;4K_6a4p1Jd=`Qlv2LE2!)^VV|}y}#D7-p`2yY>dhS(Qvbcz(II}tuq`kNkO2R4^ z%~PO$T%6l8*tZ)HAb9@1;p=32n)4`@!ZN?eN)a9BORsU+S2C`I>@Hc2VLMCdNv~D6=dU_%l}yIl`%k!%RmA7N z+$VXX`RNef@auj<8eE*`R`y}3k4ZHnY2RGnG_UN$_v|+}N9olHY)qWp8XmDSBa`NI zVu)s@t$X)S6!0uatX6_-QsA!YqiA?e)^c1y*B#=sKgCs_EZdr`Q82r|YeeR<8FaKoQRo!2f z=3qzf#b?)x+XK1tB^7inADB!S=`Q4tA~-4I>b8#e_=WX;g!ccu|KeEkQ9(q`QRi?Z z%1(FX3Q(jxc(DP4%ON5RQk91uu2Dv2ZD@ z6j+?7@LY^j9B{4uT*AR|4oRhp=3b^&j($UbdRaHxeMdO;mBG#u8xt%ZeLlAd=kZeR z+!R*Lw_ou{y30S}UEon_`I9zXJgi@mP=%+gZc2&59(Zf%uGMZ%_I%=5tCTDDa zu#{Y}ls%67|C}|G(#zuD7p>TDE==Pf5;=R*ihl$?4l{FPaef87%69tD5!e zQ%<+;_xV>n$};D%+Z+~rKiEx(r1rG5E&B&Bn_^NczT)ncfG)wVu!Xp%08TEDnzu9v zjTsnlHO97a8lk=C6SKOydj52y;-F)9smjohyM^m}d8ujf>5Y55T;i(3W%gW4Ia(T| zx~kmor;K`TkxNPQCy{&#aw`?O=|`D(b3f$`{;zv*WIaq?Ji|@ z%rEdOPe0uAYdOGnbjLfdI(qAqPl?k^nO|n5^s+cejbb!iP0hrxtb*C8^wZxM`VUnv z;4!udF-wL_=NEckZl1V`*I;}F>m6ytMEG|sU znHEgLNL3z9DWCC|7OjR(!x#3+z|uhDjl5y340dR+jnYt4%l%dYw9Ls?U6l^L*qSC* zxR2hLZR3Lpfyx9naGL;R_(;&pBT)B)#D1Y0Nd3*+P@rZU~?{+8@0T^MCQ;qQs?m|7jt#7zfy9 zn;JqH;OYY}8j{(B=tQLOw8p9jlLx@hXjzp_fSC9Du&|Ww>bzC1XQ?3}NJ{QpJPKia z(mru3%}h$5AK^eW zS~U7{zv|sdX2D5I0oUarso?Y5V!8(hgr2IiC5qv)vh3e^qR()gHP;`I`5BMG2d~fV zY>ziXzRME>hb|EvIlNV+U)5|Mm_cafF6J}WpYk=sV06vmNKh0KXWpcw&e~Jw^Lf;Z zb!RC(6ABu?i$$-UE2#eJ&tVk2ksUE$XO#3pV!yaRUAPCHs>`o1Uk)naVfSOL{kfzIER z8}NknEw}~l%|{f(r4d_R4f!qAmJQ6=+l$P%zE=ZGaKl7+zC|S=wZFcrC`)Wx>WWVE zQ-7e^Wepdqv$Nsrk-%f#=6gT~BP2zhD?jvQJ~0x$fpOgET-#3UgUa}LuTIRTB zXbvU{8eQj)gIDxHq}e)_t2b-@HBa&_oM~trH^IJlj^x|O#M%78qS>IGwA(Blvq7V) z+vb$1(@A=Fx2lv8Vt7`-#WBu6ZWlq})XLZ$kF+g_o$H@A?u@yRA&`n?xwupIGGI4X zq^EK5g1U-*vVqE^$Z*s$b6o9Dg|8d|Ct_$aB9#qM{tSOE>r1}vN=<*d5$T<;Vf~9M z0XpSKzugFh?G26NspbB0>2NtE(jd345rf@(^o^3+X$B{ICku1okO1lV<>y@0G|4t& zFHWs-S(8w;&gzQ^|G z7?BhozudNyh<9R0Nx8puuvs6})MVkr9ciccJATPeoxys!XDyhSzMTqrZgIP#(%5M) zWzzNhbmjgl>0PZOUaI(+e|BUPn>6&+q@*4*vlb~bcj?O}n57tSu4~QratwQBRZ*Jj zS!vw67TU=R-72uDeLK+PBM~>#<5S5ku9b&5lU{H22qT}_ixl(JeP-%(5H2_)EGoZY zwB*vIaCA6}|Kde#Xt)!ru7Eb`dX>K$kLpd~Qd2$tqs^89rR=F9n`GFCFibhXZ}U-N}}``RN<-W0)Tg!qWX@7>Ji?`uS ze}t9EFNQym6|1B&@3g-<;7_(7`3SDvuwCHIAyggfF+<+H>mPcqWCGbyd5l`bmEloR zf6holTbzx(D$kX9sv^+ybz<>D3uC#JHbx4@b#xBi3~rhl7)XBk&&^x@4$2M~SwJyD z=@oanK7pfQ-AD|BWu)R=L=gNs$e<+3|ADdxsVbQm_8b}Q>vq_Y3sAWvUuQJiB#x6c zIVgrM@k_;nP4|60$v1)Fv_?ZVOdQUX=9#;ylY(-Gcg=ibzMOk7H3o&H$Ok|QTUaZ) z;77ivvbjc+9?Ppnl@v;7=*^CX7EpDv{-tQb@fPhs?pForyP7#_#XHvs$H~9vfOM20 zzq_fCi((zXAH7hA3odKqSDyTeld7#_G#yjMi}Wl^$t*MgE&HvkSo=%8=oBT*5zR&6 z{C`q6pRk`6sAc_Gl#o|d*INCEH!FBJ#gFdU-J{!9uy3=Pvs=@XD(3nwu)LHGRV7^x zr%xV;hTC8C-uf*dvlc#EAf=?Uf66rZu`diP6Gg=I>KPQ-_^M zG}A>H^X{GgILB4(R?26*lU;+B+z(`)&^VzkhM2rYGKEQs~-#p?R6awN-~J z`@Fvc1db6ETe~)8oQ^L{=E<&Werm!uOo9tZo7s6o%HC+$bAa-HpQOCpKj)qH?=k#k z@GIefNGft@GTTsBQ<8 zPgn?d{SBYL7;eLM-8dSK#q9Tz)rUn_o|Dn&TLGK2uiFL^q-W!`kFi$OKciZW za`<|lel0LR+3xhlb=dGcm~c3Ve*OZBb@=UP#`)1Wqxc1>b9-iNe-dUxbD#rgV_d<} zTZ3)3Vj=LueK6=%D=Rsx(h148|F9D5-4BzVA&P5dGgzaR>JZmT-TEDVv0xzzBf5N{ zv43R8D|&FrU#h1l+Gh~z`i#AdesIF)&t7$dM7X;cED2GS+Hn;kqRk%R{i6nTvR6=z zXKLc_3`Q^$cxU~4h8O8AkN{DWdy@(ITTXd!$|$#Ywupm=Z;eErnw9{ArSqAmzxi2a z4qtBcjHN${oA_a3l4ktC-~~6aRQ6O&#G8A>*AzWI4F*jJR=r>4<=FZCfbs$Vbre-U z@?%jW@fl)UD@Gmv@#-StJ^sR`w@mjMB5u=z#PI)I`LZ$7?`uap&p=Z@ejyO3mS^Yz zOgcEi>diPr-~;NbT&vSjvLs02S4b$0xs%Mcs$r^%?*@(zV|pj6)w!M|_-q!RQ3Vi4 zJnIq>YN(o8u_x-~mg(cMVIhu2pI86XSuD`~2qs{m+0*L&iak=`lZ=gNAOX|JD ztIDeZ8^8PrCdDW!YQPMPvcqHYfQJGaM=KZ*;)}y>AugXXzKIaxke%-bUmba6%$Mtq zT@807AJ_j*pl0*}x6^dp13sZ=Ns_-_-C1X|^-7$0If}Sl$%~sU#;oYH%T&)U?I}uj zSF@|9_Uc#_W~$Ffp0`MlYiuKkWpCzv8-lL$NlE=DY@T!%Bp0AfndEzLxCSz!|K;~s z(R(cxfFc)*2G&AGH?FPZ{2So)|7lQ==+(rW^zd%LT1o6(3|7GrWewj(p%i6$Lm&=c z!Qd8FA52Oh5T=j*r@2^4ZmH%k(cm8#nE`GiXlzE-gz%w5sJNKM$(((XD-KfSMH%m#aZ#911xaY6w)%GleKC+{=t@^6+Tu}i$t zCMnrVkXwH(rv~)BU2LT3>4bjv6b2%W1`O6<6m7Kp2UhoBFrY5$X2a48=cI{&Xle17 z-E{w!A0{Ft{jrs8fgo?Sl4EbEWU_ugCVBxUgg4p8ko)JvG%vP@*2_#BCn++|Wm0zb>W1H2`qIK`#P|P0`-1?;Phm;_YZOs3 zo9!TF`4dAKHRb_M4b(Iq4-RoT44J5r5|NnO{hAN?<8Y!N_0gO6TJked;K(`znXuIz zgsBNrR8Isfa{ z6wVJJH;?6TwOw8+DEc?Lx6A}gSe7JvgBzI#1GNwu+SD``aQ!TmdBL2@PvpLdffe^e zg3@chT4ma|n^^5Wg8K;k@917Z676rz|0Jr-@gB|=2&F9YJB1vIatCOw3b@(=oln_I zaG7Hxq8CRn(S<6ZWzS!-11;;PSafnQki66g9#?El`_Ev9p`0WMKR{F~M@!09#J9;3_ zP5MlD9*VqsSOb$s!?>K-kl}|}ZVTVOt@x0EY-#tl`5X+YBHWp}#B0E(iJIOc(~m$N zOTGwvdzobDgDsX?mh^;tNAnd^jcE+N47;HmP;dp?J?`dtgPl)*$AO*umsUa0HBsab zp^#C~SJ;F%+-RlRlD2<-1%VOFsutNH|P;cE)Kx_Hr+5T;+fC38@w&Re* zucY-%u`oVhw~+ln4{vB(ei~isLbTJ~08JQWmlJ z&n&`V{DqBgmD9L^gl)Z>%hd)gKiDF zr`73O*Gm_WMT?;mKqYz*!-d3A2}lSFhTp*E_{Jq+0fz2i5QuVs?z6mA!m*fOa5Ri) zVW<=!zlMNrZpvtY^P@^|K7s?alAn3rz~g`w3UD$^6XBSxY-Mx)=PLDyq+I{6R|(IM z-~Qk3W7K{4(=~D*w2E7D0ySp5S5Vie?m3q9@1kKAL6&*^s2G_11m18$_~Zv)Jx7>w z@i!fU{JHNDx}i6Hg(ZK9J>|^zhw4*3p3&^voF@*$j$JdJAn~$Mj+!mYO|M;A9})t6 z?l3W&!}U)9$k6|z$jlaS3nSu0!E2mfMs8zM zNA;Qb1c|S4&Eiub2IW2e>$HKS%|qm$J789*!3>T2vGu+}h{Zh2E7QC_ zceT(R`f?eqVi2wWHO)#~F?58RLnz1JfG%`bPnI9tz+gb3Q~;Ab8X_Nn3@um*2U2dq zIDC`+X1GuDwv#QUoK*?ACBTII+nb2n62VP#UltSuM7D!$rlTUDd9nWlSsOM47qf#h z6I|p9$=?XOV9ylj{Jc3nT`uVOR`l{~L=#DkV+`lG90&=$sl7HY0d&oEE33}4*+ypN zl*Hv?f)fbFnT|UrV458h6(tcgX_hiooz`ddsHYFk7tfCQ#$$WD^hSunKeR_cW^{O_ zvVrqJminP`U-J;CU%;*adC`;odT6!#Ps7Z1S3kYOS+XH&=n%jEVG-z^schZ9@&0RO zVIh$Mn z#Ht?V7?-sc6&KEr26lUfspWBk!sosi^*0Z}eFQfmN2tm)nh@!Y2!5V~r!4K#Zi%e{ z($dZx&U&nuHNaHPhT_V9tpV{sqJh^AdQT*xoMk@kHcvyHnaX8_F36AS+55f$Vo}yc zUvcdLJYoPg=i2WN<;I4HK%4}No$P#HUf;I(5^hyYg+B*hPg;Q z-F6twEu-VW3a}-<3|$WTQoN75pXCI%iK_8h(3QLqwnPXXnr*6P_XXf7tr&aID|={l{L3B8u!? zRub8p$R?G&v-jRJD>aW<*(+OQXN!=X+3$LKzdzq`{J#J6kB;NHU-y08*F4Yj zUN1+9R>6n3=nVJyEKO;5Af*5wyDex^g5r95-U=@urh%e9(yc1+cPY+{by5H4EqYBN zH`~Z$yUX>BKChs|=({g)s#Hi9Dz|_~gAnZs1^74Rbp6FC6AYyRRRvSdUnI-YXDr3( zX=6wZ9R3U0v%-<9>5wcacE%emEePA(03Y}As60d(`%VE}KZm1-f?|^u4R}pEnZK!& z%8QImW^i&+OG5L{R1Ge+pWy{RW|4hdwW8B8AzGBNOKFMr>WMSB;P5Yi)(6pxsJ2y= zQ&oD+;Mnl^l8{V(9-hBfyrAIs0ibaK4C$R?)xUD8yb{NLr7^cADS^)=PyvX3pV8u^ z011@xs^9y31G?G`Br#VSUl8<*JHCeDH?#s*pndVK_ir2kQ+6hXIFPaXLFwU1_ijDL zUWE3D;r^wYhf{s0=SO@_jjzbay=Td%a(bVx=9RZ4FvdZh0JX%L2zlYBXe`W-+;kon zh9qC3qxk|Lb7?8#M&{P+eUhw*G;^7J3?3(C;2RK7KvhIGh*l8s=w)YlNIbD;umCcZ zF~Cns`2{#DB$B|%BV!XCxk=?h(ZcpM-Z@iVoMKf240o&koTO0B7Ee-IlK;C&*BvHx zVd5u6Y2b$7=H(@hFBKjpQXl{BKaLEUX-^;q1IVxppyo<*0gQScw_`?~!|&SRNT){C zYEuaU4}_izQkpn|*9~c;leMpqK=mM^Xy`QyJEaI!$kCGIiYxo;5(xtu_%GL=#O_P*JR~CQFRsRDjwP! zslj+2#^1G#ksww8(dM(3@-4R98h{_JJC;JEAW%-_4$D&hVb(dWtUhq+WQe5nBbJTC zx+Vi}woaV_7!Q)?^g-gU&F`|2=);lWuwqAj1T%@kVFQqac&ILOejmg1jMP1dWn8V= zte|TO)9A^C_?P&M7)WIxHjeJ>|3WOKFHwMKNfN_#!695^)_9(}k@cn9Isw|bz|vg% zB>2N#j`XFEnl?{({+qu6 z^8gI<`h_V$04P>qaftK+x5=wVe1`sW8*X0pnPuHGC-W2gNs*Nz6_SfcRt27C+d|pj zV%J9?y>#T}Lma&?s-lLpK?Wt zNNAk>t3bcuZ`O_v)xQVP`&1%`$qQ9kHGWq8*4OT%a(8{z(J2v*KgCYsSgm=!`IT~a z7`+c4i0jeLJR=y2ndZkFk?aSMAcM`+L|w%)$w5BcGkS$}2-!LBqq zEf}k~f+jmaji8(K3sIguXL^>n-D;@?G*JYnCU9)Vj{4SPreQ1&NbscUm|XNJd3yj0 z0eKQ&c~*A{TaCDH+`9E+dwamNTt)ccUHed<1jqG8^@D)@y}e)6G)yOp5x~WO%coJ1 zDAb+y?d}Xf`Vy!T3fy#b3w~ZE9a=4hliD^_Nsp?|QSL8)xzWI~pq{$UE#8mfcf3#- zz?%`Oc-)Ye&a(YW$Ywr&e5aA0X8q9c@aSDZmi$i^3l{-dr@Aiw+(^YU&lC2^)3HBq zd1Zt~wfrlsCPpjISm)fWw|+`RhbfUJE^STiFSf-eJ6!6WOmJ}2{Se~wzGW+e9Z*gD zWXyDVAFKaSt!X6IO?dz~PfICvZ2BX!VtIO->&9Aj9vek#NK%Az5hEL^t(e}yyG6j@ z!vGD$VBdR^E z&lBd^@SiTRO}p&IcX%4@HV5{48Wpj!?siVe`~qhHZEmP;UUeP0`L%!m&*S>O7R$HD zK>044@d1;?+7rm@2E)jK(f`g4JOQSfHlXtX*92I8dfI!GnU#Ruj6;(G93wh<&71%J z<|j`I*XB(G?M3TpAa=gOEXTr0k4}#()Bx;EOJ7vQ?xq#;=vUkpUw%FN-SaS>Dr&7n zB!HLUeK=7{P97iP*V4&T3|q--6k8`C!BHYhemkTeaLjVgCWJdCA7zxF&~&zQut0v^*p zY>+Q!y6Tatt1lUBz&GDmS~NOj_qh!IdbTt}y499^T`@aM(Q)iH;y29&(%P}VdQxs_ zyk2EXD03M9-TPBdCi5(CLR4QD3s;BY1nKx?sMff>GC)@n(?8S*GQA~lX7p^JBhesuD zbo{R$aZyeJCRzE7+t8AK$u{s@eE?!`lb2n5dM$rGSaxtywd14O@6 zrT_*gW!bP`m|-}1vGG|Dua$!iy@|MRpzPtVm=ckf&fPM~qv?0DJA z)o@KGE|{?+OVX()2qK0gura zV{<^kTYDWr@p2&k;(<%GEHI22nLQ;_qoH->=I5>)>sN-+pn(F}m?$qW1A#&S$)^op zhR-&uja91_C%IH^jdm0-SS-vHDG|i#WH&8&ze$$Ya!@0rUJ!)eISO;4Xhfx8UKPOn zelMp$?#m;=eSlUOCLed*|8@QShNwVETSB?D$Z6!jO}L- zpULpZ`Lm&>{M_hlmkPq6;4gm2F#H(l#Z|8MjRM;b#0RF?(<^S;qUfeC5;I*Gh`YO8 zr$me`zbGTJ;ZTrLe=n4G)w`I_OK8IT+`?%+wCkOm`ow2)eeG*00a&7UhYZpWJ(t!S z$AV);f0Rjqu$%}1>6_+fuE=EfNuyvVH>R!vc8G4Hb(vUox{pnzRHlZwK z?Lk@6Y!9Gb%Cy(C(VSfd`(VTxNUor04G^Xv8x&%)$s6QoF-oG#D=xoSKUPfrmi@@1 zfE4tLI%DMoF}r1E=9>UP^ZG@93(#bc_RwzT^3Zx6wC|%Y-nCCdoDAuj1E-RcuY+?iLg}A-j94mQBPb{ zE+DQts(_+*;Zn{?HRXM6tVLF)ey5QfGx&*doLeKL7*c(5}g`Xe)jSzdd0D44?s%K zI9{|V5aiK9PYu}k_uM^^MRS!)m*omFBOz8!)w&IeY9%}Bpx_8TwdJetnAjx?a>6I% z9swF0cH5NwV_B;}J^XCqnip|ij+L3V)Hw7Y_uK4&O5OanLehG{XNGs+tBqHz9RDvv&cEd>qtK*Y3w~n3qr=7t6fSAGD)0h?Np7?Q7&dDg+k78m>uAq z#HsS#{K{a&1Vx~O$4zJr2VC)|2O&GJoW%NbtDH;k>rcj%)#n^M65@SZk3g9V_8U4- zg;TG*xbJfw<*-9v4tV3A|Jh9AAmJWmT+pic3GB#IZ_4*0*CSz)% z{8Io@0JY7D|J0D0YmoBF(_3#gfLnw_=!bZ97GXT12j3xWQy(;O|D7bWI8_dEnt+g! zr3ZyA=&1v4=Cg@VPv#I?(1feSL9wMIJFm=E&Gn|;+q#A30R>YoB@yV47?#2Umw5LR z-T6cg(rv+QDr6VU=@28glPHXSzGWWd8z7lz8&Am(m1`kKRK9izFYNEGCO5<-b<4Qx zly)6t9UDlLam`;4P(N9u+7dR11iuIJB)1ML#njv@p~GCoVc5zX_9E5emQ|}|em*zz zz(4#NRsy9~BT*Tkcf#tRK17mv-tk;G9OSOgzXeG|J@Kn;?|}pa;k}5 z&ek5(Yd=vqF$Tl{Xph7%C2R(EtrrT?hK;tRfw&?8rxG|z5PE^)gfcDZWowy!IUNl2 zxIPd%*)ykwLunOPcqR`pcdL4k_o;Aol$LjYmH`w+X>UhS=R7PWojYNCdj1=gS=7@NsqDg*Ms|IGGVK9qGXP6D zeQ5+_7zCx&U;qhs7H0aph_>JIlS!b0r~8-%*v!D6aQaEsxJicMdVyBZ2Rc<%kN=K` zy$@?UfS(8!^~-O(=DdcOBI|qQpVY>Egzcgk*{`Ru2%MlGWeGAGJyh98;$#$~_&Ma9 z_w+qN{C-f3MzkEviQm)Ls$!@GFmfBd>(X5Pll>CqjQQt1RaTo>jiU{Nf<94+0_pXW zDajPGTd3%7JR(>4TvABlS?*KuqjLzqviyUItBXjxHAI2OV0?tOT60;!y~RV$rCuqf z8G6@=VC7)kdO=LvZ+mQoM3!>L!p8x{k3EJ&$WNokz@6WBKe;RKfhGtBeJdamYc@Yr zAH5#!YstKbXNTs^Y=`GeX8c{CzlQ$-Ry9gepxzVmhIPVlrX)@AJBFF&U$zTt;^jtm z9H6}DtVFbgO3@xK+#TJqw?`XgiI%f5nDc-a?fmM*^5wsuH^$1;jeh`=duuH@0@t__V1W}VrldbTm~O#;|&pJWMHMyn;~LMwtxO!@!G*5e~fBmf4`iN=a;rG zw_KxP7z33{R@ftX3moqyg8c6V3B%(DY34zUh&YLhRv>Gx==W z;aoaN8!mi3SF(u_6ayWJ^M&bk)7Ner>7iX+{eG*2P)sNaem_XbndC!h(?|&waKoEW zRcecva)Fy}>Mk!ib3EKS#_2Fl#uf67GcKc4) z=h@^MI~SjRUGzjG`2`V@`mR@v>ZA3qD*2J+$@Rw3=MNnxqT&prtv}3=*6n4$Q=B(v z7BSrj(AW*J^^BZP6KYd06De0cBO`7lh;7OyPzg;`sO27STxg!j#)U#x1Y61kN5$Z}X7>!vF zOFm|N$u6Qnb~`#5B{E}ykcmX*mY&_kF!r4ND5i33lJP0}1Zss;+c26kOKaWBtnz5S zMrVn5%6wU)skSP!(Cy56DNj=Z$=4()9K{Sbb={qpch+D^H$$8XBE%Uihe0(aw7@Lsdxyi#z6m!b57v=O@yt%e=ZA^Mh<9?)kB7qaSm_j4{CDV%q z%$Fn2v~A8>jJ40mz|)AHExdi2sg*f8f%iHM|3Jx$z)z6-`l4i{;GgFLF=_ZSn4GU; z{cfJ2IC6i;LM@P@gQF&oEt}YUyVt6b`mz5@SN{S1R(#Pup@e}BnvFg#p9bYRdJjPr z$X?J$GrCX>e(_lipGKgXG2c1Kj+T9H)rV|Kza%vG1>6&1PfQ7 zCcgGrb0%G$$}e>kc%(N?2ojuNRw2Xvx%TfJAqE919_g2aOnF7eA8J@&^J4Cr5q#j^ z1gHL8({D9T!~?Mr@>G|?_mS!muAXQ3E!*87R)OBJdj!p8FQMohw3$ayz$PoNkh zl&SZ(_)p;uOHwX^`Ft&v?hfQS5ezK&ve-KIUsfB##F{CX_ZT;Guq$w!U)BJEYJw_q zsQ+aQ)jGnNnxy`sOb}GXH&ISA2i8$y{IWor>?QnjDX*hQW0OMwfWh~|YATF@Y0 zc7hO03`zaLrEc;X)h|5-&~1P{xhN)JCW<8@Q4fv@A2P{qJRl)!T+-~Pu~@eE*c{Jl zZiSP66yR&C!}eU11ulND$QIJuXa?v#Iosp!TRH29`jedCG|*65b9){wjobpy9x@m3 z?~4Spo%o2%p32==Rw6V8MaGP(breF3k_s-DdFN>YMj5MzkLO(__I{rK6iESz0e|xK zuxHdxCpIck*#b7y2r&gA3(lV()RgBQT`n7HK0ejCTAyGuWzB>9n=?i3P6ZS-GifS@ zF1k^(j`$O(?Mu9lSQc9~@nQ5IJn}w;iNi99)kr?vtUAr=_as8YKO*%AS}^si%42H( zYP!sKWlV|7JAfPkeqKLHZ-B#&ZiNC}v@(y$17S?d;<@Fmb2Me9`KRC}@2G#x1#bhB zwQ1+sA;eIKh@F+_5W207hhN2*$dKd8A@}h-eB<+pr;g7v)wl1$rn{-PKlcxt%E4eks=LRl@Q(1R zjlT^vflECV#eD4prSn4-cW*X!!V8;0N*N_9#Ai})rSA6rMlB5{Cw`{9&$w@(x)YXM z#x?_?`JrLy#f$R0hN|{LOU!mSN5iuLmhhM)f~%MAP1{6DmA9|q=LR8+Vw##;`nc*L z51nKdjz;^ueg=^va-iOqD4uv3CvKU}?}2bi2Ux%9@snxFH}o8QBNjF#or@0e87q@# zOPHDq0?w8rlU+3$j=$vY{-yY*#QQ||y~0|*3FrSx#3>m(OsjcO4~_BUFzmY>+pXni z?rxFuewHYUVIp1v9@A3VeGkE3&-&=T{JTU5V+R6OW6%RhPI23y5eyh`W5&17ZrKIv zH&`*>}DTaqX% zabv^4;=y?2ltpI=waucVsI;|dQ&;!bCbeoF;`jxgSW!Bc?GTTEB##+UOxh;DQCFBV z@Yo=_rR!{PXbj%)EAz^Kh}K9ua5BP@(uqo z-DlCV0{Md+uNwkI3ttHNRf+2yAlC8Vl5Brg7`tfGNTuIms9%lw*ty?!oxgaxqa<(D zC+{f)cXDpAQroyb*N6rttB>H}tP!%tBCbZqBMMEwUY)DY8yzIQI&-Osr#C#-iJtSp zLEaBOQ|k{YRK+GFu0-@FC)J9f|D_Wq_sWTrE>ukfMU zd2EuLNiAWD3SetF$}Nm=BHpAidmyg(A$|5bPyJfl(AzG{5eNJG?&uu%XzVn8YT)Sk zG8$&G6h9FF4=nZ)YfB{MZQEWutS=44uDdJ~LO(o}U`Or_r&@FM0quFwvz{v+jZVS% zf-{I11qji>M0NMCXsiuqNH^HSB_5)^vouQUD`E=)5CYuZZB*>$Oa!r*RA^u2?&3j; z2FVdBFJemUYs3}B)co^avKa&?-kl7r&-9Q4;>c`g4C{A~(1Dk$Nu&>Q#s~L5YEy2H z))I%_>2RjB25B7TgMgQ+khkg|zrSwl5E2#LZGOXKA?&K&dPospu%>_w9f1MbpwH*` zNLMaO2}WR=D6pjIXGMl9XYDC}eHWv~|9P5c(76W}`0sZFb-~8ME_*j?r?xY1F^kbS z&Ju}Q=Lxo(h&Tr4_g3C+zBR4JF5Fd#SWE;xcr4pLFrtwLSn@1}-%iv41G zWvqhNcnNXHa`}8M^Cp=JbnP#0V{Tx5nN~|qjGjisLaq(YD05XIlkW+UlE{^z`9RCC z3y_u=x_uMs!@m{v}rC26J8@e7yG?xZ@J zxg3?H96_k7{UrMF>qOg-^dXjds6{5$XDjpvhp{xSsrmkRM^D82TXA>-+QS%r8)HhnuP zO;(c={YiuS@4C^N_~&j)-=3}Ciedpb!%3(@$FZ3ovG%TV#>c}R%VykU)O3qp6hDu% zJ$tsS^30gzqekY}&<>ks*1;;fwnGGwiopS*0v&1)$S2=7jRHpSPPANSKRRLgS;5X& zQIOJ}@|(->S;uhc4~5s&Cpv!CwQgr8JM8i;O*}M00Kg@$zVV??s;-Cw76*S2CTmT+ z{vyGA)Rf^%OO!G(e`5T|9=*DBI`s9Op31|{I5^pxQZP(Bi0WhJ5St{o*p5j;?B(5Q z&(^N`M8z4xZs~wR{Q6?1e=A|-%K#*GqT+K98N<_YZvdW4HA)bT)pscy;TL}(6>=`?Byv{3qnhXQ(kbFb071d}zd_IUM-*#VrV zDO0W`mCyaE7v~1iu!mtY#z|hfXd;w(k)fbRZZoAX2WEJX143XB9TaVKQhSmi%IsPy zAt-W}XxJClg>uC(AqlNP8RF8t-ArZniE0A%OZL(*8Ujp*jDg>WZ{G1|9cs1m%tsnI zR3oTLES6JR;vpS&Jo^FK{ogTrkq~_?@9P)2u`PmvjgPT(bzeZ)U@GkN8Q+Qeu;A@+ zP-IQ~)nz{P8UnpASfqQ$(QZoJjR~&McPR-gcRk>k&B8)Cx+{0RnN$Fr68!cb~Tzw&(SWo#^BTV!bAK z6RGjICA7iVLZiiWbILLzf;^!U6$bLL76R!PN(@A%c~)P!Lt>Y-=a zQJ7rZDHjwN_s*1F+&jB?xY|;ZSLN<17&!4foVWIk-7O+pG91u*7*rNMS1pREre_aS6iehMAT$uo+CKL&gB1*&u)BaF% z*%z%clLZ2ucHtCF^1`az7%g|qWk8qXS=m&=__+8k$wA))(><#VP zrPZKwasstE&X90#tFGOd66x635~km9#eENisO9qHS>{>9sD2=1M`YSMS39_KOGr&; zs@otYx061EhD|=2s=SVi*!KW$=mDh(5>=x}24G@96+G?DojH^emk=;57UuhEw(CB| zSLYgk;jy*1-;Um)*Ag~{&e`+r9!O~S5rce(^wI-)91IRWC%8>Z1hWuR*Y0^J#MhSR zz5W=og)%i91$A>+t47MN+vV}&?l@`Ug3?9)wVIVNE|LTYt6P&t>^R3 z1sC=4G9)6iS}#^mC%cxf!z<^Uy?G?Q0D3A1i4Bt{T5YsDk7h7qa5pfZOjXq5_!#OP zHoXq1nXn^C522eV0g#y*S)_~1-y3>5c=PW9G2u-YmLcB(c1TKTc@w$5 z`(Va|?a?Tn=m1LC$wsFoh3#Lx1$OsM zLNUY#?^&wUwBcLOoYf}7O&W6jj8E|r8itJ*u?N>^?g&$*g_eCHy^3~-R1EGciS`+- zX87P9WND7apYZ7k6C~Q4W;H2BEB=r9Go3%K4MumZK!HstC^q_b99k<<)gMVr4jdp`ARJNS2utfDyWp&E> z9e!kPyV6zgrrfT)K$ic-wy;(3RQxMRqZ>AVe%$d=M`w5sZ5}(3u|BVLziC8Sk0bW? zqtV9?U7}@0grG}B`PbcxApNPt6?<4BbQ{4c?Ahp;@sym-+;9C|qDFWFU7(ME{{EaK z@ot~^lZys^1hZHljiR#F&I23o^>8EQE!3odslZL;Oe;Lz8H5=Tn+!N0aws-QnJ6K~ z<7E)o6P%Ajjm_CJGtNd?C0;Vs4q_vGH$s*Jh-!|UBN;$!`9+5SpOrUB?<3ZFOBOoiz z()JqI5}CC<<=N1Ug{CP4agn~6TfBKm;9HiTPFPUIt|>H~^uOrcv2eq_s?7F8HW3mI z9PLlh27wr2){Sjzj_|6RJ(`**S|cGH5k#HvO=UXirbV5%?|yK9L%{uhjM|)0*DY{8 zh?d0;zjEsyPBumU#K$bMjBSJO7cST;lva29gCB}Hr$A1;u&HQiN8{or@0R@*>chKB zqjqR%Cfua(If2k=0*nCkHa{3mtO#H&tTI*zEcCeP5B?CqkNmo#P;mWV;pd!Md1`HM z@)SK^{Pv}z%Ot_Oedt1_iu9XTpPA9;-AaomDc=uokkws(8zFs55Bs?b@q`8Tohj81 zDI#ZqJ!V5pwj*&vg~54=a7)TRJY3K`MZRhB3*)kik+^|Ajop8MOww8v;2>wBj(*3} zG?MP0ik>m!+C#o@e65h))>^a@FNV%*D?hKuw1#9zm{^(sL5)(X9Cz{Mt9xkrX0&we zxGrw0+IVablhca50UCjb`)MY_wwkV4Ttqx(7kGpvWcrSu&R`uT%_e!#PSNnz?k8n& zwutj22IQHo5O`v#w~l~YL+Y;Or+lY}bl?q%-{&*y>!?ECG?pc9HaZ&My{tn1t>|_$W@<>I~Zx`0EzG4Q&l=&yI zt9?YgW>-6_89XWpBV+96*_}G>X+QRbno4B^SragbO>LVyuemZ1ORPB-P~`3-{g2XPL@XOP=*ox*B?c zL>_TA#?2k!m0;bds5u{GBeF&#le39!xG>l(NPN&vT2W#8nfAbsq6p*<`|r+vxcwTF zIswl$Fd!f!GgD1X4Um8Z1>7g09RDstZj`X=ZlS}4IZLlp(l?avf51$3gbiWVfct2; z6&)w-0i??)j;@ZU^5EBF^q#l<4hlhGk;CJh^X|oqysh(-yaP((_X)SMk?Y6{HVaQW zcnXzOXXQc2Q_Y@jK4dQS7sRuR72*=&!0a9g@oE#Ta~ZeVPR>}$&mifff&mEp?H7Yp8P;ZJpF*JqR+w2M<47SRNC^55`*$^iM z^6QIcVv)usonBp{Gil~G=i}E$#JNMCQCDnmlU;P+b3<>|dfMnZ_^O1U@%lz)uKuqx zMze~WJFA+9iS$3jy&2Q3v&1}%JC3o;rL$1hdz#b+KL{C>Pcmal$;hm&tSqpr(0#w) z!SRPHI6^q_Om$)JV)2{zg#CTQxxyI9{hopp#4ldWcho4a(s>H0Vazr55>Gp|cYfy2 z^`w8S2C?@faj0W>!BQ!>NI1+A$8XmRg4({pzqv3EyF!5o)2b4DV$E^w*^32#<#2<+cz4l`CcC<#@Qb zyH3Sr2FWn99y!QqliXYR(h=s$8|}Ml39b3 zF!s#=mW_>m99YuO2Q%LjcB~QgER^n%WkFogXiA~7va-E{19=67j{mhR*UQyvw>JVc zC_k^>g|HSzqibwTE_dE{T^50aD-LBvppS(1Zt8gqAew>K_*G;E296N9uZ8( z*Uy?C`cUyAM2SXrJ_#Wc;tiB5$UDc_0>-_~BG>oVxKE<4LQd<^WupD~$}8K)%hiO} z!3lEjr=t~T^R?DtLVUT$0G^Kd=aJ8*>!VXIZql8FepznPt>~!O9cOAT8cu}&@iaZU zhq61oxN*B#GcB0rsu@u%L*$u!5#)U2h$5^EEKy51fgye=^Bc$$pqUvqueO2_&K+c* z^&Z@*Yjfh*G*G?Kk22N7uVRzCeH_UA`@7w)XHVHz<5SnC(C?@$*xd1Fbt2~1Xj<}r z6#N;1K4<%ea9xbywMPB*LBWw$Lad4~$O9f-8juW86AB?Tk@vWXC7kQ;r}jh@%Y89E z9w}1n>BOgR`CTRHfJYMoHT{>zu2Os{m4 zrQn{s`9!E_F*yw-t9MK8&E9( z(QkD}8HWsUOQ~FkS6+q0KW0ir3PPZMfh?1P((|jvqUL6WX{v$=rA~!xVB8HK4|!`L zuZ$t&ZL**1ykAE%SPrqCuv=fVDYpwWXjT&bIaWLBCziUyH7(%Kn^)p{in#-CdZjDH zIM@2Jh!-U6r1nO%w%xdMBiw4RB@nASj)%w8w&?_u%X#AvJ5=V>9)~JhNwWSDuZZ;yy|j54EO|d~NhYF=BO! zv0eQ2if;%qr9tjPcYNbVh5F^Q^MrYC2E28Jmimhvopqw+v$lhesOPDkj7$b#D^?U0(rAFi-S1IUcr=(DBe$2%tCwiP;yRW)D}jIJ8#8OsnokUe2m*KEAhrZ#PgNA8#_yN%o8V~(icc7lvZmAPiu&$*CFq!6f4bB@)1S3I zM#5(EMCYEvy?d&Tw#}6H|}U1MmR|bII3LJ`wnSTBuPW&|FOMUm4sXnik(k< z?m;Y3{$)Y(aaybC!3bkOr1R>Zrd_?UO4ino_Zm^d^fQ%W4y_aQd1G^`V_L-tDq7Y; zGPg!lZLLC-M7BcY%_Nv#{XXBn{AUMSUpi@p%hTPU4mgR+(ReBrgf;vY595!414sXv)dIK5aI@p;~dD6ed)wBA#oh zhWBi!Zxl?c78<2$pasY$RoxC=q7E(!t{@R-eDI^>ws2|$Buc~$Nf?_)RpA>me=d)k zRVK>9Tig5_(u}O9e+MP3?^LoSZPQIl^Ahw3EkCerJj^-&uoqHsn#g9=z4NMd9B%6{ zzWHar%icevxXnEND365ZWCCc;LYJD88Dr+t;gOlAVlq^@MD{=g) z)W}z|*nKU9ePKZ$Y^rfC5|w93x?1kpdp_oOreY#i zKM6u7=y61Ty)k%4fnRd6cK2;Ka6%Wlu_DGZnCPpYqZ{q5Px70Q6 zNAIu98*fjRkZwGZ*}k2yv*uRK+Z-$`_Mc11^Y!k`_Iz{oIal$wTm!k_)J!|9$(L3< z==qQI3KDFhDK7%ys>*Z~mX>PlVewQK{jwyw>6dqOdA8Gh*E71YY^2$7tvYL(O;0ws zS4sHC-3t@C`=crg9~82ml*nc`2`>+%NO+(5P+#PVmpl*(7bP&{CXVOB=XoS}NXUC0 zN%HbxnhA6O@7Wrd`r-Z?AG?O^EJpbn8X9+eE)Lg5wxWeM==y_)9#$!(HmhC@&R6U+ zH|`6GNzHIVFPLRYrM=V8U38kA&nZj_8O!RyI2%k%@Qo#$wJe-}j#`K+e{&#?3M8%~ zanQu>fft9$J%21}*3pq@oqOKQ2@FU;|2QpUJ3lyChPCy^MK14vs8lG$Ji~E|~<)QsC*J$bXdvwoX{_WiteZJz3(|=7a)MBSZ zr_lHN=Ym&PLdv*Oz0Wi@HlkuSOrGj4d{xVvDeL&v9;UE9;4i#C|L3y${O|6jbC0zy zvZhkaRn+7USt>-+4h1Th!z(hU9t#mf1a=Zc6`buTY{-YRwsN7U1IPn4*1vvCQd(HT z=&3+`pR;p|fx)Vt_u=HlnM@XAT(zK^T~-d`&=;$&GL!o&<#;Cz6@Tw(t6JPu@yave z)i--M#)V*#Uk0Rt4u%1s1wfup+qiCB)Qo`}?ZB30* zPM$MAUReAnvUwivdS+{ibZXBM&o@(f(I!QbH*VM@#Ct%&RSe{*%>(y&0`c^&xw8{R0Zxsa|cFOb#d) zj*OCD3<&594Ut;+y&x^Ke(o}6Ax`Uy-NPc+l|JPSLYqpxab=Mj7bEKLQX()p?%_Q5 zKnE1!e|f$Cy5J+?*fPp$wzJkSa1nqYarNVLgw$(xi8Xun)V9-dlc24=l)G3y`%($6 zbxs>I=AY9B6KwSS>UkSkRM+tSATib1A*P9bEAK`R=Llz`TAO|m; z*g;u{oZoe)Bg>K~Xk&Th-dcj-hZ#zVC`#999o3-Wky62V<(j%D9+3HFAhG_ULH^t4 zHhd?)ackK`dqNzxATQ-j6X#ojmOluH8;Ap4J?+)~r_~15Jb3(BKdx2N{;!%ul5VF& zoA2!6c;0)nh*u{1lIFqNyUl^f_0U2W3rs6q#EG1jSsYK|c3KQPyW+wzJN3m2oM}I@ zY`=xK7?`4>d4b|zs=mEkk zD3s$fH`K$A9;>M1A?snYp<%!V!6zd!OS1w1{^3sF zKYk61`zrVib`SwA6M1(VV4ckk_btd2}oV~Q1TApL-$Le zl5nb}`=j(_R@y)Pfw!pDxy2G|0$#a0m1k+m{X$qfYk7s4&1U50F_h209vyMb{#&QU zEQ$F%DS{E)@HG44%kfX=gLZLc-(j$V{oI2dS%2dpiu^OWAUP<;K(xka)c+JtG~eHL zgC2EaG)1-t9L;hTv-)SZV-}7i2kze6fF&Wu3jz=ka(4=XhptM;doL^D{?k{veoczx z&R5Pl6K2IJ#*K{n&62F|yZeh2%Q>$5HqQHrY)hwC?- z#gRrnqOxmQqqmTpxkDQ!V@GS6W)t z9N=DH*lZu@@XVQv4O#(gX%yHN8(SjDI^Rjc$q}MB^eYZ-!o<|?0LziQz4Saq`uVxe zRxFN1Bl|pusY|Pbc(^!4Oi8cgMbtp~{t|RU-vqi?u_uHt^C?b;L{O zAdzQ1>rN$xJHpvC{e}+m`d>cDlI4`d5 zYO8|A*UE`Ltf~^5I%#!3H5qxIx%)T=*W&(uE!DLR+}!~ZaZA>B&yHS;us}f_ z<8l@kv8Hm2NLP>Lc+bT4w}nG?koL)c?f%L!Kop|X>j`;wqDY}brs?-1l*}C(!~k}- zM?)~<15ll|2{D0+z<@vq7&JZm3srV4N!w;(PTS~BrN@AHfXxz1zcPytyX;|q?z3u? z3n%y^Spz@V1X}v#{E=lIMnNA37+(7lRQt#o@DOmgPO> zDULoo=zA_xD5$Xa-Ysz;DO^#}7?d;_(N0C-(E~FYcgNK~_ zcow@iP9Dz0W#r4r*RAh6iYLzTcb2fBO>FW3<O$`rqy}59y5v02D}>2Nw9e_$uf?kbkd<+r4FCqqn^?m1P^Elp1z`(VGH(WxGhaO_FoynmMKC80 z9^-%F)6MyjDlgjOmZQi&jQ)Fz1#3{+#b589e_6REvH6Wk$8Q zSGX2WM0BEHss)f0d$!M#v4hFLC87SqDT1gVfDyWr-a3Aa%A0tt?<98;%`GS1!aNv4 zTGcksRs5^7Aw}3+f-ua`0I(l`$>dM{gLZM0Mu}HoViTVtEw`zyVH;Vt&42Y!k9%ye zd|x6z_)~HEkPtTv{-aeaKh|%!MLj3?U3W=;@vx_ZJ?ib)&-46WW5q)^PLDGN?qx#c z_~glVPG!A1QGw4^Fn#~l=wx|+&khYyL0TVe%9($j&Hz)|g7z>PurID-^>`k&ehI*@0ZVZXSIC`#A0KfyJ^z){Bt>!Vy!R^q^ zW=UWJ$Sdr`|KsZ~OG=cM z?k?$Wp26$dd*Ao-KEL-H-#Gq9%&eJNYn?!WbN@z|OpEqLOcr0r%+1T><$C=e7y&6e z4DOIrJeysq12Tn7+ESo~%G|TX4C;_J|0(-EV1L&ZGfW7os>eGvuCgm!rcxF;Ik>L; zoZod``iQQ2ORh*$dsOT%{G2VEmSp<>$rSP~EVCp0K=!NcmzYTAc?S%4+_Yk5%ui^w zowuaD7EXHi6#?$td_Q*DV619D0i@Z*oRY+|6!N@ZcY!YeqWXX-tCK~nKfv5`Y%6&P zxj;TH6<`^F5$&UQHWcOGtMfvDna3P5&Ab!ZH{gAAT|1>phy}JnuB0TAJL1iY#pT?U z*8Kc>l9rkNCCbXyb$Zal(Bk-Cv~5(~F^&-4oytK0G)RA-8NPZ4_=NJz)0>BX0*ZTY zLJYX&7=xR9tDSjSF-sQ+yxKH@G;J9d9%d%%Jmw9x-7_0Kp^f7Y9VN@h4~WFs-dxl@NPIm1V=$r|L!kcu0Lv*qJ{V%^0I#*$)J`&Fp5N*Y2{XXKhcrptM~UBX z)%9;?H#+%i>AfTQiahqp?5&X3E6X*7Ja`A;RSQ?#J-Y(UAl|tjWAW=)c#ZQdya8Z; zx!>(ohgqQXXBd4p6fY5sqjG9SZ4r*v@=jT_+1uhUgi2=4k+)pOWHN`+Z;) ztHvfvL6@tYqPlA{gY=1q#Wg9$T}nYVlZH9A60NMK*#AXN_>Ni5{Nop|GTF}ZTuC4kOAEGT>sZiWuADTbAS}XPCnAUSw)!K z&<-IpZ_f}4aKldGqCSqrIh&4myAMa@1*p>&Ay%bOiO7%-{IF3<%;x8HtLuf)HXJ3e zjHR_c#$N*^o|P4F>j0J~6<0g~#wv-Wboafgj)B9Ak1LGE>I@aTjuBLh^W(Cps{V(K z|G~3=i3I;vO7fdc_a5PZe&L!F@5LsKeHt(yXo7fpgP9#ke*W;+Zt-@5J0)uD^MM}` zudBW|o@xPs{#qe$80~%2%=>N(2yCL8ck}(l34o<0hJ+6pU2O58M2!(W<1hD3!urk9 z`KUd>>^A|PZAy{3QvL;aJaa2+1NT7UQvYNJfxFkcf94n%ToB;ru_sKA(ktNJkQq^` zApiH?^qVKS&ho91mwvi8F0k;W^tNr7IEEmNi@^9=Vy$dRstOK#cggDXwcIQWC~q5n z6KL-z8%ElHu)3~u{YdbEYucxIW7wD*IK@8XT81nXdag~1JtJDl^@DNLSFzS6M}r`e z$Plvn%v6g(kJEt`D)FN1VL)!SheA9+FCfo=h)%luj;|oTR2EkdJP!Kv2w&obWSm>ugHEkBB}(ouW-^Lj@2yqeDhMoJ!A7*JefPb zNS?+9{qsQe_!Im#Amo8%VT9=+N6(Z-aR4oTg1E>lJn}E;^!PGyF-bd(;gG2T?zES?wL>9Cw`{?aK7Fpm+@Jf7`v%GQOUBDA&HH|%tWGmW2 z1TQ9a-l80#ZhJsEbQ8ZaG6fzd(V0lrWN|PgGGLH(q^Vj2TSJFY(BsYe)F0)gZXnsL zpaf8$+{R2n3;mhV{4l^7#1rB*UDzs)2pP|_J%BS3b1)!M?Vl)I+UoW*a2Fad^ElJx zSGI3OB=^ofd4H>CZU0Gad8rP?%xTw1;>n1(w3^@603ye9FkpSSZtU<54of3RT*xU?xX>eY#B) zETNF2B)8O~sI;13w_-zHbGi@qF5ft45HlQrAXq8%_=V|{Gtd)$MP89SPZ@_#Hp47U zniErfzKn;Kx2KzVHQosl_GYu)Ui?BKBrirB3q?(4K#x@IUO<<>YcnW!^V?$Y+C48#VDW6r3= zlSrFU`LY6xf}1NwVt7w=p|;c1)g|Hb|J-#ZvswW%&LvB;;^^ zU${7c(m;BDoicp;A?L)P7>Jt%-B2n9}<&%w+r*1i0dS!p!kk*%w z{A;B>Q*k?iL#l>f2?Xn_?3~k2Z*gY_($8Z&jA8^vr|LC3{PeZStfCcyG{G}DcV6*lG<>#?Q^UK9QDV+YE{sPWVCWDa zj07~Oj^!>HkJ3%9?nOV^Y{jL~GaZ~`mT|YAzjM<}pdsRS*SFv)Em#4Nvidu^F3bVR zaQx`O>5BO^^Y2k%n?oulR%wQ+Lmx}|>dW@jv&!};i|L);l!(1R+)m z9ppXIOF@H{W*;xpS=Yquaf4Gh_Z`2xD4pYX0PUCisEXJIe5=P5z|`bj1uz3tKA>b_ObA0CtJ5BC$odK}tv}mjs#Du;=;LZg&*0swKEDgX zp@lh!mn0_{LO0A-kEkQJLZc`KRTAspZ;fiHm{a~Y5^{`` zz<~q!1qL!`6P#Li3M77dbKmh2=y>UvoksQ$eHL0!(1WCR*|}FT1o(4ro1nfS39Z(G zVC9crQY}{>wC=kStxsQ5Z`0Zq2`a7N5`q9CtKusFRS=p(yW#k?@r#QT&x=3d9<`-3 zU!VYSc8K@OBdvF6H%#$C@L((b_n`Po2ab2>QLp8TzL3nf~R9U!x=;TbQzx({**g^W2$Kce)x6&T4;kNfjxB8 ziFg=^bDuES-&x5-4;MWP*2-gJ@_8A%y^jW!>9(LT+ z`?w~Ql6LZi6L{9uII1ZNyHRUGjQHYf@ABSQpGqE(G*AM=n$jj9=P7>jTjN2ICY^in zZw#CZS(=VES)k0g-~69iiHP5jo?fr+!kIOYPWz%;X+xPw!o|^Q&g(iUTj8wmBV%bA z@^9c9H(pDNtz-P<9N}26HHFA4zJT7`8}E(PX`uARLIki@N(A{C2jP{%lrV0m&HxGU z`@z7$aVxsPbjU=-6H5Ie3Zx z#7ZrX#bq;!O7C7ICNE#Y&#GWTAHEjd{_ImUwaDY%{^*=v6a3*(n)_Yle|nyMzCVHu zloP~$%^{8X8WU0D2EMp9wwSsh97VBruY_=QN6iSSuoQ1mi~04X7b(XJP)68_0~wrK z`V>^jG|(7kKvQwNKmHwSSoTAD?IJPLV~Z43&kfXwuyci}YGZ{3vYgQhO$3Dd!M>@x z>&xaVODinWNxuz@Kg~An*Te&3^w_;~anX)2tHS(iFp;@5Z$FRX@z}84SCA>t6!v^T zOTSEVZTHM<*i>~OzEjqUIgOS~{vS9}nzH&_on92b`nP)ueezRd^(7U%)4a-6-md7$ zS42kJ35G~OtvtxefGT+gr7KKl5%;eotCXszyJvQ)pB#)2 zNy$Pdg1z5wz*NV$pCg8ayTHaNNF@Tm6!dOfAIxz2e5K597&b0lWS)@yR#DrA^n+hPKs2;%c(5TB2XrY=T*9tXK(9vzMFa2l2U7S> z#d{(O(GQ~U#_eyG9RP|TKH5mFP=h{PC;WVzqk_|dhjUgUQCh4a|GGy{ByU`y!T14x`Ir5^kHq*4|7Z`);MIJp#$%0&yv z5C`xzXIL;JH?KV>c^~#q*MKMiUP9SsZbU(VDe3)ttAW8USI*d|C3rz>j;(6~#GK_UqkzOa$x(LDMo630j-)+Y{9#nM6c8Ym59YrjI=h@v21_)!MDdey#o3?JyT8PQZr!BEA{p<`9%RM*&po#lX1twROALf&gy$(n2LJY9 zyGC9wVdb+i!AB(Fa-bUb(vLKl>|>3VQMW}Kd=(ICxr7BEk$t*Z?xl{X0o^xe&T`wXa)&ja1k0IBhF zkQtQ+U611eU*kLbx&*6&_H#+Nz58z61zxqqwN=UuR*>){voe6=#d2$h09vlkwUoMQJM-*fwrj1#Y>8O;lOJ@IBZi&G$!kl9xH5Tt4l{Si$6uBKR|0mA? zW&mp`lP~3n{|;Sksi2|!*Egy0-O3Z--t%cF*{q;%YPGfz}_37u`#t?zJ z7ew#dBn?e~exS~T=LU@9hi(fD7vxcJA)x6Oa7hHULS&T1E1Q*IoF=r*ous6j#-}IUhscaR@Fk&f~3}VjDBd1dRA0 zB-m5sTQFK;1W(#@0jLWf-OM6>ki=aW^s4#j4?>wTGL#4oXL?S0wG0Ap(Hn|UMBF=c zOeP;BH_+EoW7XeDCX7cRm7dj3)-&YjmnZ*ctuQmo9APH8UMo`qYkPkJ%nHD)4VZNH z%xb$yFK(oRP8bH)&4sxTI+AZf6A?!aiD767BTS^_Ef9FH^mG>%Fn9Rg zZR&XqmjQi7QGQv)#ivkU9#q#^Jp(f$er)6;4!UH|L6fC>>OE;A0VWvQDGW&$vtJZa zww8FiMl#R5p(_Q7pcGzYSg|^o^+?v}L1QK$<=4v+slU_Tm7CDyuI3ZEk$qFe_FA?9 zo&Wt)E2fT^qv$VR4e+ zTLgM(Tg$e;BBag)EBG!T0(>(t|NXwp1hf~vxvX9bwV-zVTHp}pUMYO!1`Xi)-$4q| z1)PLYAbUNQoHG6GCJahkc#b@dVhHjtVYaZ%*l?QC`m&_p?`jP{WQVn{@sX%o3^4$O z5YRTb9Dpm5<&DwG^Ka>(TN_4Nn9VZ)sstAhM(DtIt5*B0g`$2#zyuY3D3oCm>M|4V z56@!qeq!u^*u1ZOP6bw)Oe|gfMfbEt%pnj4lu#G9k<|iNdN{YUb8+db_?7@XUqJeB zjSdUcfJT=wS-O+>tq<}#esf^Xe@NsbhWUMR=!VX0Xzq&F881Tqxi$*%w3j=eq8|VL7`PUoWd|#W zxx?RkaaA|4Qem(SrR7eYf&`!%5QThuTVO69GAb%Pv(E`hz!UmV~l zKtpH+!N8d3GDJ(wTn5zR5NqMhLAwq1q;a9Z`$HQ(m~%iWi1%GAcH{YV$6kaKOnhXl zA>xWYw>AJDkmdb^$mQFfq${4_H^6bRH1-^9F@O#f8&w)}7d!bDZm0(Nmw5M3(vveM z5R<`N=gFmoIvBfrG$3E(Md6B+pFx!thu2>Vc{iF9?s|Ep@%(a9HtQii-$o zzxk+dA-~V{l1&X>oOna`boI>mO|J!NaZ(NRg6~Q@uYpMD+Pws^7YQ2B5T_unf}5Nr znQ_Y+-`HY}2o!aoD^y=69n4hLln;SwnB*A@-{E4^$-kg=2~jhc)C-cT*a2UkzzJPw zZ;lT=sD&8{xC(@t6N6jC_u&Ml{aYW}n~lW!pYB0>`FfGsVzFdG|7q{Xs^iIYkaL1$=h}vlIizU8gx>m-&@P=dsE6!j8Ctn&3T{;7={Q78jJn z$jA$b9spF9fIKkCca8Nx(HKv;Ql^4bgH#`YllS5UZ^d0aj;ogr}cZr!X}I{hvC z$9x{_u3mzs zuNy<(Z}8kQN|2G3+dBM%{#kbhr8>-V!MwJE3{Z_Ad~pn(KhIZhgi?f`8oz|^fRxXd zk#~)+MS2%=xbP7$Ym!cSQ`ne-MFoC<4OT69r2u;b0YT!!_j;)Q+Y1R7cpo14I)YEq zp-lyt)PM=&m@TQnq}{!rceL%*d=|@NP=8`coX;xK9te%Sl%xGOU_nZQF&7*wNh(iT zcGxn%mJWh&( z$AA$_F3|L2$*4FA_*g=h3M>HuCL)++F;&ppR;8PNaSpz2IF(TKnnQ^S(l+Q~+mIRK zS1r0uG{u31hN=VUGEA)i+(1h2BSRIyOnv~t0bo7gK{kI9qg?dAo5>G}X52Ojypb}W zzc#?f5P|X>g_xY?#Eg1Tyx|ubSYZq!#nLSn`+y>Izrfd!o&JScKo3>T!15Dmp({}J4xzbm+XV(*uy{ENVx zrO9K~fjPuih9UMqH9!nqFa|>Lq%rQdE=j5p zv8bU}7Ou|=foVwJH=2|0C9p~0YgW&Fr)Z5Mmi0{@Tngy`CHkMPE1CkDArP{^psiL` zp~0d60>M#UvunUF3xr%X9xBRa6p67KjG?pQ7 z-e&8UfBerLf3iKa0`v=mLmnF2HgIQv!R`0L{3a~hOb&YN3?bO!d)J~$M*jCEh*BST z+`UYG1kN8_w7?S+sk*va17r5T#IffodN7S_?;>9h?-@27Gsvrdik@0`ITuif4EI z0?5cvJ&J(Uyt#`M7>R&8=Rau{JZ9sYckyAK#hddPzN?j=#YFil#QJRYDZn7>y()lO zLIrR6q9u95C6iv5aRNZ#G;~cDNB(ECXMmF9^@`;ya&(A3uMQZA08!)a$vZ3f=v&qn z2Q2)3b-XYn_`l#MnQ6^B(AumvwL)VT{6!89m0()w1EUaVU*krcW+?@26|@f2cG?{a zQw(2HxGW=1w)B;0g$sCrlG6J%`tAOgFDVi6c-k~s>b$X2j$W^%cq1VGb}`H(9W6HP zs5_dns<3LRn^U*Eb9I;Y^s};f=rHGgn9xoTf^0X%4PtG@QJuBkiB4E}; zJ{aWGH=7xv>7vfJuq3W$0N+A&gzSjw-CVvSY1=V3{dK&3mIVjS?ZiXXbqxm_wf8d) z_STN%`12fw4>utt^*XU3tH1sbHF}T~*Jky-{^7%rmq9#^lb3l;@6{uOx$iDk`6Rz; z&_$M#(NIn>TPCgE`Mi-;a+4qHMiiO2%euVWP1Q-0=+j)Hr47*(FCO^sh*;emgQz7k z-)1t9lQC`_JszP~BtL2+H#-N!=P zYxCICObhk={U^%=v*XV%>vRAJL*!e3wAR&Qjw$&ab^hN>%knUHFQ z^P?MYiwqJ^QH*QP1D8U7^NDX4=TV-met68Wgg$ND14FZAh{!MNX>X}m;U7V~Um;)N z3AY~qdH7rTEA?B0@w1Qd-%n9&^>8LNy_q%-HM#FLCNNeI7I<}>WKl>mb)#!$ zk@K53e?84$eOO6!zcui^b{-DhudzNtL&WdCzH{5&EwA+5_YPH$67~D6^0Q`#R+_m> z%-m+lvA*24S%1AypH~U}M8T-+!mr}BhQCa=^tTQ3H=O8xj!7t!=V8tQJ`08bI9+JeJ>Q&qC$k=}`239Y@ zgUtmu_oI)`*zE~?S_T#5;rbjiKWY4vyv$>4_TA~V9tj48&HnBn^Dw$A6_v-;xKXd{ zl#9;A(uUaZ=-R}xBfp@?=eG0_cOH!EHE&BsVE(ga&rBcI_Dy(|sP{*SO#*&`U34hF z6%MoJ!$eG}dL3%9GAe$3X0T)zw>QP^W;u4iSf z+w4pSbG!x`)j90f>(=Du^r4kOEmXB<-PUmY)+@kvkXUe3I_*fd&xgtNV0z)t0GUU2 zQTB=Zo=3&XlOdyRHd__+3o5M&=0Pe`LkJ!>1YSQt=!l_X{pWrlU={x+=bgP?>k#pu zM|o<#UxSV}kklL1&x!6i9{xZ)LRwpPvSe(?6KZ9*cgM-c_O?3^p|nCME?8Roo(i6)fz2%+DKx}>&Lyf&!{6f^yTNQmKHu0Ln7-i2* zGsW@r(=?l2VOWxs?mKC6Y$DqtuqEJj#qeW+I}d-V+_bchIg7KiPoN7Tr<|&a)^CeU zCR4mD8bhiuvp<2N{pLDDF%_hX+Z*3M9f%sTsD*|5C?db?J5CQ|bnJ(%ySt$SM=fwiH!WycCiBKP)*;REVt&R9uIM z``@ciZP|(ZEQnNW2P#f21N5SHgdT-1J~`$d7?@K)M8PVvtNPkB%gZ$4&NaT4mb3Cc zQEy&O;{d4;l>-?sll1Q49MnAUYZ!9y+Do>Axpa+|I11W*k^cV4Pn8{k6$u?5? z9gowL*OTAHZ-{%SK5?zcp7rVeC`D*^DSh`gna5CzK^v2M1)8DpEVqNlcjVVHO0{1f z3;up1E+4LTRdpR5JRc9>fAKMU_JNKJ)~{mEdTY{_XPR1m1c4}xP&V;%m}B1nJku$c zU>vE})#l1EVSb88y3%2>k5@R+j*xPF8zm$7uHO^UMsf^JEY+Mk3~n3@f}Yx==Dgx| z(0a*Qj{VO5CcM0~;|@6vPv0!mA;q`L)i*`RYBza|3!G|XfX^lx5x@~5r{~P1PLTXj z(kp8CGuhwJHI9oeM={3hTGP9KK)JNhezV{S`dM~%WOYC;W+Ewx&2Ej9<-N+gSO_zi zkB}Pj5KXC*%?J2@58V1^MG!(yIwyi%5GMr-5?D{@rZcyK*5ZY01-S)(D{kemxY52) zbNVt#WMg~y5Hb5?^w1qblofGxKO8Vqv!cjmP3-(#&vQow&$n|uvEF7+KezxGEsbc4 z+ls#d7dp0#SpTrC$2@I#(aCrA3xa~&3I&1POm(wEAmo@2Z^?Sf4+fiD81Y+7`pYHj zA8aDa2dEgt#=ak=SK3ZZc#?){Isc_QwZ1!AYnExnNGb8N7tsnP@-tkf=C|btM+#*`cmhWl45G)w#FLWyYBY+S%_}dK$85D zS|5{%^3QF1;JAV27#ZK4n%Nz_g$tHL()fg-L@Rh1Ryp<>olSL~BrmIU%&rbx)s$9p zoYZ5rX35JB^5I8!P80i}6tjv2@6~?5vv5GmWUHr9FO3N4RTAC>k;jD7!~zkeY0W8f{E7GI&_3NsO@7ikLZTM!NY?hmyv60U`66hCu5J;& zk;TnM$xV+_J%3SNe*xkvMeXU6SibEk(m(tg6_AP`pl@?LDwidR&^{YAoq#G%kX9k) zI%}sR(Qw~rw6)RUFtH^tljm|HZ}XG> z+zPJ&#dTIp{8Z-R1DR>qgnDC0p{Bc$LmZ!^$VPgaCOjmaYn$fB^iXs=XqkQ#hTZcG@EXkz0y^QP^4GC?t^6`L^lH1u)cAsdRZgqCMJr-}UUI*qh@V z8Q~H9+K=qcGyC&}Lv>mFqi$7C_z(-5sQRT6>gddxVMBYXWvZ$EW<>c2=V3a{4z26e zF{}oC_eBBx=Vq|wh2_h_hgG3JembX~oWT-RU8>iVS6|H2&U#;an6{lF(x3cxqGQaj zx!^-DeHld=z02*HMei zTf=&d3D&6<*Ham+jC$if9bzC(##BXfo!~1iCcD1c8QOdc`u)J5lfClsl`_Ju(7pId z&h8Z&Zn)x!lG@T5mVHX2HjiA$@8#kZNu|CvS59o+ zCoZ7bG0XUSp1|ugq!5KU2Toza@V)|0G4`zB&%Vf-HczrTExz z;J{Qr|2I*U93{tJzt7cbJ-bbtg~G>7F3y7!fYdp%F{Z6jXxPwT-7jxQ-Td^)6g<_P zr(e57)rDK2ofDCLzh1F^rugGdQKQlKL=vY?n<+fnRZLBp7TC|P*aDSwbj{0ttB)pk z|FC7y2H0V!`PnwOosmjMmnx5jc**=(iT%8KaB7{3NSo8e1EC&q#6awfi4wg?u3?q? zDQ$JjWan@XZ2|g7-IcbKA^KEO@bPVuS-A?v+}F4LPhOAh`qTHa`-lqm+;*^63eic1 zkAfz6sN)u$Sx0_3@;Fb}pA;>8#cd;VR1la<`e@1`mrzdBK zdsfWJREFw@My!8-hT>EnEdtAsQa$QNQZ6B`gp05w*KJ`zd4X$~X-^g?QEyn`f2U`hY)A{O5(o>%>L+Pue7P<~vJrTVE* z73GI-dRS0?_~*8aF*jD!BV+tt<3w#d255K)?EUy{nRil?M&_Y}2Z=94NANnizG1Q~ z&tVgpdmZgN#sjHM#DSm>XC;P#I@7?P_YYR-O**5;LpMn1IL+}F8(1zD5f-`q0Xa$qK`0P->Og)u>f7~RW{#K z_7mR>s39T~+Q;3wcy%W`Fl{PgQ`z!k=Nd;df9kfXeOP#cT#c#r(ZvXPU-Ap?Z}ygi z0~8gc2oAmdPuiwt!ye{pRgoJKA5q+U$e%)~O3+)o{#*NRO~}#}O|QWlU$?rvOhite z7#$t`<%@!fN`T)x0#DPIBpp8(0;LUyoTI;eB|kF3?#@+TV%&Av@JlQ*ps8a+~ zhW_vU0Q?`VFZsE!3p=T(xY*jx4htP!_+d?QG6GH&1H$Mhj_@!Aa;V}JM)BRadUK^2 zQ=X1jIzQ^-30}l`w^BDRnQOq}Ui=xQn@d4dbqyL8MeBU^Z2Uyb$ppRZ3Zjy5kB3MN z(Iopn4?K6%E88$AVMkVXL~PYnadwm%g(jMU;9l{YKrOBSI}CNK6!8!owV`wU%P!0k z^V4ABl(=U+qT~x=8IEo&STXb(0wXRHEiEnm{dgJc+uPgu`HXxExyj<-=z}7rGF_rt zmB6d%oAZ)u^5Ahp!fKVfLFBm3C#jMkUEMG3vvJ7s8yLOmZ|x{s^~MEWY&cI?{G8`( zP@UqIN%EdCmD4ND2;sOR)`O;M$=vFhn8T*+>|0qfb$!b-Yst|s((<3hU&kAwUWt?6 zm=KAsxA6%+^I7R#{WPVrnJ>CFp~D{4tIKj-Th zydoQEq-dRQDO=!IuX1c=5NJLBaKf7ga2?*I(Z6S3q}!C2!ZhG^fc-lZv(g|~`tplj zHvXUxr;M9E3L>>ps;imv3I{BBbCR8%-Nw#NN>Z}r`B!w^j?7esA8W&1_mFj)FC2w? z+tlupiu~PVi>XW4!il`6x<(3F|Hm3}84?$j>{$&RWj+u|WB%V4l%emrnRr$5aC&$) zO|9qKzqLmwMB@H`pNw`hMB@DNd3R3Ide7x{y(Nu_^U7?xT%1*tCY@Za6iYWiie5z_YJ9#iA*uZ$Q( z$)_s{ois?Io$_A_3A`T0Rr|8!X>fBZauHG!`It^Mn_@&?N4VXVb0=QwD^A#yXcdAr z^#E!*$|vLU#6^|d;t(x2PS;d#{@)vt+yCKPN)w=0=ukN#erZW^!Y>#3RqxaPpGRwS z@m?{r`8k}LV?Da-#(ksucl!+cD*EJz)H=C8hXWcvOMM%adL5{%(`TTKy}nF4{8IF- zQ}|a^l)`5rE}W=xc|6f`{^GZ;A1&jiRJiM_8KX*qBia8~G-Vig9`d1~nH$3!3(FDF zZQ%(@<)4D~{~b*KE^?u-bdx9XuEoPBy%mL(vhA0+QZeXzb`hGzIXPHde+0_(ii`L> ze$JjLtI)*7#@^4AD-dNX{uyDkI?KPo4O^lVG4~mloE5ET$+V=|zqJm{TeyaK>Au;F z``Z6`n?DoFeCv_VLxt3o#9!K8w=eTWp>fOD(*-dj<=^N&iJ|U9o;kss$+pM%Ae!4@ z@|>LFz;y3z+%t{+NhkfD-ks*tt8IeBkcQ}hDWP~F74hc_2AOgC#GwvLUEI@xTfZ}< zOi=wEb)qvAB`5pov}3y;P1@(Z?UIx#(|eoT)bc>C>_p{Rv?*1=R*d_zjMn0!Q|D?W zt~zJCuAkO;WHwb<(tkR;-UMF8C2X8Gp-x5{2-bh>36&odx0B$s>SAtKr?wC8qlCBo zCPgEC@69i(!X;^wfIFkje(j%7$oYA?gA&poGI8b55vpTM`9*sVxRob8D`R6hKG~?4 zUK_}{A@NI3?^$P?ac}*}((gx#hXGfCAz^;X!O^&ZHLh$Yi7+{sRW}oybSC^su3wrQ zr$hHAA&2cLk)b{=EB_sTUazL-kI=@-On8k4aICBdJB@SM^l#Ei8Q7#%m$mS1bcRq5 z()bm3asGI`E7Ytx-lLE4r))+{9T0e4_ak_b*8jf9{!QdU&n}lrQhT;LI|kFPmkp1y zZaOkeePb6Ki25oRhK~HqbP*A&8V8T*iE~@0DhpvG zkNp)2iz&Vz`I%OCl2iwmOinb5i&U$mh)18Sj}Xl)4R_*pz8kv*1oPiB(?3r81!4Q>Qs?mzJX9WX%bZv561v~o70rq=+8N{AIg-<> z@{m$f8&CFVl$>qBggUJN_OPmo>CbSFa*aJ#Nf8OhfOox{%g4ys-UbS{fx0hvGICQ8 zR-Zw&s}HUGzZ)9K-f5T-Z@o~yQzzUQ$X`t)4hH?k^h(bi79hLDk4Yrtyi{CDA_jtH?*i)r(ppTl~R zTf@6RHl_|`Uv??>osAL+vr0c%|_`|+UsbFN9%5-%kxCNH;t zBGRsFOHV_pyqHty++@a!1Tot#t17I#x1wn_X?R^b2$%~ih zZ_b|;^C0cLxfAiJy5~^UqKxn=H?Nu}SuP8E?rq>7|4>yyljXXI z@cgg`tTOjc%kL39R$}RETcY9-y-E%AKW_fv{7C;>`Vb?%rPyA8`Q%iCt5fJPe}+Eh zPWv6apqhK1XiNnXG6+axS!5~_7ctov#FTSi(mZEgPS9J#I&n+sKreoVCpU|(o*X06 zvY)?M89~ganT4;{U2Zo1BPaC5?x13l?P|Zwc}5yz&JPNckM6a;)(4*`HC&vh2pc50 zuiv1zh;l#m1FBSRB85*BdP{oP)`3)pzd~za@F#Qd&d&Z{s3cKCRO>i-(4{8%4RbuN z2bKQede!#Xm9=^0Ohn+1#@A3i!jAawot&?tUW+JFv$IowR>C1u`M}h% zw3H=tiKj49tk)FrKwm)tF_fHax@u1`XN%5={%;_=P_4jD8OZ6>5Q^%_dQ%YXfi&ui zWz(HB{c-B1-uS_v<^S9Yi-{){wG)cPbk)`Gs!LJT`ue<1cgyavj7HlJ%87EhDuyI4 z3kXc^9@GV*(5K$8ofJmZX~W#zsiJm0;3W}ga1kC|zWVv4PDCWJxI0vSl%7ds>FlN3 z^RN!|jB^1>1wY~9Fa@+)Y-ebsRw_Qv=539MP2}LX7lKVEc{hOSQ3z+rI0F-x@@W&c zuHDV0Bsw}uyCk#E_l64277sU?N9vx2C&=vVP3R&kd)>~6RjY9qS*CDedN)$$c19)B zH<)*3zpfM%($_%5yh-SBSJ|Q!Gjbp{PqF94@6b7I=6$c$t%saC{sM`gG$-_^@OiM* zBM(Q=j!e+jhDzeKe9!4$5q#8LS*$I|ucd5Y=1>+I64PdQ*Mz}Q;vbzjNamog(@OV; zSW*W#9n->gkWi=yOoo20uS5V_qd;He6(#z@SI%`t|Iw?TO;EE`3_r&sas6FsvjM`81ELsFEo`E zsMYO)d=>b0w4-B4JBw$xjFDy3@^eJ+eM!wB{pgi~+`JnvhUe>CqOLBEwpM1w$}Vag zm_<;NJf=v$pvUoC6?fz8@x9`S3kr$9(N}bs;yt{b4dz}2t|+yy^HvpB{9$^`u0(RKWcbf*m2y# z#^P*JVQ`vQa567`Kay^*OOeDo-*(}Rjfv&Q`&8`?0i>aZvrQY@pl7;DBRa^_61I$4 z`i1Ihd%N#^uDXn5*?kvW@B(WX`@7!7yPqFqNc$5R{`b5Cr6S`OYD>;*Df6z6+qC#u z_(;wSa;)+T$)2^48eJXLi$GoEl%U`Ae-_|w94FwKjhDx8nc1qu*2SMf%zhxjrX9gd zkP;-Fn*YQmGqGfEdM=4CP#wmjVV;rE{(&!0i>au1{u2P+L*ts)wc^&1tf-g6O@*4x z;v2D1ZYr21GGlc!dXyW#{D#$CuxOD>Sop-)vFe6WV;Z)NkB_{l!|hty&BjX2510#7 zA^U!G>a|_@5q3adaAl*{mWFNN!{2Xi?CwqWe!6w>$o1gPB6Iyp@axOo zl<5El4yVhEM2Zgfhg_{`)XSdA%5Uixuh4RM@WX@iB`nFRpq+|&WPGbEvobf=(_zX< z^Ws__a6AIiX0vho!19?JdcLfrp5r{ zJLrxZA6(x5|MPr@K0AAv4}UFK(3$@<7KZ9V`8U;vXCd$X;0fM+Q!gLpFCmjJCH2Pr z!cJi4v3~Jd;5?PGRK0wukbKTNV!tA;;6_W!j5t9p;P{`pBTm63nSZ4k^0Q`xeqm7Ax8u+ zaYBG-wYYW4zp2=@ZyJS@vd|`^ERkj!{Ek?gJg~`{QVMxz6Qb zDKX*M9p4peN^1|^n&fAkoS1jsq5Y$jE4QoUe*aU!yQez8Go9qJLc$q^uhhy-*Syh! zr<)&LzTGu(->VFA$z|2FwPJD2FNxvo7A@ zEuY0p@>g~ecI^qBGeX5ni@#i6#EJaK znTCrc^R8tm9ZptO7t-WQugRLLWd)vS(!m1S_0m_)_#geHz36qW<8nYmlZ_2&3HFh! zFN`M`WJ{n4ca!6v=0K@S(<9fjXO~NpfbOcaxg^lH>^3V83d!0waXN(`_v|oXk?v|oI{*fGy(qVMBp1JU%W+Bma&eNffOYQ?nsD~@-9R{<3EAM&63 zIlTWsK|tWdr14CuqXCb^`2B9#mqDMO5?4^dK)5}F9GIFqm}fvjO2Nc@#BZbDUfA$D zY_B`KT{a=SJ;37_a(O&o6>`@RWK0nt5YWB&0}x~=I3D%#ei6Pr*-8i7%* zeH}t|g{j|h?5J9MO60Q^iUtH<4!t0{wVzd}ezE*KARs8Hyxi#b=}I3~m-C|&PHv0D z(5c&t9JVOxE*qR-a>i|+T;FJ08OSQW?ErcfOt5PO^Q8X*w-&3!KxqNQDyxtED) zSjOS?%bB#uww7%=DH6)6>8cgaznPrv18PU?kGAV8{YdstPb}x*?jk=qc}0thBj-bc zoRszH24+8-;&Lt}YsxqBxgV-zCRM(tGOmVE;O_XRcKmxws7(#Ot#X&pbC5G9qxF1L zEy=I@e_fQG=FeAy9E{DeH?1?Cu^zR{eAsz+KF9%K`d*8q=!ggHg={DW#$=Y%wV|j5 z&b?z1+tRAa_l6O|@=_cMv{`Y z^bMcXs@0U!`vsWSL>&C@F3f2cqTTVe-@1HOUFx4;{Bu~gNjGBgaAbY&;p2#4h0@>) zZgyI|h(z6tJ5P2^HFptI97Q8nMUEpIC+>IcnLJnaw? zvFlMar}wGsL?Druq4xc%7!d^pgr5ZA4H;2E%zJ`EMe-N^J`WB#MsZu(TWHejOCA@4 z|1Fr~+O7>CW-LCG6V=yy`tdw9aimDcg@fKAW7{cm?K58_$*qo9`oZL@%*-(f!jrRU zF;v5;k^G8qjgsU>w}EU59tZcW_0j3E3X2EU5?y!0x5ODYCBJhep{dy2J2EDPEFgWz zk~Y}z&z-=f_~BvDy63x41Xs=~fnkEK5A+C00h#be%=R#dE(f(e##b zJBdY;<9d(C4*flq`*EJ*QTI^an=TM{{K)lQP<{WmEsWJPkc*x9L>sTatYl-wQK1xz zoftr1wWU^6{pD@_FnMZ1hag}dy(jnO6w!0^Do-(S&YZYzn|-wtH8a=sioB(<#G$?R z8#=t44ddRqovyW>BtV*zt*6Pd`%lkc7nxa0Ddab`yTs?jaLpD?^+-;7xxA5*DccRM%D^1Yi4h;fqqVHm&Xj+dahWNQp6C-2T=AjrpDDgLle=Oo9h}dC}rG zgQ9adHFREnk%G485;Y+M6KM@SDfb7x`*C!^y1EMA_hyt}v^t}XMX8Wi9r?dDTX;)? z^NQ9t;v?e+$p*PW(TS9s`P{vD(djt~IA4sO!le4oH8F@skRs^p@THa-zdAzc|HIW+ zhGo4jUlSrqN=bt#jeye9h;)O1q=Gb3(%l`B64FSgbR!*tfPhG+q%=rKyu*%j{^#AF zy!MxeyJptRthIjl|3JMrFLurH(2tTD+dO`i@(ZCf`|K`dCglmb5U>Y(;jmY&m}6*^ z+i+{^J$@T?zuX2Bua@{B@&vv9_46xWJ3tY@v?&dU%vMd2w&|e00rLVl(Z>Y&6ENS1 zr!!tenY{hK9mtLEzB|7J7;1{GSvh|ke$cpkg>j6;?ElYItVAgt513~$i%bgjFa2io zyILLa5i|X zA8%*h+{x!-dpKiubO7Wwy_&zmG;*igok89FsX!g*b}zh?B(<* zdEb>6?ytNUv#$SE4neZ`lclGh4T!znm~R@0euI{-Di4;nHa>2kD<`6fs-)sS-E9f{ zK)T%qlIQ$iTG1CW}Jw!a|NN9-4u(%4g&Dy2mzM!PNjPw)6hmGxJ1a(e_FyY&B_5sU~& z-^Xg%ee+aO3?oz&UW&Oe{ek1n4#oapqD4{q_(?!W(kekUYdwL7Ln zYf)DYL6ZPC_Mg2K{hosH!tK_vnb7~fov2~ap^z+_T#7|qv^=I#HY;xFAD>gVZgHU7 zS_GjyBBe2Gl^Gg|jNW>aAk1PE9@RU3Uzm&f`kji6W{~z+|KHWnZUajk7_eqCOuO*4 zBRIjR;RBhV1}viM`Bl%_g0poI5QB8l{GAX{V3-}p`A+>iPk$BF-Oq1gV^LV4Um8#I zaY2{&&d)_Z+gv3p)Dg2#A=f0~=DUc0&lwr7Tkyra(1J%a;fzoJYv^=iQTKhq*B!2m zNB2m8LVmqGuT(MNX$`A%nnzL(a!_+AJqPSDyPELlpV%Sed+o{)$Vw&nJE) zJ$uks-%j%Tbrc)n%H>P zjN%R$6aW1La++(6r%pB9A0Uks3XCs(|Nd7?5940!iM)%tDJmv2#x5J~e2re=*JDuoH4Vmpr?^4uBG0Dt z17rESwQ-L>k-jBE26oy1`I&WX^)!tJ8&>kaUR(e8J<@2H_b>vTwFG#d+ca4JiBoai zO(l(eHuH-KSzS(uGS|Z%#_@`W_x?$WI3vD6zyZG=JwRYY=a62@8TpHSpMLt^unD|z z?SPUF2%CMKa1XO)v2w=ldj974Qq-O+z#H^Gg5jAftk0z2TLn?h zN2+aJea3NIyrJm3#E1exz2*CFuggZWShshI@e765`^gjbZ%`=>NYdQaYBzOyMI7VV z?8f8CIGBQ*Gxpwk8~?wHOckg+z9#nLqE;qJ{G9~|x&+R4<#I)2OdC){XRc3?U_%2V zX$jOAsLX#Vcosc(kYP-mFDj#q$ZYBlyG^90)07^l*I7Z2#yGj2l0O{6>z{kOnUx4A%bx2Cd7DIXMs@Xs!2}yw^cIVAgqX9<$Rbk z^0@iPApxz5nzDyVQ?KLDOHb(4CD40dOzJb9D%mKzr0?(0s#o;yK6Ive5LF*N{Qv)m zsuzty+hQV*w`tJ-dTk-eTW3kHa`0rya}1{0nFWC1Ec04<7b!&qN5B_{o#yDFc;#g0 zj@f6uhxVM!SDT{!Q{jHK6;sc%vuVA_G6^6=6WNGk!w_OYcOc5zTXbx7Soz;8dWcf` zkdzYSDYfxP_XsPxE_=sYNN4!m*Dn*l7}2o;&4u7hIMQX1>!@U4glQV)?os|le8jbf zlAoj7firjCmaO(i{V|7uQE^~m6|t_muD{GP5(pbP`AnbodE6SxfcJPDjdC5JGH3@K z?3)R9nufPu$9JUgYT%l87a`<4RiWJmAr}B>&RI`RnHZOw4@~>kG-QF5Ub^(c^1}jI zm$LfOhZaGx0vMp#GF^iEs4HQPA7Ua6=RBuy|OS zx+y(w&y+Ex821-peoNhDDt&C8aLj)Z}$nNicYJ zCO<5&Me|jsUOh@9k&wI6+3GtsAtN!BnYPuYFy>2qbirK4QK2PkjQ+5DkLv8X ztdQz=eP&KV=5M%FaqRomDe*zZol%$Q<9m)Pq~&j<064rw1+0?F#f1UHGE}Z~ zHSN{t=wPBXKG;Q?K|YktV8~pZjNW$}Eb}`^_Ii0`ed0iMycKoL^}oDyERj(JZc$!D zS&3lhkIDKSj0$cKOSh@+Wg}!H>0htrlhCz z9G;FGeQC9nCRk)$f5WO3pLk%M)_wJ^RUhHNLg#-fwqpG|XJUaJ`!_{P%PP^vZ(jXm zNAb6l;T$vjs1=e-TRT&UQ(qZA*) z{I5Jq>Nb;D+!vN5rVTjBB}=jr4>@(3yAOvLj0WCMrTkeg?U2SjSl#Nm7`JBCsFW() z;5w3#yqs9+pWRn5?hsEb4ot$*_43qwq^e=NnCdbvKGa_JNO;_Hisor^>V(;m8$$&;+ZZ{JK z**7|If>ZIT(@j%Nsy1m-Y~~IKS2_7@-%etv4}4zn!pR*N693aPbePWA#hfO;)F^o4 zsP=h4WZim%{^Y{``Nlb zrt%*v$3ZLn7?It#fdV|G?AV?r9%gkF@9vswybtL^-3WcNAs-YNaztDcP@_BKm8 z{h7?I(G;azaUD|hJGu&VR5_@RO_GcDK2UXlxGvIV4hs^M_dkiMS9@2w$#|37N@zPf zcz4%YU0q#9MrL$sXB~qU*+}Sz&GPWaD%v!K7SAan*6&XhPZaNvmrnmYN|>+Mt_Awx zI}YCy_IHqbJ~xGkRJ@V(NM=3FURxT>UE+M+?fZI_XG1MJ4YOLHfI=xMg*tM2u{FAf4EHT!$HBP5;* z7kkt)O{$ht;hA!8%+X|aP4cm%7cKWEIEV1uJa&koD?}?&1VOk*j zW24~sv$60@Yj`$o292p|$o1<%8TA*hq%&QOE4hVLfy^R=a`ICP$qKoN@-JT3o3%^?%c!l~eS27>NgvFYi+TAvS$s1u zaNL}QOn#{@&TWuoNwy_n*k|u{!20UQo$8hJF%N%ZcxWi(D525Ae9k9U*HXiftR z?d7R-MOk9|x+cWlzDD}AcQ)8%UT{Z(Zo4~X3rpwog}$~n84HOP^Yp+Ld*`pF$8Ns% z4uPz-KPH#P40h9c-hX@B-a-a4y;>_wPX>I5Sw70exPBk~hSGw5A37$~e3;Uhn`lcK zamh3NGdxX!SKCCJWdEJeV#RRQs($R()=BP-=i$kcbCmek;yn?k{QY6YNJt$0h8%x?ZojY}f_*s=m)MjuRD~9wv@tOEqN=6Eeip ztx9}>p%c<#QP?`YeUppyvZIg-uR(`SE^*4~Vosso#O$ulNc1g!mMaonh2wkqs8WE{ zI#XPNTscMdVsd}K9PDlqw*9w|-@n_~NNZ)aw_|e4>&!t!1aV^-D5$}_zJojQ+Jsju zybxg7fQ!aUScV-3gWe%+3@WJneaPB zx;a^+nXT}XiNmXp(@rL*!v+WPXVMX|i*2b1Y=rBYnBo?#g=YBI8*iljEMR;@KypJQ z8Y%5ow|6MCUGjj&hNB|R2?Emb%e#Fe}IU5lDlF-cbcY^R^&yz{H9K=k}TB9i_ z^X~efCSLTLW4g}`UlM>)^g9)kyy7qRSQr{sezZ@k)2{XncH*A4NCt0!t*0{W@8o+N z=hBS^0plv1dRkv^un73LX7Al^=>Zv?T?v!!=lje z*|zGGZi>sG0I9VLysx&q1p~R&mG{?^>bg6afpqV@6Co}tJ=^g5*V$k(l=_882Cem6 z8^7|tWJSCiM-HOG&s-Na)n?otzp)k*OINi#OzCxthBe-)`si;Y0;bB6g^+LiWpZ!Hu+@_aY6u9yW1tPB(QN!;QA~y74M?p=8)xXD=h&Eg5fFg4_V%86BckL_u+6R+u%7a$;HR_1 z1X=F_65W@s+=rKm(jGqEY+hriF*M_X(}yJ79;(hp!tAFfBiPr@6-|6yXIc4B3OQkV z-CMNI!iuPOUeej3+s?S&$y@sdgK>Gj&--ry4^b3bHNZ%Rr3%F;Ynj<8gMkHPK8 z$Q<$I9d;i)PMRkHFRmdeMm=4-O-|j5@5Cu@&tePYOHl=Yx0hOCXg{ThZRmCyFtj>d zt%|NPMWLiAP8d?l`Dv|twJLG+`(m}gz$@?86M1hF45}-9lv2U#D>V8+cH-HO_w0YQ za=dha+tRREERm#8-(`MH4M!eT#7$i0Fv;&eks}ycXJSHH@T&b>8I zCBawcF_s2UL78yUH9230*3UVIaMT>s;RCPOqdrD zy@tOR9?s=%tm(i-?^)1A>6mV#6wS^b#H7&VFWJBUx^}F7;EM38*;i`wy6Nm`jKA%Ey1%Y!3)JODRtN@& zpos%N3=nX=n~aFogoo^eIq`fIpLVY7*#V6%sz50NpK@3+!IRalbdcqn=L-X2a?0-`jYb^Bp>gVjD174|fXRx$5d!UElOM=820Wo!1nPI&Kg~C} zhfXxfu4IiXtkdWw_y>;SQaUc61?{z8CQ-Y5g~*AP%?^8!z9*OS8J$(ltG>L?_#N5# z%J!=LkS%Ew*IuUSwPrjR35HX3783aWbn_@?IV;Zj>A89tp7^@E`-Z7nw@5lSdWsOH z9$>#h1x+Kq2FUU=*DaTr3*TI2WLC#?*_3Y!z?VRF4*5lphVGJ>nWg=a(6sx8t$CRn z*lGltytN+|{q<$c#^7lY`gHM?46QxbT__KkD@z&R>Zad(#?5tKrF$T(T)6I*jv(Yr zoIjynLHi#u3bE-#YqBFD&w=a7g6?9vRLEvt6)5|O{_fls1f#Ip9hI;1AwwYV%$e(l zM>GAW+y+ksgqKmD?0Mq>hlgutv;1a|cej^&U*!m50%$eaQj|aZeWJ5Yr($bjM#GY_ zX*TZ3lEf^@3poJv%DW8;vaY|V*NvI{5r_ZcatoWo7&CXa>eC7;N4{CEKVgyNOUr_3dEQL{|x4r`#79)!QKDUa`3xC9_FO2ScsyZNEA_ z22?=h^62k&{Bu00>o?!!zVG@75!W{TRJd84XWLy2R16^fzVDy|Z9X5gmR+!{TCVf= zvovvQ%mTLpCDal^|E{IDAYZ{ajZM7{hn=?F#7{DB@%rlb896*98~ZJ^Pc99NP9o5g z&R%s0S3Ib-E=P{VNYmx4fdkg@e4Xk_uZy90vv14$OGNsx?S>9%wTCe>y@HO$&x6lv zA2;7$OG!byHf#ev8s4iN#cTVAzr1y9o@K7_k#eA3Z~JKg&83U*7|hj8Ku^Ap9@>A3 zff!kT9qR)ozy?I}C2l%P7;kx3{Br~i9!$-o9pV7j;C6GNoAm~v!;&nj-2LL5P4fix zd(Q#T)e;VoHCG&e{7^SP>j_GFv*S)Oj*)hBgbBzB0u#1yCuBJU#FvaPFKg4;9$?Fz zTC*~c#Jkp$oZG7VD6T;yJn1?CK^aHBHEG4Rm`BvI%#Q%Y9t*zA<_(l>)XKoKz75cg z!^B-z#R323`6_WKf`9rnZrx4+z-5pRGn^vpdKq#w=7B?yEW6E{=~o_oSa#lAR@{A1 zU&B68C%YzZlF=Khe2rc+uzOP2*WZnfKtNSwbxYH^|1|ffUkw>SYx3Zor}P+e9?dr4 z*dMcvhKMc6qQvQzP!Kp_SWQ&ldg~as8(dk4epL~L|5Ubbd-Hq*UDrg?yTtf<2Qujd zmUM43{)=DskkT2X@5f|f&s9=BqD=V=HXzQHRDPZ#ANRC2Kwmk8DqI`^AkDsG12V2n zR9OZUWMZ)TIpgP1TO@eX4iZwsy+OEdn4|C2Iw)Gc>~OUn$2XO=GGC-SWw@DxJ{pvG z1rNWq+(D%O$ic1!U-_ad8b+VS1 z{qE+qFqj+~Lk+hEeYnj1m{_-1Mv`V;w~Bk${0D?so#NvL z8eI-RG9<^*+5AsN%0s=ADSQ4>emWRM`zr{K=ok_b@|H(nX+0-6+eOD*t1I^!<+K zcWN-tfR)>o6b5)Qr4I~6%BW&hD4{Vs8BU$HJrG()^l!IqyDNpAwBir4c<@R9YY=FC z|JYL}zfSEsOLd#Yt6&}mhAs8^6}%KNWFTGr73>Nl3AszIvXUZP9UYifQMafT*MmC& z)3qcFeMrL4#S%tacged0ES?}w3&Z{)RqOMfhk0|I?WHYUGIx}tli8!ll`m`)VCtULzD<|(?aWH)`r137R_qNN8? z%r$<9QUsH;B~H^1hQ`Q{=?VNl$5T-|MZJs#soZ1B2Qbrw%bhAvCi=j&QCVj1rPG}z zXqV${ z?I3=yRl(jvlKY%IXc7WV_NhV7;Auw!Rs_u(8wGjonU&Db%3DaM_&<1fDrw6-Rg)lp@hdMIX%ziSkRCx6{w^7#8Ik?7v zbpe<}DbUhndH9uZ1wBU4@5HJPbME^6X*IzYnW&1~;a{{AQbEco0d`I7wl$DDVJh+j z(z)Z;W^f`f+7~cw&>&b>9BNnm`heV<7GgjCA%|=;&1ZCu8@7U3B9WEX-U79ULD3Cg z5!YlhOVAXiM_53>52E?@CIb=n#TCJ^8+SxhSyT!7#Tn}7RRM0FwBrJZL(+5i1y7%~ zK1OFxS5sNEddbh~_enCUKk|bE7TEf%>_otNIe$jjhvqtjzq=(X3H%zB)L58Nc>o3D zSL91Ev+6Mk6}U~NLv~*v++O<^iR)YoW|29(l@X$+s@eYh4a%^>EGGk|SQW0?YSkDHg-nk-n(t~MTU3|en zLBav?fbvU?Ely`X62yYnOuRFQ_R6EG;QYm{s)6!e2ZN)bkafcaiWop`2$OH~rGYRp z49%vc<4}l?kYjF}$@JNb7tW@>4XhgcI)Vm>C=Kqg3KI0jDQMp@wuZAmKeDWZqi6px>!;5XkJ7T1<2>8(C)Z@O`N z&H>BvnK?23it4_h=%8V};u^4kG8u5xt+L?k$q~6ju>IHr53PHIN!#JvBeF9+Vu#Q5 zogty`?$+v;7Lp>2yG%zOtWfa|1Hb=m-zIlH!=XdV#D6mEPc#C&Co5 zsO!VuWJUq5I@>7tUX$7d7=XrJw-)l227!f8Kd(s_R7?YwWVc?WuRr4*AG4bEfGP`8 z9;xR6jq6ed1iC+^t4q4Y_q!SH7~Zz~*^XX`Hm;;u9YgX**cn3%QI1qGe)!kUGU6$W zzC*x(04^i=`bgGysdQJEBdUTsiYh)yn#&xE{;C*I&J?c}n>nW!ru?C!(oNCwL2qI9 zk=;sr+Zj{obqp314{u$+JTP%W^0*Ln^^Aw-FB$T9n!Jb@?hu3n%W==`iooBKPOGsc_wZME zZk}A0k3)h55=>e5BY)_ff<0gMY*p~dmJhshD3PtFB7}R1#qxS!;JMu#c&=RArX#9KwNoX??iV+fX;YIjCyl)6V}MIP)bj|`d> z$$t5C_KNNL(Dt<_*%HFdW1#{o)wL!%Og$99;a|j{As3I6z{{GQx{N3`pK9-sS z`e=ybynJ)-_%8(?RTQ(VD<5PqxyY9t?EF&c4Q3T$LD9Uh)eCIiYWBmN)`N7>raPosWf&USHl8ETk^>B$*n3A3qd~
t|-ON}P^Y%gsnRQ90%$60qR{?=ya2C^phsT$_(xe)s~RhF8RW1f=zOh2<*?*aax| zqNBu0@f~0XbwekWhAbUY~@G5b7zjSi32xmPcNy3^H*LSEbQYr;0h}^{PgI%~W z!2a&qa1t^K#JBXp@*d@X$^jq^-{IPeCe}XeReY(VLKYPi?K#@I33hAtCq~{H9~OW? za|oAJ=X;FRKKezLS;+1Mr8j)N{_fxo7vfzsntWykNAQ{j|0m3C{$d_D$f|Vb7;uX) z;gY{%yRWB+`fTQoy?7(Sko=5wN0nYr zqbrIUil@T3_LXdr{g0!xP};;bgie;u+Pza`&|yNrGv1x9bV+{x@~F*oK?K^}Oe6F& zmv=>f41IPt=Q)oSBfm#Om%Mt*MeZq{(~tG!r%)jR$<6-6G79j)gX5P>p`HQb2+zBP zNUdgYIV>AFv-ds)1JaqmPJq;+FzUT&N|w90dxQC`K)4}D&~3#08`pGUAvnT0o;c|J z_+Bwt?s*@uJUbY9U7};vM!dj$U@P_4I**YwWt^48mufmm`lx`vj1*7NdVOEjSyb;B zWoeertH!B%1++c7m6iC}P(uH*5j+O#7pf>#w3J!aq4E;3rGg3#oGGuL%^O#t;*$+k zM&JqpXXaq~=`IqZ2)n|MC5^ywY}sXMrGCH%z0@(A;bE)!0OW z9^65F0QhO1J)(^Bt*6-V$|GGw@#4C^R!EcsVU+t#ZQvpL*CTw%q6&m4Sk%$}n2YqH zA;<;tG9F$MlgL)g2k^{fR9ChEJgq%`IV8)l7oGT}?3!nZT6$Wz$MT3dnef_67z|tM zy20DQDQxOigLHlfa4ZsptYAiPGH|7HNGk4y`z*K<>W!|B@-v=|jI!Y{Y2jROJLZhp z3ASqFbg@{wndOI`Oor-N3zUG^XEYhyN#gtS~6F9JSRzzc_<{}8+^b)Hvli+lwJ{dLEcm0$8y;Tae>D*RQd z4t!j3Hii2H>&|*2bgmykF=X%n2+;PUlUK$&ET2E{T%mgHaEn#9c9pf>n22n>IYqSn zO*vh77^#zZ+p>K|@3VDarRgMxy`!W0#`bKEMcWl=`OlZL<}#)a9OHLZouN>1XSLYb zpEa*@9bEfzdw1C2g)`gnHznRY#)rKJw-uZWC>sA*)g(4NJp0OiVv^uo`h;bqTITL- zy+s(h)v#JeexN)a_oF>@>N>CJ-krR}j!#tVChvGt_0V`G&#_3%nw+vZ|ApWz8I8bh@LElnm5@AE0)20ob$J`>=(<|O*gz&H><6Em9hKj)pSE>4$ z@SEY%KNk2_guZfZ3bHSM7Q#5oEXry8CbJWHB;54v*%`|^iq5BWo$(%ev&xVnHy$tX zE!wk7=W-6g@P6?EMY0$&k45hR$}g{Ke^%^23y7l=BrUw1z9%ymBpXf-%|-Pe^%`q-#N1!MQn!PLas<4EFf(32+^Lu{hmg| zrSc%k36d8w$q=1fJ?dF=kwZ7i=_zV^WA|;FFC^U zl=HpjPVoX3=0G&A;MaH#ClTF^7i!3NZM4GKHU&pC%+c}pe~<=V#CdA;=mxCvp+A+4B9+9;l}O?@sB|RBmM1*;chR5hD)cmy!ZP{o zu&D*BsI&4!WJ_f>pUvdwC^$8_H1*4!3m_7URZ=C!{^CUK<_beVW+aM@9(Igcy1U%6 zK-My1@ImOkn2wunYLc9#2)m-7T=Vx3-mBRDbZ`E-TbnPB;4BqQ^#kT6*~MSV-=zO*);J65F(pnHFCY6X4y2>E=jSaEcQMHHm96oy znyjiGF*udwT4%Pdi+ACKF8`6xIP~~~#vF3TWzB(ILfI?`#h!t{J~xSTA&&Bn;iSdQ zSv(PAhjw+E&8cXmXF`HZ3XP2xvf^_owc@d+t4mGi3B&Pt>8}wlH1#a0>ToP#X^h*P zzS*{l)C;^4Nl@=F=SvOCbcyZA5sqTNG*gCsjeCLuXL^^u=Jq>g{*|rODq>@y{lTD- zce|m7yuB*ejg{a9|>O;54(8S z{Vr>dE<(6AoC1RVPCFeQs5!Ho%g9;!1gK!hbDWc;9?7<(>EcHTixaT!6&w%u2n4ujd_V>-(ELJmEN0-AY37cQaYqv8*yUcHJH|Y@N1V`o9Ve~ zNLI}KLBUUyRV4Bb#}lr&6iEw}uPq)`E7TkYHMi}}S${SCCLY70Qd=x8lCmV|_;T%K zO*9YJDWcL?_Rr<1NM43unW$;g&TV7!piXZsR*j4DvilF>`}Ij+u^H*;%UrhcOMaMR zorVS!4WD~aa*2{n3~uVDcrg>UEAZdT3W;AOH@cY8zg}=seI*yfAjdZJuDqN%)7J`7 zU+0$yrl&Xp}T*K<+=#iMcpF^X#!Gad2+y3miA{4 zXXYpR-1;EqC2dYjk1$SCV9?1ANXPIs1GJxVwA{M;k}{EVGYgj2XluxP0Hk&1H|?490i!mK9U;=;uUUv)$!0 zyZNSGxJDw;fKTfEVFo5NppWPIDzu>WTHLwe~qNh8-%dfHaqe7eCHGjfAZ zI?=<-yiXna-M2~a%M0CK>Q`5x@{^u|7-cSx3WvGgrojJbi_5o|JEPqcg^qC6GLyFB zJ`M&)U-a|c8C*MLYs?A9w&wanRUJN>z}u|w%);DuO|=hc?!u+LH_#s*_FyuPg@ygx zj)Pb=Av!)^Phvaiif5`QS03`pBR|?2MVvhGH#eD&5?a!*QuZO0+?N-i&e~w^7WkoI zTQRS-mC#b>^f>C<=k-X-h3%F-{^T+rtDMs!-bDT77dn}`glh4*KMf{bx@R9@OuO_N z_NnDH9|{ra54)Cpsoe6OD($#<9lJ&5HKRQ$`{=3f9&VPpZEgW0V-;mn7eoRZd(6b{ z7o&R^=+yiiOO8p&o5a#akI0f0tu^xv&XDub?4D+c7BY{$!-~a&}0ljM4)FG3vbKL|RBhk6bv`iwqCC%h$e;@nR5~Gy2WS zywkiWSNtin(RPP~w zHa_LNFYNysI0J7v!jQ>drJMa%q~&_+PCBA0Sz_x8YetdVej_3M!bR^b7qH~Gh*kNC zL|*B+(iIiSTXJ)48*tZ|r%j^Zmvcxy<-+05Y_ zS!ECfHM}LsVA$C5^ZQWi^L6XiET14ofBy^{co9*?6n~0%bpKR8!=6Eg+aj$Nd;G3V zY%!9pPIiLC;RK7=FunXE#(}QwQ|uX9_JnJ&6Apojb}yY> zLRzdgnhxoSRqK<`^vauy3x7KhS-bSlr5SA$v{}_v=pfO^xTHAC8qv#`x+SeUP8vK< z`M95A;qg*`;w5+RYhU|@#peWZPcO*I)_uh0oV#Ai?GFhc5Fnwe-@X$X`Z{`KU?z*T z#X~c*ilUxO#83p2O-Xntq7w$WAyK)oYcdNq%O{*m_&c=pH9RN@BdDTu+`4jqTQqokNV$b0M|w*`q1Z zQ+|ZjWHl_?ln>ZKOpv=u82C})ANPK(%|s$!MJkQqtPr%$1FzML$m36`P+`H(tuHDS z7MCwp9$U3Ym+;_?2h}o*=PgL9>POK}eEzzziUOA_n}jcFLXyI)kBNQD&F5IRhP<(V zx8kup$%p%c{6-@xA~Z6V6Mwp9mQgGleiby$WDaUyUz&&O?WOj6Zz$8)h->Z z<5(x7G@8%dlMf``+@?H6qykY>Lmn{QB@Y z)YMBVOL~asq)NB_iH3UCW3ydm`CM^S;8BNnv#NUg7;ydU+^ZF*S zlB)f=fVYMMdEjGnHVf4{JCZMwv~~QV599^xzWp#bSvLU$=;NR*Rb#E*D;7FH*U$PD z3K2IWg0pevcc*{gqPLmzQ52wMQt>&WAVYu#yFxLhF-kzfVT%=l#+Om2Lj6zmRzct-Y^4 zwqE6J>aLGcjG^buLsTI)rcJ#_nM|y_giGq_i+3_m?(~l3&wCrDTzcKuV z{>E>ub1ihQt?@pa^y{|iwjZ0?aL%&4<|tdWnaLCN`;}xw_6>uxS(Te#s0+=l_!Yz_ zGIJW)&c2}&k=L17bsPWU!XxW{LwB{ibeuwK5v$uvleo-g10oQ@WW`5Mjo<}4>F44k#aU)l2H+6IGST4h``v@(PgLMIS8(3BpBNfv&tRXsEVO{)Hl7^N zEJ!SN7-_m`G3?5syDUb@X-E)F`ZY11hnE2=N&tQBKX^9UDni1v-=f#y-Y#@gOR4;o zTbL~9o|O3EV42w<_7olj;FCqiQM&d`k7^a@}XL`=<^xW>1_^Ii>lw) zs*R>iKcZH*H+|x^$Pj>~h~TD{T1NUQ1n%XikeU#y^~eNy<>usxjp>TobEIR z63;0QA^wE~7!2Cb>;L$asMrdKLbk;I{otyjJ7-A3#xD94yP}7F#Nf%9E31&vVW$&3 z)96&K@mTd}tsd;K-i)bSKh?pI`*;wR5G-ROOm>_Sv_ibSmXkvby$PjZt1{+RDyM~ct3fRY|_eUO;l2y0`Tb+;>0c{2;l z;Fdpq@0-@1z-bVhI3F8Wk^n(1i?s{Zom0!1@m4?-MJG3ays2{h1G;5by zWM8t+eA9UNq}-u~O(Qjzf4?|C7U1rJV-iO8*VmVq00ArO+2qS-)r4aY zQ=gr<8ID_ATupx$5>Ncy{4;-InGfe__6x}Wb4pZo3@()f~Z-&@Gv=* z@F`eN)c7{q*rA$#`g_hV#y{*nry73LbuG(QAPJ}o(ti(q0qWl;YSxDC#QbCts%5yj z^F?*UU2hEV^Pjf8MjsRl?4fU0HCPr;@id!I7zZ2+$t1+-71}u((T|3&;20^87o=h_f8eKDirgvu@dI{!Ldz2L#3Hmtcl?UVSe$e)0Y*v{XC0lZw-+-KcMTCTmx;IhE) zcgKr;7{JD19fxj$`VD)Z!9F}`S2ea`#cp;p6cXA$N`(S;*h9u8c=DJ$BJ&(n?2(h` zlg;!nR5a?sdGeQ=gI(I}_p*K| zt5C_h=q+)WWVF;-c~onk zk3>(RmEJST^r8uQ%oPP<*?p%`u#Z*QgD-G%T*&hoT*=i5d2pPu(Y=aMj-Psylez13 zjm@Xb{mAQ>`qd}Kr0l5g65i;95^A~WoCsg2{d?AyL~#JlgJk!<#&b-@Sy?Ts6ZU!a zhV@_7XNFYgG_Y?Fh@IBS(S#gW*Zt*E6>1-q2D#BamCWu_smL&6#&DG~qF0yF4$(MH z#L1(N3s^dGqk{dVU9axKkt`R~N~!vb1Jz*jgJ{31*5W3eVXUu)b2*@?3SG}20Jt`43o5|^T4(s(e zi3jf_VAq{&iPu&{cW;P)akq>`5UZzWL+r!m@Pu1lD?4EZWoD~H`wgAkry@rh_PAYz zz1prPGP~_hgBWyYxvI$mJ; zgY<>k%nNS$WA&rnyf#0IdUAkUY#|$Me}N*jv|Xg1rcZ|WM=U-m9Bv%>PKC83bsTcm zC4L3GTXmsXRA0$|*_?mTBXmm6iCpuN0VDiDjT7M_3C{VQ3JTsw)b|dO(0HSa1nhh0 z2LQ`Lzt`K0>x@leAT3-=MGaBn0l0-Zniy7-LArvQ{3lKyiP@1Qpm2=lv|Sn3Ik+D9it| z^uB~$q@nRZk=Lq942j;)na@w$0fqMFNvjgz8$UTKl_Y7M0SL z?z#K`>Db~Xb9j^955KrJ!%o`6d1jB?-u3qsqe5A?8QQ;h&&MoCUwX~D)EYpN&&V?U z?rt>A{QB&nZlP?Zv|g&!Gib!@{Om6B(CD#v^6jjq^OE!{4S%&_2lp&NqVuB_zvk!A z6}!}tY;Foz$jvJD(4FV9RfjT8(S^OJ>AH!$^XwKUvODih2zV#toDgjDHPGaCNi$4C z`Hy3hvV%rXj3j9wJDn*?X@v7!yoeA;>!OqT^egW+9SWz+&)^lq7saEos=Je6DwA|b z7aV{BAw!|3Y<{E7+K!E;ZA1tYp0;yX;zqDTw!bq|(&DRzCe298mHmd!bN_Wo=nLw; zvfumAR)J@*+SYR2ykOqw&e0!9Xpb{mG2*lH7fY*yIMgx5X~5+gTu^X;oC$r|eI55c zmvjmM6NQMO0L8+Z^b&R`X=*ftKGjmQph&--meYl00?d%QJ9TDP32I(pI3;`#m zydFx+2hWJ_f_6RUB<{DRKrO;4WwbE8$#st=Ol zN;*6oB{Cnv>Q(wa?E2UQ0W8&%Fxm4WeNKu&9_O5~t|j#cO)37X@sqcY9t()+@Xz^K z20kjKKV$2LmOm6~;yP}#33N^6Sw9+&tb@fe4N97zM-n;jj}{-TMDnBCXa2{DD-zsM z7!2G`TsU*~hJpkh+JRe}Ib)J*O!{&_M|uK&s_1fEu7~*`kKClmca^|{me!mZBjL`q zhO_4oS^-U>cn>>8u{|wliy%qGSuY;ALk{Wa(A!Y;XE2W8ihzX{SiaYK<|ZHBzo zNh4c5Ht74BZV7N|&=aO7GH_u2MbCvv#=@h3N0F#?m}>t27<=oeth=sj6oXJe5Rgzp zLXeh_76hcF6i`~aK|s1hkZuH|JER-w5&`M%Qo6h2tjqg;-tQUbd&e2azZvdp@4fbl zx#nCy-VY)%-{_;em;f;Gm1Vfjq4_a>q5QsHpB?FbIAl&qdTR`a+yQF|Q_eijOs4fy|yEU+d~6g%HNyjeT?1_u)sFWkYfH z?hhZcZ?nzUZTRa7LnDOz7+^1FVg2J!_cR${N7bhvERWuf=X z>XFGs{RE(ez{i5|$7hpQC`l?9EWnt=Cxqgx_0isJ)rR`a~>Fc+cLykLt z<$4D_!CE76EP7B!cUebEq=>vuUq~xaO@iXhj0RE&Cnqv8vSo+)`T3AU$3OFqUXDyW z&|R1|Snxgnm^H2pH~3?2*UHvr%BkghY6bw4g;Ub|7E| zLp5n-J_5d3$K zpKdW@m+oZ)VsGDrmN$PU662gVc5edhP=N!+uL==qQ$aLNvixqBlcS@Aj->AH?nXvN^O=`SbR~O~G6FcxIc8AY z0-UygeWe0F_SfpicjyTxtHP6-9}akpB>kifq*Jf$#d8q9v}R9|C<-OXC$J-XZ&UH0 zl*EMJNIf7P)dB4*3V-nj^rJRw*{P-VvSr?2s3Hyu9P8W?0#0J-mA!Ln!klk>&U*D0 zFEqq_lhnHF;rq2mBP+ZNXKVM%U2FZ$XZ1+;j)a#M7u3U{Ixhagu-k=3?&V~HiDhFS zcksG;h!?{x!RX-z;fFY+0`lvYF@xIy;(mr@3qd>y$yf|Ibg}`Dn~k#`at-HZ-XT&9 zI6lkJkO~U1QS?aO@NXQ29J5KF;L?U<}{)qtD z(c6v(j`E}ci9F(CrC|$MZQvR>&XIUzNvrE+H8k?(G2_u)hOr+fN*+!-4EtECQXw4| zG6M$9O!7}%r7}*bHf)#4c(A5|#DYnQ2nk0gCR%^|fG5d@ceC|0m&<(8Tzje|gCeB< zH*>e$zIitQ4OTewmmQLYmB+pf2eq1zj5)4RSLdv3SvnRPN5GsM^d%L7O~e&JXPt{=(dBK9&@W z92$VI;N3tzB$p7`yu}_JKyjOABwbo`iZ(*p-aW-UHc!&^hvu*<-|sPb_pGWW{?`c00(CL`xPP1NSyZ*3eVB(ZrJzG zB5o9Woeq*}(;;2%98oA?9|j5bY?V7~eF`HglF06IgDM$?_q|J}8sjJ>;Q z)N@zVK<6t?{6tYY=tf5$^tP8CP_upU8Gn<7kBk;+8ukJ2x^$blpbKs955qxH>U104RXUD>f{pvNDgvjExGNMj{alUM4`uJ+KS(FZx1;D}>@3~$t=n&MI$?p{ zwG{KLReTW};C_%5SSo05Fzz{10@Ml^6e2x>?&#>ND-Uw$LyZNiY}D=>j`mgew^BxC z{@E=;Oa7TMyd9!8Z0a@=bj=iND`mL$tFCWC7qo;eE4%aG7=HgVj!MaZcjU?R__xX-Qof(yQE3E^o zq`MmqY7}C=3~waiKd_+8pO^XB@ZL%(XAY0he9$aA+b^*H&YK%l!E*b7_6{Rd;1y{C zrJ+#k<%JgTxZ9tT@3A#}TZOA(yD_`JQnruT**M#Ab|;vsyC(IXzPnq{#WmW0`sNvQ zia*(EKuY~pYeAVfo+>+=+6`3*trp!FGtu}!p0U~%*Ex7lk(+spv02ewx zGXEhHj>%7?1!Y~yu$xrd9`Wvtl%pwl%gzRyKNHM0kC0!fW#7}+zeUx1)23PH( zzw&MB<#H91*3!5eos9QFll;eisB3}Ipes^q6sJX=`I1HbWm*f(l%w5@gH}(WMDy9@ zA#PE0(o6sYjmt{#YJa-0N=)GX(e<9s6{&><_YCa(xjJ4i8O~8!p`!Zwnlni_+vP3T&_h4zLge59gF7~? zIa0w1{onHO^Hj>t_Xk{?y@!{|=2X^AcOsjqf;?yIS*OG?0uylW&vDwH9E2xGPM2 zNDu@Z1CNTYHbp<6)5$hh-@Pj&DKfY%Ct&Sl!da<wvW5U%yy8Q^F=*#=-Nk6v%dw|9iYc`yJqxOQ*=4t$3P*bqLQCPPcwhv=o`4;+Q zx$J4Geow+XV@Huw$CXzbFsi+&zW++dxjW8xaIs`=f7&gOKG-f z?I=mGUiK@O_G!S8!0~KQuz<~tjwu7(7SWh;Gu59FIu+E{n8g{bspCXl7jQpMMk7!A@B(wI%t+Rn2W4BMfOEvyG|9oGpi#oJA_L{0 zqhFZ7phf%l=(pr=Q$2lUU_7rs=&4889yL`MA^Db(XR2vRLI;;f#3IF7eOz}iKBdo- zARre|U3Yn+J4MUSzpA!DJ33X5Rd~mz?vqwMk(cZhxg%258i7#rp~FOvo%;A$Q|q?Z ziCLF}ip}9YhW)MabAGYYRQQgF?R=Yxz5MGxBkV6H(w<9cs>>(Lo=S~08a@drt% zXR|g|#S3W?!m4G)eYH*mOh<7aJley(1)OZH)<*^3@6Uey8m+!DQE`@;SkB5>Pd(Kz ze){v{wc3YvzkiT_`!?JqpcWR3EBxmbhNfoiQ-gx})x6-?+rb#{ZBZnN7lI02(I29< zhcriQdta^1M14JqX+Co%2EY<{PKa&-REm&HcMX<3S=U1p8Go>ad^mjWPn*u>E`Gq6 zt=+~oezStfUQmpm*KJ!_r}S#rz;Kpkpk&TmhAoX9k@-EY%KgPpYy9F+$gxMzAD;}1 zbh2mcB!OK@Qq8R~9Df{o@xlIVpT%DW`0l4XVQ3bwqmbdp7U;)weX z@_`pfUGp*P)$$WtMh!P{+$V&##PtaQbfkT6dbgf*_il3c-B|9=qh~jD$|pX);ulPk z2u^f7B<=Mc4YTNBIXRt?s+gQ26B1B7y?$TZp2c?kA!h~Zw)SFY5h-c#Y|H6^HM8cl zvf4UI*J_oGwO-!(!J58Li}W;Md+p$j&)QYV zgG)w>siZmqaIFrH9&MIY{jy))=TA0@>VvrS1kmIQXbn{jYS7XZg{VMf~cI6 zwjJ9-E-698dc`sAm8To`PYD@@?1xvnpk4M^2ruF&mv&VVOOZRyapHkr%n?p3|UuQDnNst8`9+Ijiw+m&~8?+>YcY&Gk2>6g}cmd1w z@A*l8?y*rjB9S>CUt>2VCKINRk*2;zjgp8Fb(!UNo7t$j-fnBx?UEab*?fAk-s$L- zeP7PVQ3yJ7-PNVZN|XZlkz&Q#Svx)baS2Vk&GU#-g0tOp+OlwR7sf~a;^A`3ubrG$ zuyV6^KaXrz`y}p7*~ODfou6u#ZcbH;d-OKEQF6o;P>Q*KS+aHpxBNVE_56>Ch4PZt zUHYO4L0XRH14^B5Y|6|jf9jTd1$TGOm)y2slvYR7XaE5TJv~PVkB#vgx!LQ?NwFY8 zg4di@**oy5E-7(l4?eHdfQlOW1&{u?Fl|juS8uHT>hg?*g}Q&_>TKpJDV)=K@$F-$ z{)(tb$5OL1feS*r#OUcJj|A5j6O&PhHG zk>x4$uBb=oG0JJMu;GsJPa;J35P{(MR`Gp}$#;9F8Xgg2+mn-|4HI*pBZtu*#KvmF1HbmNet-#4 z1MX5E>#G=PqY#Od^;R;Ov98MWnK!N7>vrgqNU-pfFkpP7c~5Bn9tKZ9rYrYh{nZ85 zeGU(#Vk|*vB_@@>jgabrr%93 z>2$e$1!{xNY*nFm23g+?dV7>5CZ~ zWdFnCDUQcdO%_?$LaY8+bBu2BQ*lApY6x6~HmWMz7t7{sPxA6~ZwN#uU{>_2Y%Bu3 zbXmAhuk27v;)M^xvi|e2wLxD76$?gt`ZwK^-!1FP4-Hq`5ceTfv0q45>lN@T_GniJ zny4Z23jcNq@T6&KH0I(6%o7M5vTNPm z?!v$W^Kz4Vjao;gcMmgDn${M(E`+@=88A=J1iUXjpTAGf?Hp)bGAhuR>9C#8bF+;v zSi=~0ojMk%>u#n{(ys7$%pvpO&a1@!QTTM>k;Ynos)5U0BP-tb*|tUQve$T=+uI|b zjQa+#kJr12tPL}!zkatd;WoGKT#(d&9E5aEY}9H3Unh)=97*4b=P<+j!ZWr;BOBC= zjv1KT8kFa4PEm8@O;#7dXj4$y{25yaLkLla>~U_GTS3_;#peyzr8t~2G{#h47Ge4~ z)6svy25hcg@01SXjo>h!HjVv_iTGyj*NO|OXJ>EhLqoOb&0jQn{J#BQ=KIdpRtsyu zyo>_vd>K*ZvZ_y0@C??Noku{5%D)BTGH`@%FVz@Q0_Co_K0hlvrc(|hr66Q+yD4de zJq2}pGFEj7H{OlxLTsb!rj~xBz?v@iO2>HHysngCi(YV;`%MIXx#Ct*LQ+~PT53M^ z3f|a$dFwbMecGq%1kznv@jPW79Cfy8RX)@&W;Mr538T=yy03BdC;w*3aw-6R6oJ}dp{`L!Y|n>33_nikz52)(|IG0 zj=vdn3^NKC?MPHiPZ3zCqBM?A*iTjKU#u~}>^9_guUucLRHO!J@9hy^tPyK>=diTz z_30?y15}F16I&bG7}MhEd;F_kmDG@Et8Z&WARy@gLoWp0@J>*?8(4>=S2 ztn`zqvgtA%q>1Kg1x3IzSyG6ASG4Sbtas4CJn{9bTE@@lFhY4Rc?ZWJpjbdlI+|P{ zV(es_9=e&I|EQNBf^H(9K*o)wm5DanXfez-9$1jxOGX_rJf7 z2v;KsvaWej~#ZjGv|mlh)1hSiC)iz#tK~9dc@HpH;-z z%53!V|3Jh49_NjY>|cmmzMkwhb$i-6KHyix5HmV-Y}+26V*Ohf=|ExhU39)=*K=c5 zuW3>Uexyi{YDm)BV0OwYR^j~Bb$TC7JA!kL4VG1ov18UsyiW|bnmTJX)!8<csE((i;H_BOGD>b4;v*@+9xbu0W|lCU*uwCezei zXomX!`@Y^PDJH;GLnduvs(d)|DAj5Kn&N)RH;6>8=FTmi5NY!p-)Ky`#rzFuUyP@n zi~ygrg}j31*9s8(i6U}NPjB~s(c0@YZeS3+idLF9R3V&PoOs50>uJe{-`~GZ+D$n1 z?h=r!xtAyw&tJ>nL7ZyfV~!H!3j@`49vx$Cv*o!Sf7vGoyEdhT@2A}QccYZqY5!vc z7I|~YcR0_KTeU{6J(yN!YbB_8ckLYge|kOtKCFKmp8+4=QUQ$rSnAh9wt1TOXAwYt zXnX7^t)|{=#_}nEHU4ex)g?B?&l+f-xkOVQD^)+HaPNHX2aH+#5AiV@#LxBHWSd=( zC2&p*xK~ikCk)sO^OJH=Ofe8GA92#@-2K+Ecg7Fl#2bVDbHaaHu!!Tdrm3O2)sg)P zap_^u59ZpW4i5MwyKa-e6*B-hmeOnT`7#n&Q6d=zoE5hQKSZB$Fbo*f`38@p-SL>a zI=cY+`Hc@%ism(3>o7PdXhQz`8rHM^LEl-Nn$W}lSweES!X~;Z5S9SO?Lb-}VhQzE z-H6r$YuxuL(W~a<7a@pt?^M6Xj36Z_J7B9zwd+~X7SL6YDJ*EnfOm+>ivXJmplm?n zHMSR}5@i?Wn*03C9s0-tX#k@-nEf15Kx@a~rVWzdSoz$^%w1m;r9b3HrxJcW7UE=#D^w&3_ z5l`4Y8mtj+J|`o(@PaD$cR3+>{@qZb<)NHkao2&r*8aE|%1M;O5cF`w?m-a-nv7n9 zg^LWSp*@~Y%Tu1@7%L-rV+pk{}QkW9n$W(Zcw21y2aS)wk9LgB-Q(1d0 zWkoG$u!^#R?&i4Q&7hfZ!#?ju|1mqOpGIwVTU*)vLZ1LuHED-O6+@3H+Kz8A%c-ku zf`SKNIRwcUi#BX)^)*P>Li+T>5AQuGqNPoqXw1+~_5AzfnlcdYYq1O4`w&;-t3raI zhF9oIAe9f8v$bWNa|Nj9BsqnB&1ax(wr#Uw{qgL|3A;M>?Du(fy3b~qKI%H>;r25FcmJ3 zFY!GzEp)%k(Xs9Uo5uHH4t34*Ad?V~K>t(L|}`-5PA6 zaVg`*zvw#MzD5}T7Sd(ba+JUWGM zhy1~Z7Lbyj%(dt~Dg>hfa)tlJ2IIDy2A?A=@FvIuK|rIcKngO|<9O+jMf*$&7UI^CSQr| z4J;1(bp|~6EJuj)IuES}XuBIdl zW}dq7A&~kqXEq5O|;`kTpjuILSjy;N#uOCL!gR~-vdikbx~KQL9Mu}?HG|aoqZZm4f9&JAti)OUZ=ToE zP+;z}p5kYO!;(L-;39BXWFd+`tuHgszKm>^7H9ZVcKjZMRdA+6N(msX@kvs7X)lq! z8-GH=u5CdWMkJnpokM+F)h;ri4qff?qcrVnWqR8G`xXE9Inqr{#ygq?sl7;W!TBC< zcC`64G5lu+sCQu%FdTE9YTu;$VDw?5c+dm|GP7?5CtZ;ETVz!3mR|QxLv{q|<$n)X zGWJ@=5215SnH{q$3AjX#pJaQ0zSQD)br%JVU`p4~Q;geKqry&q5Tg7?M2Dzap{V`5+1OV{hC z@PphA(7#amGJ}5Q96m;G@VD!j!f=>AN#oM?5_;n&XjL+ppz>BwlwKrv5O>tldHPO% z0DrIP|A()5y?-wVn3=kzW1f|tp=V2zYAnORacs|ZrY{6C+FRoe5op;fo+CLUA~QCp zcVcIv@LH+D9mGk2JZGvB|JenZ;}PW1qw=O-Y`+6^E;uUxPnz6xi}@uc6~epH5JrHS z_)+Ta!%F4iq^|+lMG&k2fNg)g_Zg_5w)0GP6=oo70y)pmjitNe4weocSoh~Focy!jfu zS7(Kw&rfRnQC}l4f(#=zY_ggJ)YGSAchWB@Y^f^A5O0iqo$xVtUk%akURTI8e&Kd? zJjo8e^0EezA9!l(_&Um#wouqEh<&_^OkleX%+F##ppW+3Gs-jT72)@TFmNI4?p zF*Gf`z&hQ4DFdvju8^LO$z1m9+Ux{1&Y{a5COFqD-DFocm5f_idnCQPe=x{^pMe^@ zFtLF)y~nxa=Hc5N2&}1fF9rkQqR=CRvli8nZGAUkDe>o^{mDh1SUZEtBS%hQ;`_4p zEXBE-yv;_uk$ace7m8f^Tt)Cbe^k zN5_C}CK`VD$W@2!E%vo!c)?Gmf75Gfd2fwkYCghI3MC4hotq=aMoSQIy9}{OxJuh| z-WEEJ>U_t1OguN>*~5;Y`J~N!{$AxZqECDVbOiB}IkY}tUL9{& z5+q`HqpXQkTLxcN3hNJGn8lLw$l4G6{8D`C+(yye+N|NszP=I`uS?q8SB{Z-I{4*{ za3n_v!($FBK13l#9gshlXv*CgIvsp<8A9-^jOyqx4Ea$U838!nwHQKshu;pxw+?QE|?G$#%^08x2JuIPSqc7;Nv~uCPmmX zuIR}2sg&)NTgO44+{MVVYmO<_Y(Ku-Vn+Eg!o?rO}8MP^zwp&t`ygpZltOnm4Zv~AR6prWAg!nHq8 z2^&ubMlY;-MnS(U?TD>TTjXD}i3GFhN!)cj=|1u%Jp7tJW950-+Whj(g^2kJtba~k z5o<%mY2BXBC7CuUT%9Ap?|j?;nO58YNDUBx}^?~L}IE2gOljA zZ1S=riD3KGNJE*`@p#VjjW7(q=z>{_8jg5mvyTb5%>_YV*3u`TD|(US@~gew-HVQ# zoZO4CiFndMQ#!ymAncrm^|pqv=cJF#|5y-w#HC%f$`TT-nn=>Q%Of)?&^-YMiNla3 zY(o3yQTSZ(gG*&O(|Id|H+3OYZ;r)M{&g}#=4IA8)-`1|X;uZho2%#N)CigALyC_j z&vP@+B(6Y+0<~af>}6J<3jQ+r~dT>;y3n467hABL$)S);``- zTeb^VM}#;O((2ETKsw*{7yxcX8zYB?40PbI<0LAFIxJ5C4GMausf$N`UWxXz^_RKp z_1iHKobnx09o5vp5wcVbV!yDBf!P;87er9|uNv4p`s&&FHzMA?th)w4N(wG0b*!h) znn87A#QCuGX`6@>?}y&K3yOAW`3ra$A_ljxx@Mp3@*1Y8I{r`_I#PBZMrnvU@_wQD zgJz6;Xm7@zALQb!<9rAWgyUxjg&=*jQVjq(RU3vEy{{AtqS~@-$_WKccOL30xAY`Z zYiOtN*5h{_B9K`FBbim$4A>f7mROM&1RBC=O8gWcbOGhF#lhaE^N)scqu_vk$o(W? z?{w;-#qiCUqJ{AiFnJ@}x_((5E}sn~YY!?$(8ez+_NU1TTD<>k-Rft2HrpUX5I=dJ zJY9;@t^xs5a|EAFx=0W|V9k#FAL$!2Y#9a=u=?R@1k&W+6;Zd>KOag10i%fGkS>QY zJ69Of>vBhCUP=8d?@zOD2evZnSxhMLgx2 zbjlBhNi~NtRex+y`sjk^{v=Vf8OhH-ztltpTq@Rtq z3Kp>y>vj&b6y?8xxHyfIGlE(lSpSq9&&40bJ>|^YCT=ri`=POPn)ggtbm-N7Isp*u zLgW`cv~=RnKI3XgU&~CKjWvQ2a#s6L8ij=4pWixt#yUIHk!dmePcd^Dh+3A?irUS8 zWEaoBWW_@KmKczcGS>?CkF=xM!qL`+2HwY{shNM=(b(fUpICh5MOL4e}B~_M2FJ&F@_Vc3rUF-r63vZXPkswp|Wc-Vte#cz;CcU z!I>7Y9~f*iCrlQDl1&O?kJW)rPS1MAzg=w2F1h||5!-TcB9ztCtQu& zkMQU00)6ly@fUv+748q<9*CUUvs6CaPzBAaXmrow(WA1=Exq?mQgR>ReP#rONl4om^YiEI1{nfnDcLkUxaPA@gkvOe`^`|9t)r{*STjF%3ZucX zL&oPh=mCfch-$<7^q-g)$VbP^iVg(;#1F2Go~)6E$Z*7w*c(H}zFo}5QW>gun3RBL zb4g2&9wL+;^Zl!HUdyQkKd4E}ycuXx%bo+tR&+?T*qx+QxGzd0gb1;W&{ZR1p=$xy zBs8WFf!?th(lW`vAr3bk7KYq7G3%A#_RcmBK{NcB!>8->ta>>xSZbBetdAYqM-7#& zn^N;Nk;F#!?$6sko3&-#&!R2ZhY=#@-pb#TZh;%{yzhmpf%eT~HO#8H=O;wk5F%*= z!_P07FY&zX#R~o=TvFTPy$G09U>hqas@Z&t`2^m-cXD;k;bGX@NX=p@O_<35{zh-D z*7WH;A<&9)@};6y7Gj!8=ohMJ8O8yNzjptQV2$k}x{vc;AgRUx^>gLyba zol%`-b}?^{B;GzSy`dT=f9O};&SqW^y4@Dn`5g8(h~zppa1&swkQg7X18mU&-O_K` z1=bgwag?dXKOuKgVtR;cvr{=!RYkK4R^d)(eLG3K(VnzhQ9j*Ky?j6y9D(XpHsFBN zY=qs?26iy=f>rX`L_?(Rmp}l)rt~+;NwZpiWqLk@omnU z`R}L`n5srF|0d#fwiN+PyZ|?d82f`#ouw5l&442k=iIi%&fSH`CJ{&b67B&AXW{aL z51+2{(+c(Gn`nt`g~@vw{*>C1n-mZQ6ylv>`4#LMXXPKHu)@1lU|5Nt$qQXlcpzz! zNz$Iz-inAaMZ2$ND#5DXU>?{`a@8{;VitKl+dASAp3+N2W`T!(0oj27kqBc=Q>1oA z0Uw^%o`~oIOUC}2sEvffagh@gd{9U-08(DkX95Clrxkga)&s*g+WC~^!bu;n%M0@6 zgU9W*y+ySL4~6_-5hgb2keYbt4yK)@$pLN(igbiQg&kPjLfPLtQ*_l~2X@i?67O%)(&!)0$Ic zA`iB6jyg_j6L05VZCUrDRD`n{%4z%MZH*X#2iAeU=ihExMuYDQQo~}B;+pJ_W~kl= z&k$p-;4rlFSHu7Da?(wwo8eZo;l+1f>++(Gp4WK>a7aLOe6mTMy83s#7h8Va=X}C0 zP!a<|pt~=?H77y%*83 z!FTM@-iRX|RAAWTC-=;Hp*U1i{%3&|<0XsLhxnrKfNXE5TtSTt(MT~$T#3r`T?A*` zc1l#(cRYx$@N0qRt2cuz-Gv8oP6*2#16FMqKebJQ^B!{H^V5Q&XY3+G8sXn)$yBRl z(UMQUcaKINclrg?RXbljE^~Qe4j}kH;l9Imx8gy0Simqutq%&s;p?^gSvzmSg|McZ zB7%)UR5+OHEn_6a6W#bScfF`ZW9fdyh`6({gg(N{pgny+kNE#lKw#wn0F3AiNkDF3 z9U%mt8^jIAXAI8IB|%64!@NTKRNgoF*Gc{vfD2+b=47$&IRG?*RaL!Z`UxIf9&v=Y z{uAsDM^l)F0YV7qnyKM*G!0?jg@by5%CH6pHGTVM%ehSWLhLQ#eA?#}2Iqe+M(COU@bsh8hJz6vAiq*>-EgCT@} zPpcC|6u5;apZW;?%*`Nl_^KCBpPs~1FFAUJ5d|~_k;cBI0*N#kf6(6=46#I@9C5^G z!|Ne=v-M^EZ;}$GlFC-pL?S+i=bQ<_To*n8b-a)l8tI$se%U~z)F=$_eo@PaV3q=r z3$Bbki-d^21_UXXhv>LMLWiMP9c?58fNQ-6N-8}A{ysP=D;SbwO;{Z%jfIPdJ6~S* zn`|YKlkufW= z-7#4L9u8eR`6sn!X)4s}8DDqsvxxhZ{hVGG~Lp(LZUPBfLkMUzK6t>;(#AGcfvTMSV1XhBnH-7&_O&?&2on+B0yV((_!7@q4YW& zg#j8M`}_@^+b8v3|HcEkaNY4U815q|dKX!^TJ{6B!(tIM4-m`y@SXi|bFtp)=&(e8 zRS{Fp&fk^Rfd}E%fqxFLw)V%!GWJC;V9*7~$lEXUTDK50ZN^OBsH-gkl^x{zPw%~S zJiLkPWD26+fC-Zy=Xtgjb%?{h4fxN_cmOUU0a=!Qxz69`3H_gAAMzh+$c;q^UG_3B z==8N0)@5%13-raZ9RX_vO{qex5m-0*^P^9orhx z$)Qe>0Rn{IEW`?Ll-EU1E5ptvNXmjf8T8kY=rNY z_atm_TIpL9(CI6k2+;42VeyA)KhE{yP-S0r&qlooBf{gFYf+)lQUv@PG{`Xe)W2G< zGuP=NhH~}%HDW9ow7oG-wIqWX7h~Lk%#gM;tcwEP$1}u=CH>43JFNPLff8aCLZ2Oo z<)kA$$cXg5Wq;BJT)G9s&M3`-67Lbc&S7Mlno;JCJ_KwFg&NGBlf-3fGv$zEvGTl- zermM&nh!7V@)-w6Gw?{k(4;`s{r6CXB*m`40f`HOyb&&h)B5zM$<7=I+jYOBLv2FR zS^(7%s_-CWWV)qHTyyD6V20N#G+8c?RAF?fbESPUT&yA#1)#$|i%kU)U(#0*W3;MmD z^v7qM#`mUZOvgLY{j<55@Lb6A`Q%iIgzbs>D96m9sgS9j{@&HIrMc(?CmK^b@5-Zu z&hEm6!k%4W_M8l2(OjAG!xZHN|2i{`GmG++*&%T~d%oScBd3-<;x{CUf4ny%7Vh!L zj?VMBQcfh95jS)Zsmcr8=Vjvw(s=Xbi_8QP{8R9Y9iTyy3sOK8m=NqREN2SKtBw1a zpQ&s^MaMYcvoCymfCEZ@s?C!i1kfdzyO9{(9wofn|wB-}as6(;} zJ);`mFQH{uB^aJz>fA+7RX%v7@izD9(r4W5Aedm(YWn-17naK0W?7`SHRSS|jt4_r z-bnLDo3g!YACPifwcH4PLf>QA>A1A>K+1a8D7OEb^Ut5%A2s|BmG@&(W%Q)s2h^dD zW*y8gGsb+5Qs8&_9aV^X_ImyAHL3E z2wyYGP(Hx+*b|2iHPj;8u!H=9a@oat9cz4r?tI9__W#~ z5o{S(TFtPW8ut9GXiuufJ#}r+EUbWsTKW6l&WPCOoo~Yz1PW?(nUS9?<4)x8< zhqpKKGHvfPUx#(&F86OCarrR*?pM2RRBp>!BV>xgl&<^~$9km6?B|`Bg_1Zic~c_Q zU>vZeUb&{u$;_zzb(Df9#=QLR256_BZKu?{U9O$~2#0YZzf&sR_=Q_X$H2R_UXx{$ ztLQhADdJ?$(>hmhk=`q9cl+Dax;dn${P^(aFor!xv<82}|Fq+y{z(AiXd>~qo)R^= z?dz58Zjso*J@#2Cx`04V}Zu`(Vd=f`kLzuZO--Q86xAeu3W&_UI1Zk-bpqnYf!W zi|j{1$0$|&{z#=%w!Y98qJWd{_pU|LCW*p$a7 zg2!qO@)B_k-DanEF7Q()Gt7dA%C(5bec68KEnJJ0iMEMN*n8|(-X1GtU|K1gl6Ts< zcWfkUWPa_hCC<`(mPthVC`L!en-kP;x?#^a`M_l&PJc*9c=aPOp5wCDQLzVj+{gCr zyI&UWiGu0(k0#A%e`$?-W_i6Dh5tbjJ1_H4pXS}2Ak|7hLKml{6CxK<;4}y(+WDs-%=e~g74Q|cd6jK+~xClSq0R-SfrlpnEK z<%r2c$E$fB;Tc_dFQOo7#JRF({9caPYbCiCyo$1{Z0G_mtV8k-l1tG9Y+jWOa3LWD zH9YxICRcx#j+tT@o+En>Ay>k}JvxCq@vRmCl@=l;NULooeRW{+?5gMzi<{lJ9DNK| zF#8Uw8uG5)*A7J?fghvmWDSMYlV*|QmZDsT>kp%_vbzRonq{B8k1dbaUqeG?o{j9E{Pfi+a+A$&wSsVg z%XnkJzpB8V;)cFH-K}=^?$tp>EUe&$hK9DbwjV!!Oisq2e?dYrMrp<#5n>d3d}Y&$ zaEQvt4Lb}4avPR}RO3Q5xiFbYyT8lGV=QZ9zoHC>q$6e#cq?1I9X?>0#2Aw+`Gg`Utiza z+S=e?tl0MS%*=3ERHWw{T7P!v9u&{oN50A0<-+rq=9TTbjh5+vbf7n6 zpy9Qo6O)I0fhC%~J%{7BZFuwuAAUhHYJn5es8op!MECdc-*fp|x?A0*EW>3pzuLr- z?yrrpFCj_Xt6z+cZoB#xn6NP}uwNHVZzxcwz1!!?H=$1yX^>Yckb+Mh{c~!{X1>t_ z)yvDvl$wB$@axyF;sV@ANH%Z&JfUJZaM5*~&~Cw>D#%~hUmNT77%?ixXK=boi(?L; z4_tU-%~m6180ihx>Xr9&^@!{Gb-2p#^#-4iixJa0RnuOp+>sQQ;3IXHmd^EWmF1Uj zO3IwNho?Wh5}Q$)=+dO2tNJZlUb{loQKB>~W-In1N0>FRx@2!VPqkw7WjEY3jOpOv ziE&kdbaC?@@+VgLj|H>YNlU>zQ<-SPW&_o3$~}t-u7$VG!p%wol3MZp6l6XcpNyI! zkl&IUxtsljBRT^QskNj=sH`0fS{eDKadU{;f3MBz9cqHpH3^9TIcom1 z(+%dB1xD|?Icq!A??a%@5S-{4Fm*|uMdnjl=6_rVbaa~Z@y9ICXzAxe!oScWG~U2D=6)A&KPhW;L*c(`Q}eP(6}l$v zjp@cW$f*oD+7wL6Q_v_DVNa7({;%`^!m!B>S9dTzf zVf4fmu5t=*HiyV9Q^q>m4C)YU-h|a>VOrfEY$Rh@0AHN>G9J^$bJV=j(2Y~BfM_qf zSz`OF-bk{<8Mk2R-9eZ0p;5mV%5%8qfX>cW@gHtJGw7345^2ndO&c8ApR$XE0R?Y7 zyxR`78V~gZ1Z{_{mb#O#-EgcwGamqHyZKmgQep4wa@iZgRJ#Ip=3-mZ>aiRynbu1| zVnOE=#tp>smOJN_%9%1|EP*$WLjIrD-ZHGJwOs?9ih>2G2uO({C0&9v3L@Rz-62RL zpn|ZJQV@_vx@*#@BF&_`krL@{=6R;BZ|`rP>pK6=`nTq_7Gu2i#2xRr+t7W#Z;Wq( zuASwq)N6M!H+t->4^K9RducqSojWhyw;6Y7pq^*RY->P;n1Pr=bayNkhbaiT~%t9BXFXCbdo zv16$3Pr6oYqE^R<3pCheT_XFwYE(J3?N9A*?$ju&%UmAn|8Xvl-Mamo4MlFil)@%0u5=vMhCWosLA;f0>(Yu38-}?eF7{PF%lp z!;s79hpT$Q**#A)Z|52{SxB7pX$+{ybWIveO`l|=a*qGV+ zu)KfxOB->$Y5VyyLEF)my;W_J+ZK{xAtCA`SJwtt3HGoSJ1Gj%N>vXr@yU*=;lrf5 z^6uK{)5y~oLn!mvP8>?_!qc7n03na44)h)2XUMkmuith)j9oXA^u851f^0rJ-CvJD zw?-bdN6AOnn43J3i{V=F#gCCsI1x2V52tSRzRUmAb!~iewR|cpt^u7TTB8%NI9DN; zDD)oJ5Uw-mKso23Sa#jc@z||c5BwG-5*N>4W@at!N!_9wO83oJj9;%`ZxCmRtan}( zab^vBsuk0asfaav)xbDzZb0fu?X%1cW&D@wXi4N&O82bhk#Y7lZe7D|spjqSkfP-e zoqyKY=Z`J=_qgwj1@~=UN;1ujVt3vp<-Sol_uE03X=`GCYF+S`=ZKJv{vH7X9V63l z_ScEiNGEYVf81rbo?s!FidB7xjM8i8HT6iDZ99#0`oXcV0YP#3qzBTxtMl78SQU%z zA#kp@m)o7*h}D{3tX`j}wi+$@XhY1cTIIT4xY9*jALm#!^0{b}q)cI?$hh^#y9TT6 z^8R$u2-XDI^@R=+;#;W=9>q@;HKQrVa=>YB!_l_zX|~A=1ReOHV^Rs2lS4$}?=%|J zi}VzUJf+}wHKOZ^H}}cu_;r!gb#)@|*;GPm#>d(+hk&98Q3QXuu$R@7ri+rf+C0Y{ z(YEgHb~YF5TvmnavkiUP;SPb}gX9d?u)J2r@UY-uvc)20KK|9IdLNUqvc}Spv^%V? za0M$X^Ur_V^gi_{Gz@XRD||RWF>H~RJ3c&5OSb%eO`SL+);YcG??tnr|!mRt*G zj2F$&18qW&`P`eIh>4bc9%+64C`#tm=-K)@X?4+3?G6+WcTzZ!w4zSm6M8w+RCXHv z$qXGWahGjdwy)VNk78YI-LvILbu9j#46`>f!eZkqYsau}%E>9o7&}!+@;PzJmr>pO zcm=t~L_lfZxF8Z%EuES^TEE#u_VHs=*y@nJPrPhix-6Od;g;}J3={pv!A8UWh&UYd z#>UeZOGNKl!+k2;9HLBOSI^FlQP!}0!;f_a0$Cqy+70GPiurwTw zVsFKz^=cuqx;M3zzp+v8e^#($iX?a4Tq5$+zHXP6jK9QdM?#M~2rKBKQp0ura3tr8 zc^|3f#YEQ+I$dEOXNI$swI#z&nIAlGi5N5SjsGnz?KL9qUa23&LSc=RuGL2z2M%*v zQwbL~;YHlLb=0y(GlBFvR@2n%w3!{@R9>1G@b=?4J!u~AUgTn=gM^_Uey_DaU)a3m zLtQLS7agU;Ja$NfI)T~3;H=&R!m4$D@xJq^UBT4o?8n86TW7 z9IK?3^r2lv5mw_qC#Ub8s{Tyr?D}$8Rz%7CF@AT#9YW#99?5;Vngm-Pk^+fc^E8zm zyub)t|5>CD3;@}hXJ~5D#=S051!rqCriH%KMAIP~nc5pCD z)LZcS^g^V~WR0fc$EcktB@#G*j~$EiO!!$k!&dcT>(iR>RO{T}Z1`e(F)vx#`+(K9 zYeYOpjZ&)4^}*Tx6`vwUOmC$l?tkxbY)`TJkD9Zi_d3e#jOTBwyR)Esf0I|65go`{o08Xoz*#9HjL(7pb0Q{gX|?eDstA7-7x zVEpYoYOEZ;I9M)z)Wc))BXz*FCC2OI=43u6o7*sM>Q>k$>StAs=(C48YN+e=xk;^q zWp$@z0rhCCB^lGk_j!^G>m`myI|X3{T!ROHlMrMX=jFk-VRJnxWN@)hC-X!7?&GtSwy@c3<`L-I{vB)r!h^t#|!EjyE2mP7;3QU^cafy&zTKyt=40l$vji0=H zUN}AAS%jw8Q%435Ye+BQSqVR(xn2DzL{lE=nEWSkgoW%bFBW!r^`*O~l7%#AImQ>O zIuM_p+X!U4{|sOrMN1OfOuY_4=`Q#BJ|-XN3yRRDhH7_gr$hfijyf|d4_>~a_tn_M zjHtr2{M%r7YS5n|Rqyw3skSqTWT96YCEbsoTl0c8F@(hCtwfg%4Y57>NTObqDj~QQn_SsyH2fvPriGhI!G+pFMuIs4>3>F7;u5|E7H${CwkZ&a!o4 z{g(`t+9wSGJ|X11cezxcP;PB4Gw-xnhTPsd#qrV&J>{+a?I`whoNdofK}bfWhuT&v z3iE-953O@kw;GKg)wr&y?2ro_kZ~^>_fIPQz-fwXaK!0aInmenwKV&pz;nN=K!1wP z^5}4J36gtzm+MgPXqDThiDYrx#ltcCdYVclw}EVu*RMw*%-L9k>*Qm5_2 zO)DRfSX}lLW^8vKDW=q~B_^wf)%_ekTV;k~`m=aNrLxnJoPR@8ns9oXL3ko09Er7= zMp~_2I4$Qz1U2^cKP}vpKn?&XUXC^-L~T9m@M4UT)V7Eeet)wscr=97EkS~84(D$j zEA8CNeq@y{^DSr0n$>w_w6rRSdbn#tf6!>TeMF2E>(bXU#`TWIGGimA;im0Hvxb0u`_Y~F1VMh` zmj~waQ^|Q=xjyIwR4mVO_m|zRd1c1LrrU(3d^Q@wgNd>in3-5q&PvqL%nw~Mw;El4 z_m>sZd6I-BoI8i_xxdy%8x_T}YE~`5X8_0M?qmNiVgUg_tG5=TUze{%c~wa_QCLpl zQqoVLsDE@6cR6ufE8-L;qlkHE-COyh`Ng7(%0gc+IoHF0VntEWSBfzTVEh}jWSF+ffAc7#i@CGh2WW@&Z1gwl_nky) zsMs(q(gzCvp!$S#&)<)-Zu~kRVLEiy9GaYnd1ybFY8l=sSj9A2{D~&**iBd1{&e-) zHBsDa|JCWLD%sSo`sb#O{C+3p_l8y!Y+Sa}zP)iT0dbRp{uWD~TC*b7HIW7bHdj8u z)PbEHKhCvs?*~`O^j^Le!E9N}a9(r--f85))hFEld83=QYs=o;dQ-Yl{g?D8_Rhr9 zCuogsTe%tdSzRLU+PXp>fXG&Yz6z+F;+iL;3W6zRvw`897LoYL_OaEnV{%9VMLi9h zQFp8N@%XkMcrX)TVr~W(A+K?fA)nCwB+0W7NatIL|hR^sb&P zJUn{cRQ&c8L&MLaXx}EKYod;q|7*~10RWZea!wohJ@T^rQ6JqWv%{~NFO*kA$ztZ; zCD|?t5U&7uhv{(v%ZSeGm@@5k3}k1#@J-&rR+?6Waxi??+_SY){kkf4I^@Tj1Gu6g zG3~hC8cFMl+s^EJ=bG?HrP;5wGO|5+cp=2x{cUonD6m#nV=lgmN+7Q#EL03M%UR@e z)`rZ4a!g?3R7W@T0MA$Q8o&7bcesa{9@Al70Th2jBZ8B2v%OXGYg2raE}f>X*In(o z>}!KARK}d|d7Bit5+kBbe!$Lf4}LbB|fy*V)RE z-NJ&PQ1si(EKH)T(tg4|T{AIyullTntCVAFr|;c+GoNDHNJIC*(a-j5fO7qPA1iYI z+@nsmLywq&NL`{g^}#E5ZVPiGoqAo^>t@Q9UEA%`jREE3O1RMmTudd}h!O*eeQEvz z^j&7KxSa-owM`nU3hHIE) zQ;-m?>enJXAW8SU-7fYVQkKuMuyaMe48=hh+GdxFk8fo_?}W*%_iy`G5Cxn2WmiZB zzq^X!zJ^(#C!r0n?tf{(4?nq$pY2dwjmZ;-6bA%f4^#QPa4?S*&+AZq+s@GUJT`eB z(M+$o>Hj?VVOPiXE0^BN%_0zP7XScG-V9P8)VI?1j58y{#*E6L+0f9Y*f7W8sbp!b z)5Ro*_f@&;r52PZwfiXEuinF5TO&uutftj%^GsIw{w_M3Rm?yi4s$gN!5oj(9PYUl3 z-Cbp(9HBIm8S5i{wl@pB>myVCWoYf}x%qpTN&6g~MQs(=6hU~aahc!mPF?goCCjeE zIYcJeHBp^F(r5I}Mq5j_4kueKV+QiL+0aEH)xi^mIk5-?hm3H}Dv6Q`)h#ZPqbE%1 zxHUh?=Grtb*v=%A8IG$FX^*GqNM-^!5TaFM+=)Cb*O zg{JZi6%V*mbq@jz{xyV1tpT9dDm+hmk^POsov8J6-_(DiHpM zEhQDV<-)LJkvYR?t%^afn0Wz6YESm`Q#2bfJ*x}{r)Vbi8GzAMY1?C$8z>`}%5Fbs zt(H41y-OSItpYIarH1POiM_?PlVWpp85|cw;=Y>Itm}~o5k=U&_cB=Jb0$NnHNb1u zsf4#*4a5cTJ}&MtSq1Y#{#(_li^;tlqe+0$o(nzQ&S~MKQ=%xnAr<&fA00!wgR#2M zflcyWtZ#|F4{wpDSCT{ZWgvieM9(7>^f9{-9i$MP(*0Ep4^YJzTLi?#_u|gv=btM( zNTq*!meM$1TBZAG`BUCy@lLLGN%noF`Qscs8iT~QiesCa=dvq@a50NmG2$mhb)wS9 zm7m;6^T1iv1}(ooK^e!zeZi*ty+B5|$xH$< zw-+p$c?5LZsGbbo39U(zM#jx?twjMV95c^dzQliLwNeJz2K4X7?Z51Y+;Qv({?ze| zVS5kZm_1&v{X_1(FS0;00qp_blKJc$P2?^Y;B5etdlAmV`M3W6!8gBN1d{IUojOUR zs=MPHhBM`A7kqlz64V22`=feKjTyz-3l_3B7CQfD>&G=s@IK#qT(C6CEdHy8Q*7V& zM#%l4ez%dr{a!5KP%Gp{NGs+$fc$Ueo&+UC2>}8jkJ&;=-QCwQ)YBupa}{@cI#3S% zS}}Q2aICv7dRj($eh-=0JUzUGa@1&yA{moaSUv5*?9+x08Jfo#4%Hz`E^$fwGZGW& zqP}JEDU`iFkREwMQ*K_1|1LMat?S%xI7bS=NyRoXV&fJ}>P3n#3Kp4HF{zFBPC!>d z>;c*_%wll_s-LVmkIAgpI5{K4 z2>Tvs^N0GX12=Bu?(UT{4iCz)U#Lb6->8}Wj?58X%6}~2p~Z&ax{29BszD07%v@Yg zFhkwq1F}mwc+_GJ)F-$I1%4M%we(?+zT6;CHEgq*bu%@mR$tWI`7DbhPv2tYlmdoL zV6SV|@Bf}mU|axMAT1+}qB!~Ft>Ua6ssD-M_6@p1Psh2){V*&SU-d#>{j)x|QGA4m zGbSEolYRL`mmxl^Mb(g_=4zUM0~1nfLPQrY$3DT=%g{t*mNxt7WT8-%ZC3-GV{ub7 zLpHT)gmspMP>!k&j{b_(mo>c&OCB%%8!E0dy!)N*01W@VQ4z@baC|Yi+zrk=0As^NBG~f6L-Ga!Ee^AevUqLv6qUrhbpoU9jII5XokcxPyhD|7vv$Ysn_SaCkd zqWlkKv4#oFq~7F2H0fleJs;X>wh_V6nI$r4-;Xv$B4j2SyU|e;Dgi#JQbg{0Un6UN@7@0#c8de9kXg`a1o2z&1!=4vZ{Oe+r@hSwS}F!sqF!%A_pd+9 z=IJF>ig0<_#iu`dZ760SH*k&4UVr5alVQF6ya5D3lxT;yW|iMON4^!#x>`ntC+KpP zt=0ddydR07r~aHWh z-J={?q_ZDpGA%+y5qLKP#XyWhNR!&*kM?ju4Vxd{i zkA0Fqxxf>0LHKb;JZuV!z4|aFK?v&IOgI9ysf$9MJSfKxm|}q$r$FrATz6I2IZT%6 zy42M@e`C^p{Gvx7yUAmx>a;pWJNCMNr-c}B!KOcX0wE%6cspC4`t!s`*)|$XkxCr0 zxX8mw8#5Jw+Gd27@wrsLsaHYcvE^R9qt{IFrF^w5q00#exSZyQWb_hLgvhe zhxDa#FG{~Sol?{C2$r&M#RpVPJHq6$$n3}^0zq9K^~>VuqeyMxYt--9Lpx5F3+ojdE7^)w z+6sWQ!M-=sWt5zaz7VK3(Q}u7KWn zenOt6j?YPi881}z3Iy;CkG;J;3`K9`K=$cP?Z67Ixjnz-Fu1weF9!h3{b@LcX!7sJrIt`3yVMxa9PV7T~@-=xMH+94*j;jrE~7 zWbv5OJF6mTeJb$y&Q83n=Z2jkZHVT)hJKnCOZJdlUQ>6m} zuHfmhMWnG3#c43V9Ft@hgp1dpe0kT>B0)(>$(_c=&VJ*SQek;a?aYd;xxKfC2j8iL z$T!f1mV+>^S>E#w+JR=FPBq>2A2!BN*ny_-x|A6#*7f_od)iaWFOwe(zf>rk&2(92 z=MyDf)~S5#Ie0@n6I-ci^W}bBr#dGi%bKTWq06>m*qf-%1Jx3;!~r*Q@i=db0oTXw zhU_5ct7MRp;j!S|8z@)V*C{M-3gBhH^~^HUO*cLA>&0d<1iz4c2DP?l4>k+LoqjPR zBdS=L3)t8mZf?WA|Ml*6b}X282h~FK{KONdJkCw8KE?$bDxIKg1x`Y}GOb#`VUB$`cK3^8B$i#PT(B}MZADCnLq z`fI+UWr0RP3K>U5R4q3_glSG*K);hjJIqBTC>W2TOHN6-|Mu#twU%76ZengXFh};0-hAr`C~?@^O>p%&GrJtj)SMqRWdUY52sB>3r@R^ zJ19nDyQ~E8t{N$#buk=w|P!>fN>bUGPIOwuHDAl;Yl(9PGeQ%i#s0Q;5&17C!| zG9W}ygmmVq)!2g7R<~+q-;C{0sCg|cmEWde@fmnJfj~$p1MF}%FN4hQv%u<)KiwFB zlAWua#O4>!p1=nyLNC&KkjLB9L|b;lT}}JA^fk$y&@&_!;#J&_W&TI()knRv7Z^L$M!sWurn{)SdPt7X^PcIlp0l}bi z$NHRzZ6Pukqy~>>xW)m~20>^KlRDuKYO)e?#*P-lG0+IWX=4hK{t}Ns%su`borC@+ zfq`TX)cw`}L5aw{4D3cng@<|{2b%Gw&_9@{nEe59d-SU$=E+}$hez*^j4m%dod7AP zF0F0RFZQwGeR(LHU!515;%Ij#e~MHJV;a}@IwmwI_N9V+Es4~bM{Y^XC(Ef&_1p5P z=%}4du^$tYWisZcrHsb|;gdd-b^RZOkvF^mxfD**xcQ#$8|QD6eH zFAmEhfh?J2S$ppc1PSp!Nih!uj zSC(0{;(E!AO*aOrkALx>eXoqPkkVCAspjHwKPh=OPaKNiG6QVLV;z?jWW>1WVv<5X zTz0M;u?J<7uyuQwcnU3Rpn^W^x@mz`4oVmV;yoa1VcYZ!dQQ^% zHUm=OtE%gPV)CrNo5stbNf^I>GqOr%6x^je*}4dZ=7r=|?tw|$3FqHsm{L)d3MQ!1 zJO7Zt(dgTLb_9RBgZy;p0cyR z)BOCapL4>&@O{Ik$1!Y-@=R7@Q!CPCdq3B82N3=6E$VE5DSs#Ik^L(MQhgs*!sHv; zTqtbmYxS=2&Wk;jm-l1K7i}?X{z@J;TElD)=%c??vs87Bnoih%ne=SXci_iHSO^ST ze#>ny5#!_;Ma0c;do?5L-4APTBNXuEX1yiZT)vD%0U}F*5oo4e8u38^m&lc4^;)|N zWa!KcGn@8d&?6xbyYR7RPO{XIm3u1(6K+_|am|VqJ6IyCX~Tz~T@&YzW(zL%NS5TW zKM0cT#7ON`+pk>W0o8I%rXTnY=-b1E?Qx(I9EoxiP1N3rlSRI7rp*LD1T0J+cEtNf zDYhfW8NDk4qhA^SEQtq$l!USL6v#H=Rf-2#$&eSbjODyU!V1Alc^ALo=%*qS@$G-1{-eBukmPMu{( zqjmK?Mr9jbCm&H4m*A>gd88FJz;~Ie2V7AiP;rsZ@|jx4f&RMA_NY}onoICl@p&^&68s#?%t6!U^^ z@%;Eci1YrMWD&E_hQ4#Qk7#qkU4vyF$(e5=T6QBg-`R}t%Hlp}bCeqg64FXxqi`XK}dZjTk(qEZ$_*Pgd zKIi_rqUQaZQa(fJD9FDt7Y`xau0got&$PfoJSRJj`lA8Y_a0+6@FhYqh=Xr|EC^5= zOW)oi^u86jap`(2&up<-cEQKga%NqGZ_DA8_{nUsM-FkowT^p)euQXsqF(?)Xmjgm=V$C|5hLuERaG_~JYAw=4B~C+QDR3>qK@ z2RLhBdW*$nYe(C298TxRH+is$Y{Y@`z4A+!WG|pR5O~5qr2yo@5?&7Jws7Wag>U*3 zMvu5Zb1HH_g7`+P!OG2i=P7#>do%konB~AwqV?&s-0?XsA)}A~!G8F#8+6F!B>Whf5T2h1YTS>+PLjQVyO<9JNh<06 zn5Tj&TGiQE6~N)XuJpnsN?Qf}KL_cna9f~Mb`4d7OE*WE0p6s;%!q1=(@+v7Kwybb zT;_Bfc5L~#Zf&BZvDCz-49?%$EVyzr!`hzn`2*CJf~DQ-6~R2HmVbAq~oQuAE!vctDK1}enS=GvH3wO92$gY%dCI+e5_{Uyt>(UCw3hp`WoFko`>y9uMX}XpeF!^>;83^ z$4dl`8Yfy{I%N$~Ik)Z+A-A6=N0Xr#l`LHnW;09kmCGZDiTcW#&i#3Fg(L?1gZL#1 zBObT60JF=7Oup|c?ZOMn+zMkybiN;Y(GvPTLo@$oRG(Aj8;eN9A>A z((1aOWH?&;1VOrviDHb~hA$8W3ZFhK2zi!+(+S)uCAe-+K1VFV>;gJieDWRkITv1} zeiv%zazy9t@*yTEnW#>#>twXKM;*$eecnHJ$zeMg*mwX~0Z)2Pq8&o3?fF!%8+X{L z&9s*&@D9>>5}ZZ{w5vEtRKQq3x9k*Ol?P;0*+bgo-r_K>1VJ?8NLycOUn;J%2Jj!tE(j{+6UDe09A_ zW}LiGk#Vc$ZfmdavwijRbp)5CMe!#jiY@xX-@%bJ8~`Nv8Uk9KZHzILlx|003D3(+BY}QV=G<_(UjfHD%DoRQV@*OqcIf zKzs&y804?TZRj9ZQour^F0k~vZz)&p#+S*1 zWx@=Im%Y@;%gCyFq2;VyXh<`!0tYJborcnkGY~{w;(P(*D!8y{<7rI~1NyK-vbKtD zBM>qmw&^X$35E$oZndC!cwV7I-cHprjx@!hOcL~ZQ*eQ|$4ri<-WLfCDI}|&TPM1~ zxHI9ICrk5qY0JhH4D)aYF|e)Y_!S(80^|kJjQ81^ zsxSQg8UK+3g(*8t19L@r#l=5r`KJXLr>= z*A^2M09XoK+e!tvGFA&{L@-Nz_Fg&X;EFcTwhb*0>vBT;<13;Jetja?x>g@+t1{>Pg76>bRAG zt3deYq#-_uQ8USwZDLS$=x0Ib%k0rfR3oTyBwmSlA8E8~%VR==I*;J80}q+UdMG{X z*Bc#s=zTW>557?TUe^B%T$Z%rHNQ&KqX)G||=1;(GS1kX zC(Z{1@yi8yS%{83V%n-n+Hx>s_yn%n!(AQV?26$G0KUT~Rkl}*HjFUgH<=oMlznLL znJ1>#?HpYZZMG~8-nGAF*Q53U{C^*-_US{U!LM6TT(5Tl)>6Q2SCBPkGYn03pZ8Zo zfCu5qfam13EUZ+KWe%Zi_nVXEhu?fQ0jD->ad5HnEORjHO}&PGp0VtnhIlJfQ!{`@C{!b!<}T*(WM$X>GmJKm|{BW)lr4E5K&%&=}0t zpGZpqx zx4v=VyiQz#uZ`Z?CR)FpFc7`%eGZ}Wlx4Bkgi#)>a;d`}$nexoZQqf^Vz2BV6Gqks zZc=AK!LVa|F1;JJ-=98UPm1njW0ymWDM#z40SO!8% zRA}r9)4#(E%EE62FS6#qC*@WoEGra$vv5fzqF&>T|KFuY%%!ujq_wRlRmzO7l<&EL zW(hb0Xn=nfJC3Flg)#LGA3bBj6DgE%=r*(eXR&6=VfzsxQ_wqJnuf0G7JuS&JTZ_v zb7$M`?pOZ4umTh25`_hz?9Ovr!JoC6^or~x^JS_}kUoAWb)uE};2!m|2=IS`0s`l; zuYbue^IIRom_c%dTXJnHy+EQo(GryPH&Qp(Z@_Ev7iy8mqR&5 zSMVD2Wx>T8t!fFF6oX&dQ1CS7=96N)TPuAW?CeG5<@=kPhSJ}5cASpDG$JuGRLRx4 z#o}4Y7e4q?EJNXMl0m40?wKa0!VgpYEPU=8-i2=bMh)i=;F3q>gZpbF2o8lgdt5at zhNj!ytC;CjbZ&J!p8tEh{XJQ)e587dp)O81aUU~pG=$&+YU3emApwIF zqSa>i0p?yY(=)k1Z-SCoqY}-o6+e%_$UneJp zI5@)oOj0&~6w$3i@N*`Ct8y)C_UIe!z(wnUQ=6Kuqt!OvC|D`-zbo~MkG`FeNv<^& zppu)iI`DZ~?~-Gs9g4tfUClI0BP9V+s+AJPj4bUlIXg%B?6sRJWi3zN>>3Jc`poC{ z-J;OI0SUE=I}0=YRu5T`2%A$vT|mCg$3Xvpd{CN#@-yQ3f3JqK+U;2K<8IoyuMa^V zKXy&W3a+#`#eW9bFa1;{we4xlaxiwSu!~NBh-x`tUtdjg2==fd65PF<-H8j zqqWkCGHJeXXIwsc3AK&Wn*Uuu1jF3hW*~;HPCEAhvjTu7=$Q3DqoJGs+M*(JVak&-_WzjE8--Vy%J~eHDKFwIt)y^ggY@?zmHv1iT%yxG~ue zp3nPnyKX`4V3sIPZ}4in_jygtcVcIYovXhls;&Fd*PXy+*YZ(c?7dFQ06$npmix1q z|9y?4mYp)W{np|}CR_beUh9Q2bctwqx-8%RuVPv2#c2mokKJ|Is_2&wRgZK=GrEY0 zS=X{pFe1`ox}r9NMe~tVr~jRQ;Ikt2H89ARepl6h2Us&4;j~k$*G#=NgJ))J$3ZsV zayY2dSVn68sOUdL4D_Zc*P-h|!PA#aRgfVsySJ{N0_H=PbLm?ZF1G8rn#M(V7hZYX zT~rDrjCCHe4bOA&8p$~J@wVS!?d`K#Ui->i&DbTED+(T_?XB@)?&Iw~`7!ujkmT~f zYl3)3kV{~)TDJmJ)~b4o^T?ltfBiIYr3!Sqfl}=fIK>j2#~vY@kLgCF)J!D?&5GS6 zRaTC7$(KwcM4q3tvkEiPZ+wuGi{{WNHnecd25V64Lu(F?ov&aTk#zj-cMm=fNW$wV zvb})H*E?=W}1XJ>hdFmSgRjKTMsZKmoX zUcZi{Ui#%$YCp9$QRVgBdm1b)r6pxX6qgXYBAsa-`mzJn`@|27QMx>d@xsCf8@{U< zu7W!~)h1{A2fQ(=L^VuK`6DlRq_MUXV3dDO&H!$2=3&rktywatDXwkP4G{FzNI4NkcIC6gq2xVTzP25k53J@z<6} zeF#Qp7EO-EDfDA8zaDM-+7YDr;gf5>o{rWzb?i$4UCI%G5Y_@ z#b_>FHk2k^U2dn_QZ|wZM1phg_1N6&I)x}T2ni*~FvwW$>|%nn>+En_{t9AV8s#H>|AObjLvZE9Ni zvoBluT;O?Jub+yu{n4ylq^jvu!aF7>Tk10#%tLiQm}ab?{)}%~%^0UFK796QC+ppR znF^Jaeoo|ShW~Tve(TikLahBQB9G2E-i4Ks)i7cMbJsMbz?J}jo5g5J4f<@T;+69xLAuU-X2(B!pUzv2a7(v2Vk zCm{6$@o&`6R=4Q4?^C|zgVQydI(PWbOCm-64JRMft}FX1`Ydh`?7mGc-33!3?V? z=68etMP$^ms#?MSG0mxIZiJoPix`742j_2@gJ2LPvWz@6IBDEtnef^G z^_;!Dk;4~LQ#huKI@EDNb{{<5-sw-CK40p65Vmb@x@+~TyUuezpMyu3lAP&7-it5O zXy@q}i;uj;QIz z5_pktD~CL_{u6Sc8nk_VUQ7E6PIlh0#$QpFa#EBZ+B_m6gOt4d`dytan$<4co*$Q%LYR212Q?(;0~<>$@2`(%{o-}o;Ia8~o6Ne>bAO9g zcJiZBrX$E-iR7lh8UA2S=XZ@u?20mJ25VxgoD^l*kwsrm9uN8Yl@na~;Munj2u20NvUcH-vXjZ3F%v7Y3jYXaMwLOfWE-4M&U7tdNE1rU{M6d3p)qLOW zlw_Fz+~uK?C9qSzG&FR090nm))hgR--evx@e%M7O=&3Cqe3v}aw4Df|t>f?h0!p9p zCrTT?`?G9K<@Y$K1+mWG*;|_^1*00P?kLLTqf^qd2n9v>+iIuDJ2pH!ivXA&?VUr^ zh;^nx@p*BAE}UZ!%YK6O*eS!jcS!Hp?m%S8j`p5eq*uChqO`uJX3o}5O#^paT)wKA z#;@NA26RPWTC=dU&68=f`(W#lEc#8F{l88hLEuT=5sGUppHX`|o40Ja*sGB>F}!8! zgC5Q#ueVzD#G_T7vt|w^r&zq;N^{An$B0+iooP+_@_mBNas4$;C)XlRs&cK@?NBj1 z*1aW?i+6O1Y&F}$&_k1_Z`CxL91wI>S%D%e4F5=7e?otRb;{$*#1uhQ%F;&0UJ!JF z)d>6T^@~OG{*$U!ma$__ofJ{%=X|OD5_Yd2k6jUOQ5ci`8GK7hKH=V8f~^Z){Ne<1 z`*6cJ2>HU!n^^zA%bmA+Q;@FQj`!r(R<>EzcSgLofB??XdZy~G3cIGdPkBl2+n>^m znalFdoX#lEAk(5$wK%cytS3jt{ZD_nBqTRaIEqLry%2%*xtq^{%93Wp_{reeyxWZP7-yR5(C+sf zFQis?4i=#@830 zIWX>j*Cs2p#Al&x>1wSl*7B6_)-c)IYT~y%0f{sF8&Yny+306XQHMi5mbp{o-1Z|0 z$5GBG&k0}MueW;J{&%WSp(UiTD-^?ngSC4pf=K-h17fzfCB_;-* zKaF>xEkZ5wO4YwR>gPu@j#>CE%m{w7QvS0Qni8cfvg@DM4ET{)<+|dWpO<2kzNq_m zHD$G?_z4U0O;eJxFfU;plS%uELHU(Xcz|LM2)&qk-y{hy;hvl$Y?ROtNIR6Mw2Ny`bpF+DKL zO3LB>vs4RR!Yrqgo>h+mxV?JnHj(jULL-X%4v+k-Jj&Le}7t28A_j~@p P{Hx?sIkEgF25 Date: Mon, 8 Nov 2021 05:33:50 +0800 Subject: [PATCH 242/272] Add files via upload --- docs/diagrams/arch.png | Bin 0 -> 133105 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagrams/arch.png diff --git a/docs/diagrams/arch.png b/docs/diagrams/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..3b5842fcb971b005b7a80ffcb9b905eee24ec67c GIT binary patch literal 133105 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 P{Hx?sIkEgF25 Date: Mon, 8 Nov 2021 05:34:24 +0800 Subject: [PATCH 243/272] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a284398a56..df8f7f975f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -29,7 +29,7 @@ and third-party libraries -- include links to the original source as well} ### Architecture -![](diagrams/architecture.png) +![](diagrams/arch.png) The Architecture diagram above explains the high-level design of the Typists app. Given below is a quick overview of main components and how they interact with each other. From 0ef4a3858046d22fd1045aa273a2a106c28201d4 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Mon, 8 Nov 2021 11:03:12 +0800 Subject: [PATCH 244/272] Update DG and UML diagram --- docs/DeveloperGuide.md | 13 +- docs/diagrams/WordLimitMode.png | Bin 53814 -> 57298 bytes docs/diagrams/WordLimitMode.puml | 124 +++++++++--------- .../seedu/typists/game/WordLimitGame.java | 4 - 4 files changed, 71 insertions(+), 70 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index df8f7f975f..f3afc6f9dc 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -71,12 +71,17 @@ For instance: * Then, `.run()` method of `TimeLimitCommand` is executed, a Time Limit Game will start running until game ends(i.e. timer's up). * `.gameSummary()` method will then generate the summary of the game. +### Word Limit Game + +Sequence Diagram for Time Mode Game: +![](diagrams/WordLimitMode.png) +The Sequence Diagram above illustrates the working process of the `WordLimitGame` class. ### TimeLimitGame Class Sequence Diagram for Time Mode Game: -The Sequence Diagram below illustrates the working process of the `TimeModeGame` class. +The Sequence Diagram above illustrates the working process of the `TimeLimitGame` class. ## Implementation @@ -103,13 +108,7 @@ There only exists one private content string for all sessions. Each time a set m depending on the choices that the user made throughout the process. Whenever the user starts a game, the getContent() method is called and the text is set accordingly. -### Word Limit Game - -Once the CommandFactory reads a 'word' command, a word limit game will begin. -Gonna to change this .puml diagram later - zhansen - -![](diagrams/WordLimitMode.png) ### \[Proposed\] View Statistics feature #### \[Proposed Implementation\] diff --git a/docs/diagrams/WordLimitMode.png b/docs/diagrams/WordLimitMode.png index 158124bac2edea439ac977432794a52ba649c7a2..4143172c502366a732b21dc43bac28a60c02f9ba 100644 GIT binary patch literal 57298 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 z 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 CgkY=y literal 53814 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�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 SearchCommand : execute() -activate SearchCommand +-> WordGameCommand: run() +activate WordGameCommand +WordGameCommand -> WordGameCommand: getNumber(args, WORD_SIGNIFIER) +activate WordGameCommand +WordGameCommand --> WordGameCommand: wordLimit +deactivate -alt Able to connect - SearchCommand -> NusMods : searchModsOnline() - activate NusMods - NusMods -> NusMods : getOnlineModList() - activate NusMods - NusMods --> NusMods - deactivate NusMods - loop for each mod - alt Module Code Match - NusMods -> NusMods : fetchModOnline() - activate NusMods - NusMods -> NusMods : getOnlineModInfo() - activate NusMods - NusMods --> NusMods - deactivate NusMods - NusMods -> ModStorage : saveModInfo() - activate ModStorage - ModStorage --> NusMods - deactivate ModStorage - NusMods -> ModStorage : loadModInfo() - activate ModStorage - ModStorage --> NusMods - deactivate ModStorage - deactivate NusMods - alt All Flags Match - NusMods -> TextUI : PrintModBriefDescription() - activate TextUI - TextUI --> NusMods - deactivate TextUI - else - end - else - end - end - NusMods --> SearchCommand - deactivate NusMods +create WordLimitGame +WordGameCommand -> WordLimitGame: createGame(args, isReady, setContent) +activate WordLimitGame +WordLimitGame -> TextUi: getWordLimit() +activate TextUi +TextUi --> WordLimitGame: isValidWord(n) +deactivate +WordLimitGame --> WordGameCommand +deactivate -else No connection or Quicksearch +WordGameCommand -> WordLimitGame: runGame() +activate WordLimitGame +WordLimitGame -> WordLimitGame: trimContent(limit) +activate WordLimitGame +WordLimitGame --> WordLimitGame +deactivate +WordLimitGame -> WordLimitGame: getTimeNow() +activate WordLimitGame +WordLimitGame --> WordLimitGame +deactivate - SearchCommand -> ModStorage : searchFiles() - activate ModStorage - loop for each json - alt Module Code Match - ModStorage -> ModStorage : loadModInfo() - activate ModStorage - ModStorage --> ModStorage - deactivate ModStorage - alt All Flags Match - ModStorage -> TextUI : PrintModBriefDescription() - activate TextUI - TextUI --> ModStorage - deactivate TextUI - end - end +loop until Exit + WordLimitGame -> Utils: displayLines(row) + activate Utils + Utils --> WordLimitGame: line + deactivate + WordLimitGame -> TextUi: printLine(displayed) + activate TextUi + TextUi --> WordLimitGame + deactivate + WordLimitGame -> TextUi: readCommand() + activate TextUi + TextUi --> WordLimitGame: inputs + deactivate + alt Exit + else continue typing + WordLimitGame -> WordLimitGame: updateUserLines(inputs) + activate WordLimitGame end - ModStorage --> SearchCommand - deactivate ModStorage - + deactivate end -<-- SearchCommand -deactivate SearchCommand +WordLimitGame --> WordGameCommand +deactivate +WordGameCommand -> WordLimitGame: gameSummary() +activate WordLimitGame + +WordLimitGame -> WordLimitGame: getDuration() +activate WordLimitGame +WordLimitGame --> WordLimitGame: gameTime +deactivate + +WordLimitGame -> TextUi: handleSummary(...,"Word-Limited") +activate TextUi +TextUi --> WordLimitGame: summary +deactivate +WordLimitGame -> WordLimitGame: handleStorage(summary) +activate WordLimitGame +WordLimitGame --> WordLimitGame +deactivate + +WordLimitGame --> WordGameCommand +deactivate +destroy WordLimitGame @enduml \ No newline at end of file diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 2b08180ee6..1d21089599 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -46,10 +46,6 @@ public void displayLines(int row) { ui.printLine(displayed); } - public int getTotalSentence() { - return eachWord.size(); - } - public int getWordLimit() { ui.printScreen("Enter how many words you want the game to run: "); try { From b5a8d5da8c2a22b08a9e5525a73dcd50298116a7 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Mon, 8 Nov 2021 11:05:05 +0800 Subject: [PATCH 245/272] Update WordLimitGame.java --- src/main/java/seedu/typists/game/WordLimitGame.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/typists/game/WordLimitGame.java b/src/main/java/seedu/typists/game/WordLimitGame.java index 1d21089599..1408fdddd0 100644 --- a/src/main/java/seedu/typists/game/WordLimitGame.java +++ b/src/main/java/seedu/typists/game/WordLimitGame.java @@ -8,8 +8,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Scanner; - import static seedu.typists.common.Utils.getDisplayLinesWithoutNull; import static seedu.typists.common.Utils.getWordLineFromStringArray; From 0be591a4476dd1848e43fd6b275dc78c9e4ede8a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 16:02:47 +0800 Subject: [PATCH 246/272] update command DG --- docs/DeveloperGuide.md | 5 +++-- docs/diagrams/command.puml | 7 +------ docs/{diagrams => images}/Content.png | Bin docs/{diagrams => images}/WordLimitMode.png | Bin 4 files changed, 4 insertions(+), 8 deletions(-) rename docs/{diagrams => images}/Content.png (100%) rename docs/{diagrams => images}/WordLimitMode.png (100%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 24e8681176..99df3866cc 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -50,6 +50,7 @@ The `Command` component implements the Factory Design Pattern to parse user comm Here’s a (partial) class diagram of the `Command` component: +[](diagrams/command.puml) How the `Command` component works: 1. Typists `Main` calls upon the `CommandFactory` class to parse the user input. @@ -95,7 +96,7 @@ There are 3 types: The following UML diagram illustrates the way content selection works in the program. -![](diagrams/Content.png) +![](images/Content.png) There only exists one private content string for all sessions. Each time a set method is called, the string is changed depending on the choices that the user made throughout the process. Whenever the user starts a game, the getContent() @@ -107,7 +108,7 @@ Once the CommandFactory reads a 'word' command, a word limit game will begin. Gonna to change this .puml diagram later - zhansen -![](diagrams/WordLimitMode.png) +![](images/WordLimitMode.png) ### \[Proposed\] View Statistics feature #### \[Proposed Implementation\] diff --git a/docs/diagrams/command.puml b/docs/diagrams/command.puml index dcc64e4ee2..779342f81a 100644 --- a/docs/diagrams/command.puml +++ b/docs/diagrams/command.puml @@ -10,9 +10,6 @@ package Storage { package Game { } -package Content { -} - package Command { Class CommandFactory @@ -39,15 +36,13 @@ CommandFactory ..> ExitCommand CommandFactory ..> GameCommand CommandFactory ..> HistoryCommand -GameCommand --> Game +GameCommand -> Game TimeGameCommand --> Game WordGameCommand --> Game HistoryCommand --> Storage ClearCommand --> Storage -ContentCommand -up> Content - ClearCommand ..|> Command ContentCommand ..|> Command ExitCommand ..|> Command diff --git a/docs/diagrams/Content.png b/docs/images/Content.png similarity index 100% rename from docs/diagrams/Content.png rename to docs/images/Content.png diff --git a/docs/diagrams/WordLimitMode.png b/docs/images/WordLimitMode.png similarity index 100% rename from docs/diagrams/WordLimitMode.png rename to docs/images/WordLimitMode.png From 3e5b89c7b2973ed27ada45a9f95bffe6b2beef4e Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 16:19:18 +0800 Subject: [PATCH 247/272] udpate --- docs/DeveloperGuide.md | 10 ++++++---- docs/images/command.png | Bin 0 -> 47575 bytes 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 docs/images/command.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 99df3866cc..73ec2cc8a4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -48,16 +48,18 @@ The other core components of Typist: The `Command` component implements the Factory Design Pattern to parse user commands. -Here’s a (partial) class diagram of the `Command` component: - -[](diagrams/command.puml) +Here’s a (partial) class diagram of the `Command` component: + +![](images/command.png) How the `Command` component works: 1. Typists `Main` calls upon the `CommandFactory` class to parse the user input. 2. The `CommandFactory` returns a `Command` object (more precisely, an object that implements it e.g., `GameCommand`). 3. `Main` will then execute the `Command` by calling `.run(args)` method of the `Command`. -The Sequence Diagram below illustrates the interactions between `main` and `Command` component for the `getCommand("game -time")` input. +The Sequence Diagram below illustrates the interactions between `main` and `Command` component +for the `getCommand("game -time")` input: +{Some sequence diagram} ### Game Component diff --git a/docs/images/command.png b/docs/images/command.png new file mode 100644 index 0000000000000000000000000000000000000000..fdeade20a6c61bac0c0847941994f66a26b8cf54 GIT binary patch literal 47575 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 literal 0 HcmV?d00001 From 24d265f18fdd9ebffd19eff1798937beb3f78f81 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 19:03:36 +0800 Subject: [PATCH 248/272] update timelimit sequence diagram --- docs/DeveloperGuide.md | 35 ++++++++--- docs/diagrams/TimeGame_SequenceDiagram.puml | 66 ++++++++++++++++++++ docs/images/TimeGame_SequenceDiagram.png | Bin 0 -> 46009 bytes time-limited_records.txt | 2 + word-limited_records.txt | 5 +- 5 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 docs/diagrams/TimeGame_SequenceDiagram.puml create mode 100644 docs/images/TimeGame_SequenceDiagram.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 63aa657602..c765d8498d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -64,25 +64,44 @@ for the `getCommand("game -time")` input: ### Game Component **How the Game Component works:** -* When `.run(args)` of the `GameCommand` object is called, a corresponding `Game` object is created. -Immediately after, the `.run()` method of `Game` will be called, followed by `.gameSummary()`. +* The `Game` component consists of 2 parts: + 1. The actual game execution classes; + 2. and the game record classes +* For 1: When for a `Game` object, the `.runGame()` is the main method that runs the game until termination and +the`.gameSummary()` displays the summary and stores game data. +* For 2: Game Record Management, which interacts with record storage, will be explained with further detail in [later section](#proposed-view-statistics-feature). For instance: -* When the `.run(args)` of `TimeGameCommand` is called, a `TimeLimitGame` object is created. +When game is running from the CLI: +* The `.run(args)` of `TimeGameCommand` is called, a `TimeLimitGame` object is created. * Then, `.run()` method of `TimeLimitCommand` is executed, a Time Limit Game will start running until game ends(i.e. timer's up). * `.gameSummary()` method will then generate the summary of the game. + +The (partial) Class Diagram bellow illustrates the structure of `game` component: +{some class diagram} + +There are 2 constructors in `TimeModeGame` class, each handling different number of parameters specified. + +As from the diagram, `WordLimitGame` and `TimeLimitGame`, the 2 major game execution classes inherits from the `Game` Class. +However, their implementations and functionality varies on many parts due to them being 2 different games. +Hence, The section below explains in greater detail how [Word Mode](#word-limit-game) and [Time Mode](#time-limit-game) of Typist game are implemented. + + ### Word Limit Game -Sequence Diagram for Time Mode Game: +Sequence Diagram for Word Mode Game: + ![](diagrams/WordLimitMode.png) + The Sequence Diagram above illustrates the working process of the `WordLimitGame` class. -### TimeLimitGame Class -Sequence Diagram for Time Mode Game: - +### Time Limit Game + +The Sequence Diagram below illustrates the working process of the `TimeLimitGame` when the `.runGame` method is called: +sequence +![](images/TimeGame_SequenceDiagram.png) -The Sequence Diagram above illustrates the working process of the `TimeLimitGame` class. ## Implementation diff --git a/docs/diagrams/TimeGame_SequenceDiagram.puml b/docs/diagrams/TimeGame_SequenceDiagram.puml new file mode 100644 index 0000000000..a128843e20 --- /dev/null +++ b/docs/diagrams/TimeGame_SequenceDiagram.puml @@ -0,0 +1,66 @@ +@startuml + +box TimeLimitGame +participant ":TimeLimitGame" as game +participant "ui:GameUi" as ui +endBox +participant ":Util" as util +participant "in:Scanner" as scanner + +[-> game: runGame() +activate game + +create scanner +game --> scanner: <> + +game -> game: getTimeNow() +activate game +game --> game: beginTime +deactivate game + +loop until TimeOver + alt Time Not Over + game -> game: displayLines(currentRow) + activate game + game -> util: getDisplayLines(...,currentRow) + activate util + util --> game + deactivate util + game --> game + deactivate game + + game -> scanner: nextLine() + activate scanner + scanner --> game: line + deactivate scanner + else Time Over +end + +game -> game: updateUserLines(inputs) +activate game +game --> game +deactivate game + +game -> game: endGame() +activate game +game -> ui: printEnd("Time game end") +activate ui +ui --> game +deactivate ui +opt Time Overshoot + game -> ui: printOvershoot(overshoot time) + activate ui + ui --> game + deactivate ui +end + +game --> game +deactivate game + +[<-- game +deactivate game + +<[hidden]- game +destroy game + +@enduml \ No newline at end of file diff --git a/docs/images/TimeGame_SequenceDiagram.png b/docs/images/TimeGame_SequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6d6ed097e6745c2f09b9329b4fbc87a4afaa72 GIT binary patch literal 46009 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 Date: Mon, 8 Nov 2021 19:09:20 +0800 Subject: [PATCH 249/272] Update UserGuide.md --- docs/UserGuide.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d6ea31138b..d05ab76a3b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -68,6 +68,11 @@ e.g.2 `clear -gtime` will be interpreted as `clear` ### 3.1 Set Content: `content` Set the typing content before the game. +There are two game modes in Typist: + +* time-limited (aim to type as much as possible in a limited time) +* word-limited (aim to type a chosen number of words as fast as possible) + Format: `content` `1-3` `[optional]` After entering `content`, user can type an integer from 1-3 to choose from following: From 8fce7b912992b1720d33f53234c6c5b85d21931d Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 21:08:31 +0800 Subject: [PATCH 250/272] update PPP --- docs/DeveloperGuide.md | 2 +- docs/team/lusicheng.md | 56 +++++++++++++++++++++- src/test/java/seedu/DataProcessorTest.java | 13 ----- time-limited_records.txt | 4 +- word-limited_records.txt | 2 +- 5 files changed, 58 insertions(+), 19 deletions(-) delete mode 100644 src/test/java/seedu/DataProcessorTest.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c765d8498d..b37471b610 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -48,7 +48,7 @@ The other core components of Typist: The `Command` component implements the Factory Design Pattern to parse user commands. -Here’s a (partial) class diagram of the `Command` component: +Here’s a (partial) class diagram of the `Command` component: ![](images/command.png) diff --git a/docs/team/lusicheng.md b/docs/team/lusicheng.md index 83b10f9210..ceb5fceb83 100644 --- a/docs/team/lusicheng.md +++ b/docs/team/lusicheng.md @@ -1,6 +1,58 @@ # Lu Sicheng - Project Portfolio Page -## Overview +## Overview: TYPIST +Typists is a command line interface typing game targeted at users who love to type and are +familiar with the command line interface. There are two game modes in types, time-limited +(aim to type as much as possible in a limited time) and word-limited (aim to type a chosen +number of words as fast as possible). + +Given below are my contributions to the project: + +#### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2021-09-25&tabOpen=true&tabType=zoom&zA=Isabella-L&zR=AY2122S1-CS2113-T13-4%2Ftp%5Bmaster%5D&zACS=167.6350974930362&zS=2021-09-25&zFS=&zU=2021-11-08&zMG=false&zFTF=commit&zFGS=groupByRepos&zFR=false) + +#### Features + +* **New Feature**: Added the Time-Limited Game + * What it does: allows the user to type words within a set period of time and analyse the result. + * Justification: It allows the user to control the input time. + * Highlights: This feature is one of the 2 game modes. It is the one of the fundamentals of Typist. + And it required manipulation of the `Data/Time` java API. +* **New Feature**: Added the ability to put game usages into 1 command + * What it does: gives the user option to input all usage command at once. + For instance, the `-sn` tag will enable user to start timer immediately without the "Enter 'start' to start timer" prompt. + The `-c` tag enable user to override the current content set before starting game. + Adding integer directly after `game -MODE ` will avoid the "enter the game limit" prompt. + * Justification: This feature increases the usability significantly because users (assumed familiar + with cli and typing) would have a much more convenient, effective and smooth experience using the app. + * Highlights: This enhancement affects existing commands and commands to be added in the future. It required + rather sophisticated dealing of arraylists, exceptions and constructor overloading for `game` and its subclassess. + +#### Project Management + +* Managed Releases: `v1.0`, `v2.1` on GitHub. + +#### Enhancements to existing features: + +* Implemented the Factory Design pattern suggested by [Jiajing](limjiajing.md): [#56](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/56). +* Added Typist starting display (with ASCII) and other display format: +[#15](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/15), +[#16](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/16). + +#### Documentation + +* User Guide: + * Added documentation for Open Game section(excluding Word Limit Game section by [Zhansen](shizhansen.md)) and Command Summary: [#152](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/152). + * Added documentations for Introduction, quickstart, table of content and other cosmetic tweaks. +* Developer Guide: + * Added design detail for Architecture (excluding the diagram by [William](williamwahyudi.md). + * Added design detail for Command Component, Game Component and Time Limit Game section: [#155](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/155). + +#### Community +* [16 PRs reviewed](https://github.com/AY2122S1-CS2113-T13-4/tp/pulls?q=is%3Apr+is%3Aclosed) +* Some parts of `Util` and `TextUi` features I added was adopted by other classmates([#87](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/87)). +* The `game` class I added is inherited by both `TimeLimitGame` and `WordLimitGame` + ([#56](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/56), [#144](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/144)). +* The `GameCommand` class I added is also applied to both `TimeGameCommand` and `WordGameCommand`([#81](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/81/files)). + -### Summary of Contributions diff --git a/src/test/java/seedu/DataProcessorTest.java b/src/test/java/seedu/DataProcessorTest.java deleted file mode 100644 index 756205dd6e..0000000000 --- a/src/test/java/seedu/DataProcessorTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package seedu; - -import org.junit.jupiter.api.Test; - -public class DataProcessorTest { - private static final String TEST_TXT = " testing testing testing"; - //name: whatIsBeingTested_descriptionOfTestInputs_expectedOutcome - - @Test - public void getTotalWordPerMinute_validTotalTime_success() { - - } -} diff --git a/time-limited_records.txt b/time-limited_records.txt index f1812feb9a..d107aff7e9 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,2 +1,2 @@ -Time-limited|32.119|24|16|40|60.0|40.0|29.888850835953797|[Lorem, Ipsum, simply, text, the, printing, and, typesetting, industry., Lorem, Ipsum, been, industry's, standard, dummy, text, 1500s,, when, an, unknown, printer, took, type, scrambled] -Time-limited|37.157|7|33|40|17.5|82.5|53.28740210458326|[fleshy, balloon, head., The, earflaps,, hair, grew] +Time-limited|32.119|24|16|40|60.0|40.0|29.888850835953797|[Lorem, Ipsum, simply, text, the, printing, and, typesetting, industry., Lorem, Ipsum, been, industry's, standard, dummy, text, 1500s, , when, an, unknown, printer, took, type, scrambled] +Time-limited|37.157|7|33|40|17.5|82.5|53.28740210458326|[fleshy, balloon, head., The, earflaps, , hair, grew] diff --git a/word-limited_records.txt b/word-limited_records.txt index dc68040dbe..11294572ba 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1 +1 @@ -Word-limited|12.04|3|8|11|27.27272727272727|72.72727272727273|39.8671096345515|[the, printing, typesetting] +Word-limited|12.04|3|8|11|27.27272727272727|72.72727272727273|39.8671096345515|[the, printing, typesetting] From 2abb6a7723e504c9432b84c5b39029b6a8d9d8d8 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 21:19:10 +0800 Subject: [PATCH 251/272] update testing --- docs/DeveloperGuide.md | 15 +++++-- docs/team/lusicheng.md | 58 +++++++++++++++++++++++++++ src/main/java/seedu/typists/Main.java | 2 +- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c765d8498d..c09532fd15 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -208,9 +208,18 @@ It solves the lack of entertainment alternatives on the CLI. ## Glossary -* *glossary item* - Definition +* Mainstream OS: Windows, Linux, Unix, OS-X +* Time Limit Game: A game that ends only when timer stops. +* Word Limit Game: A game that ends only when all the words has been inputted. ## Instructions for manual testing -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} - +### Launch and Shutdown +1. Initial Launch + 1. Download the jar file and copy into an empty folder + 2. Double-click the jar file. Expected: shows the starting page and current version of Typist +2. Obtaining past game records + 1. Exit the game through command `bye`. + 2. Re-launch the app by double-clicking hte jar file. + The record of previous games is retained. + \ No newline at end of file diff --git a/docs/team/lusicheng.md b/docs/team/lusicheng.md index 83b10f9210..df30db7e33 100644 --- a/docs/team/lusicheng.md +++ b/docs/team/lusicheng.md @@ -1,6 +1,64 @@ # Lu Sicheng - Project Portfolio Page +<<<<<<< Updated upstream ## Overview +======= +## Overview: TYPIST +Typists is a command line interface typing game targeted at users who love to type and are +familiar with the command line interface. There are two game modes in types, time-limited +(aim to type as much as possible in a limited time) and word-limited (aim to type a chosen +number of words as fast as possible). + +Given below are my contributions to the project: + +#### Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2021-09-25&tabOpen=true&tabType=zoom&zA=Isabella-L&zR=AY2122S1-CS2113-T13-4%2Ftp%5Bmaster%5D&zACS=167.6350974930362&zS=2021-09-25&zFS=&zU=2021-11-08&zMG=false&zFTF=commit&zFGS=groupByRepos&zFR=false) + +#### Features + +* **New Feature**: Added the Time-Limited Game + * What it does: allows the user to type words within a set period of time and analyse the result. + * Justification: It allows the user to control the input time. + * Highlights: This feature is one of the 2 game modes. It is the one of the fundamentals of Typist. + And it required manipulation of the `Data/Time` java API. +* **New Feature**: Added the ability to put game usages into 1 command + * What it does: gives the user option to input all usage command at once. + For instance, the `-sn` tag will enable user to start timer immediately without the "Enter 'start' to start timer" prompt. + The `-c` tag enable user to override the current content set before starting game. + Adding integer directly after `game -MODE ` will avoid the "enter the game limit" prompt. + * Justification: This feature increases the usability significantly because users (assumed familiar + with cli and typing) would have a much more convenient, effective and smooth experience using the app. + * Highlights: This enhancement affects existing commands and commands to be added in the future. It required + rather sophisticated dealing of arraylists, exceptions and constructor overloading for `game` and its subclassess. + +#### Project Management + +* Managed Releases: `v1.0`, `v2.1` on GitHub. + +#### Enhancements to existing features: + +* Implemented the Factory Design pattern suggested by [Jiajing](limjiajing.md): [#56](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/56). +* Added Typist starting display (with ASCII) and other display format: +[#15](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/15), +[#16](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/16). + +#### Documentation + +* User Guide: + * Added documentation for Open Game section(excluding Word Limit Game section by [Zhansen](shizhansen.md)) and Command Summary: [#152](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/152). + * Added documentations for Introduction, quickstart, table of content and other cosmetic tweaks. +* Developer Guide: + * Added design detail for Architecture (excluding the diagram by [William](williamwahyudi.md). + * Added design detail for Command Component, Game Component and Time Limit Game section: [#155](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/155). + * Added details for manual testing. + +#### Community +* [16 PRs reviewed](https://github.com/AY2122S1-CS2113-T13-4/tp/pulls?q=is%3Apr+is%3Aclosed) +* Some parts of `Util` and `TextUi` features I added was adopted by other classmates([#87](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/87)). +* The `game` class I added is inherited by both `TimeLimitGame` and `WordLimitGame` + ([#56](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/56), [#144](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/144)). +* The `GameCommand` class I added is also applied to both `TimeGameCommand` and `WordGameCommand`([#81](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/81/files)). + +>>>>>>> Stashed changes ### Summary of Contributions diff --git a/src/main/java/seedu/typists/Main.java b/src/main/java/seedu/typists/Main.java index a8b424b704..bdf96202e7 100644 --- a/src/main/java/seedu/typists/Main.java +++ b/src/main/java/seedu/typists/Main.java @@ -17,7 +17,7 @@ public class Main { /** * Version info of the program. */ - public static final String VERSION = "Typist - Version 2.0"; + public static final String VERSION = "Typist - Version 2.1"; public static final int LINE_LENGTH = 10; public static Content content; public static TextUi uiBot; From bc97c18d99a9566c598fe48dca303f59c0a3f2a5 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 21:20:26 +0800 Subject: [PATCH 252/272] update testing --- docs/team/lusicheng.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/team/lusicheng.md b/docs/team/lusicheng.md index df30db7e33..506dc86be2 100644 --- a/docs/team/lusicheng.md +++ b/docs/team/lusicheng.md @@ -1,8 +1,5 @@ # Lu Sicheng - Project Portfolio Page -<<<<<<< Updated upstream -## Overview -======= ## Overview: TYPIST Typists is a command line interface typing game targeted at users who love to type and are familiar with the command line interface. There are two game modes in types, time-limited @@ -57,8 +54,3 @@ Given below are my contributions to the project: * The `game` class I added is inherited by both `TimeLimitGame` and `WordLimitGame` ([#56](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/56), [#144](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/144)). * The `GameCommand` class I added is also applied to both `TimeGameCommand` and `WordGameCommand`([#81](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/81/files)). - ->>>>>>> Stashed changes - - -### Summary of Contributions From 00cc43c154823829457861ebf2ed9b23e808dddc Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 21:28:18 +0800 Subject: [PATCH 253/272] update UG DG --- docs/DeveloperGuide.md | 13 ++++++++++--- docs/UserGuide.md | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c09532fd15..71624b2ab8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -217,9 +217,16 @@ It solves the lack of entertainment alternatives on the CLI. ### Launch and Shutdown 1. Initial Launch 1. Download the jar file and copy into an empty folder - 2. Double-click the jar file. Expected: shows the starting page and current version of Typist + 2. Double-click the jar file. + Expected: shows the starting page and current version of Typist 2. Obtaining past game records 1. Exit the game through command `bye`. 2. Re-launch the app by double-clicking hte jar file. - The record of previous games is retained. - \ No newline at end of file + Expected: The record of previous games is retained. + +### Opening a game +1. Opening a game with optional operands + 1. Test case: `game -time 0` + Expected: A warning message about error on limit input is shown. + The game will still start as if no time limit is specified. + 2. \ No newline at end of file diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d05ab76a3b..8eb0a83727 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -146,7 +146,9 @@ and terminates the game at the same time. without the "enter limit" prompt. > **NOTE**: > if you want to specify GAME_LIMIT, it needs to be right after the GAME_MODE argument. - > If the GAME_LIMIT entered is invalid, game will still start but with the "enter limit" prompt. + > If the GAME_LIMIT entered is invalid, game will still start but with the "enter limit" prompt. + > Any ERROR in the _optional arguments_ will prompt a message but will not terminate the command. + > The game will still start as if the optional argument is not given. From d3b47e6689f99d4a59054329d88bd2de2d67823b Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 21:30:50 +0800 Subject: [PATCH 254/272] Update UserGuide.md --- docs/UserGuide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8eb0a83727..72eb2e0bf2 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -146,7 +146,8 @@ and terminates the game at the same time. without the "enter limit" prompt. > **NOTE**: > if you want to specify GAME_LIMIT, it needs to be right after the GAME_MODE argument. - > If the GAME_LIMIT entered is invalid, game will still start but with the "enter limit" prompt. + > If the GAME_LIMIT entered is invalid, game will still start but with the "enter limit" prompt. + > Any ERROR in the _optional arguments_ will prompt a message but will not terminate the command. > The game will still start as if the optional argument is not given. From d98b28fec40c1290ebd17a8b03ae222282d713e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:41:57 +0800 Subject: [PATCH 255/272] Delete arch.png --- docs/diagrams/arch.png | Bin 133105 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/diagrams/arch.png diff --git a/docs/diagrams/arch.png b/docs/diagrams/arch.png deleted file mode 100644 index 3b5842fcb971b005b7a80ffcb9b905eee24ec67c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133105 zcmaI7WmuKl8ZJB$5G6#Al2lr{K^mpILmCO`?i3ZJrMo301*9h>-Q6kO;H3MEscWsh z_d4hM_@j7vz3)4oyr28IN1&p-1O_T0Dg*+-kdhQthCuErLLi7d_wImy;Sc0_1pavD zB&O-~+Sbn9%EZ(OB4J`<;$Y}xV*JF&{mC0ACp%tdW;-iG8z*OLE2h`B)>tghi6M|X z(dMd}PJjP91OYt8EqPa?%Vvha+iW5>M4Kn5zT=}FnNW1Ekyp~7%BP6|E zm;-{qgJ>6c4-I079qbxy#IqVr9$T?y9u{%HS`1A%8q8HNdUB*L`BwS93!9IPb|`I{EnrXP%eA#H{otInkQr{Gy--R+j;)Q_W9VZ z5k`UW(&SJiUuA^+LSLPXr9^dQtFrL_Hv%u&reM!3!dGr z+c26~zn?P}lAEZfqn*khg{P!la{1z}fxniEp1*++-qN@20A22#TEhv9I-5!7+tp%i zH6f3>)jOo6wD}*gLYHQE2*rlR?n<3yu3T^h*hjazO5rs3S)tKia#kl6;eA`oR-9o` z(O~Y>)~ZjkWRZ|SnxKlxZ$oMzW=Rsdu|PO$4HLB!A5(0;ayBR4YY4y;{egj(k8@Uw z6n;h$Q=_W?geuYdZ>*T{-c;UU)B*(5Kafy=Y^j{O*vZVr2w4jp_0Amso2jCS%l zA^!afBq?JN`R`vWkdc}H{<|VQts6W|;6Hw^M4Hk5{1pNjMMc$vq!Z%SAaBawBtF7* z|8S%YN#{-ELf9sbuYvzBh7bPuki5HHl+X9C(w|5C+)-#mhU90NKl;}HHUa*eCS~w! zKZ{P-?kD!#;S`=N60BT>r`C6KhLZ1Vt~d3ZNC63zbfh*&L1f1V&-NQrJh%fHbF*&H)%%HWQ#hBpb0$oFqA~wI;i*j0{+^)2?TzY3hwbU;$e=e|%FI0QXIM0cIzl5EcAfvE9;)E% zHL?FtgY8=K5wPg@TO6q*+l7X{RR^s<4OgUeta^((k@r`>TNEfUQa^e8Qk>2A z&iHc{M|h}cVu0{b47E6fKYN)qxS9g*K)}8GITuMP|8fLc3N^EtTX*R9#{_xP_a$>8 z+ul=Er1=?BJ{~yuw?@mr46d!7pWSTHcurTPoAND_Q>lK0wm_ z4z(5$;h6cI$fC~5?%TsD(*HKk-5A?AjWhek;iB_0krLGAsi^UVexn`hW%!GSkeN#x zfg7BY{EX?#7+=%;D`e7PyAR7}#JzK$tq&6m-9R}H>yFRz&M*5sz0apyu60|eAKY&F z>Z`PfUYmX4BYH+%;ML$Wk|Q_ozMitym!zewuiS6CAlMnzm@ig}X3oy?kQ1Tn=%@Er z?e+VTmD$t=PTwW9J>T@i?pN6^n666K``>Z3D9hurV0UNzFE?P&EmZ21CREwfIh0+u zH8t$3ek3%ncUD-86@bmg3{21@aGl5TH~8Led?c%MaHthut+FNChw_@KqkrjZ5*|f5 zn*X+KP5oqQ{Bl)h^ZM-d?IRj4T%79M?5Pr6KG)-|scw~*AAW@mtE$;F|98gbdCgSc zqQ7ow{L0{QQ~QAu&3dl#IE=lH?2J&q@=U^Pe#PR@S|)3|^4)qT`&f=#QhdB*fo_@G z!Qy1;Ya)~IdgvZH3GX+x0=&6eXATw~T1!d=x5Kr!VI(t=4^am+wRFkrgA^j;)^l>X zi{+9qO?wHF()Otrq;DAW@YKOY?(So2OXCkO^1^mmtlv! z*)T?JJSCw37$$|M-=BJG@w?tCo^$0+vD~~wh!Ja?SP_Wya_|cM>axm$!LrIlR-9bd zP1-|CT}9d5K%36`F}_0ufPIoD$~1*!5KRF8)@r(NMSQemaiuV0qy$3eL4zL&c+x^qKi%$EOGrn_j>>7G;Dd-Rw^t(04LxFm(y z)NeY)Z8P(`#eI(p0HA`F4B?O^YVRhb6xF&WJvrrl#n#4tRc0SkBWv^9f zrXpTjJ*)V)eJMvI zstwIjXr4@|+uw=QtdO?dpI6&o|8D+>?Qw7re^+w;KS!#NbPDs@ z?upaC`dpC!{a3Eh@Ch!Sq==ggoqD_JqwidXMK)*oDiTwpa#j)M#qC*9D%emBSn5$W zQoS>|UkOd=;G3$l9oU=W+upYI&aG{&p6<}nk{`(pKVN(oyWo9l@+Pm;%P-^SPrdqD zZp-nb@_|~S$0Qo_ivFM*1Sa|!U)*a<)vLNM>2D1sCsbO# zGNz)3+7x(*S%3aezKF)4A~YympRdHxQMW73-X0GYJ0bt?NTxFK9YJ7s&s9(i{66$D zDtjjO_@-7NSe-GkaRE9Jmv#+Z#UIY&X}@eoPTDt>x~Xr)9JvGP{bv}`_ZyekgV`=# zP{DAgVoM(>;&E}spFSg&VSoqMFm3W)Gcl6K)_A4Ti222 z46W}%R;r>tH@Sq3@~>ve7Wh6*&S&JlWP4OmJU@cTP=hy-%1C+lE+>*H6L=t`01gB( zWXSO(HWt>sS*Cq=e+_@Pa<6k}ko)0!{QxxZ^S3!p%GW{Pyo~qqu4S6qb-TOh9N}NA zSn=qyELE_*(1g#O$OvQpmjCUEes@&~qTZY?GhdCrmYVPM^rb9W?eq)1C@a&bIIpZ8 zUNDC_fbM>lS|Zfj`m||O=@Nh9YY%AZe?5K>z?cL@^;a?$AXf<3BG3N=B;kck_}%AE zZ4qYAuPR@)4;1LaSe`PHg*=$`q8@71dcF|LuTVo~Gifqx8M(;d{rsu>rx$(owmK}^ z>{JHJOlveVl1Xph<}jk9Ae%9Q~YXv@@$UsA;W_moXU z^zxEDzrrOePJ-B3F!`J)46+(dm#)KJt805-N10c3iSJ`zImI{Ga_iOfQ(>}EznM8F zgjt(^x*kahy;HSQdhJuZ@!Fa#{z~RI{5;V9@$4=@)ai+6dc%rw{|mv=38}ggp5I_~ zt?elkCk2pJuhm^KPdrPqZqT;67+P6(-&ftX#p5+EI@I!DdDHQsgJ!S&aeOYHU@t}( zHIbmF9+o3`y`#u3}wht|&b;T1WN{hvtzjz;~~=;UPwU>?y;72$)8 z_|@kj9Xq-%FJlwD^JN_PM{J@11m9tEj~Xa@nSoL)a4zxLYAtpbUoSFRM5w30q!uON zH1U`6)b<=%h<2#7>yc-U)HxS8*OPxif8jngyx0|iASo`#;MyjPY5Qi&X0itq8VSeA z{qCm{BjMCD*Jr`t-3UqYAO&Pt%6eev&w^w!(w27lYp7SMNG*@%74?E6sIA*gc`kdV zIcXNer_s^BJpW%uoVVLVxQ8a*WQUlSS2D|;i4#CQ6=Y9fPSXnW-@uP|R3U;QKy=?Db=aA%x7 zeRC`HD?nXKFI-xse1q}vej5U{nL-Yq{U{&#K(gpGx@^|JjKLx%re|1bt9hl{vp5$w zYqtBHkR@%#>;0xg6p8rtR^5^vFauJtcbG5IV{zLq`9#P285}zI@5M{}YZOxq_0M~6 z?0EWVjxBfQx8vGVd^wlbIoS%6IVT+dFQGx4UCNuroR8O%0dbZrvHz4ZXPMh^z>RPp7`O-wZODiL12C}B|BlR{mw<_6ZiM-`=5l}3tlBg*-}{Fy*vD`nRq_r zOBo$E5ARK}$zp7I|D*9Fr}!ruUv}BdRTjq`ORIXzu7A)6OK(`G^D^6DyRPAM(T(wu z%cs5gf4B!KE@p$!g-$Wx;N|oD&Ec+*%^{Y${_P5@>%j6OR}}_+=@G{bjC2>{^U5_O zkW)BvN&igWu`im@{M1up;;h#2JPvASj;u}7wg`QB+I=QbZ;xqS-*9!Epmm%F9t`8B?vQfy2pObnl5(a{-;XypCp21s5c^a`y zri2ss;)RZ$NTVynRt_E&6tG??zzu+(Ni;BUZnElp<(mK5VN*9S`*bVAa#+5{eaW_& zkC_@qf|iNBF{G%#v5x)1e4qrW)tvRmL9U$Z5wk$fz zFM=|d9=Bdi_PrL^Tnmg`+s{*ws;2Bf*7L+Z+=^QR4dJ8JTIO%c1kPf-rOxkUChyXF ze6PD{L+F#Q*y~85qPmM7jMKJLw#D`ZLnkfjNLHiaATlt6vn5_;4JLbO zr*bU_`s|71{t_43&-0$v(NZPf_@Ybjj+bGS{deX2VJWR`a z*5dn^-?>jgSnK@5)w>chtwtUk9K3y9Rk$N-d}hp!wcDTY_6kj=iQQwDSyNlasGDmHIq$2!B0tBOw^j5#XmFeGz#_JwiX)YLB$+G$?AEcNtS$ z+lO<&Y$}6h;=Oyg(MCoSOPLqn($TX>H7-;BRXq(GtHCEF5zh-vF7hG04qpkk^&S3aERZ>&ZDD56hI!&+5 zw6&9kxDYnp43TMo(5G`i1Mf5_^U`+omrkM}{ZJ!6Bb}N5J=w=Hm11``rzM%@Dt4Dh z{1gGo`8zHCGB_$Sv%$yV(Ly8&zFTLS!i$0RD$;E>ca^i!8BjP|abu1Y4FZFpKhVv5 zwKUTj+6B^mT~8wbl@oPTmSHrZBp;PAd}drW)DY!l`?8~mPj#B%Ya#4a^?-fvR=2;= z#hm*I!`O7s)^-|c8VARIkr|(x)DFf_f%I#L^I-g=&+KN8ayJ#_>+HLAE71FGQF!_S z?B}oFj@T3q*0A^c!L2S1QaHYV=PBb&arS;U1)lf%!Hh+X+yb8cg-?G= zM@c;l>swfEZmuL{t?zAv$jjQ>bEm1NM3~cIHFXAPb91zvmXsyY(D~}>YO?`m{`JPa z_q&T!CJ8m8o=Y4y*3gWYqX^MRqs^bZ)&=Rytxb$(Xj%3h;(2Bmya*U^`yPWfg+G%q zPEmSuE-iNVV&5glQs@&qAI}fgv5ynY){0?TNRIvWj~&q+;I-%N`hhXIgK1 zkI&MxcOKVyo|c;@krZW%iiKscxmo1N!_S2ja@YY5(mtpKms2$x}?h;ReUDh@69hKX8%d zF{)m=M~oQNGd$9_NduYyp-J&Ef)W8QiRi=d|e6 zatxqkg(luF^jE{3tG_gXq;1hAz`q z29eKbI)}hVQiOv5!Z&vaH?0?)CVt*{t6XTVYh>xW3{hD0ZFGn+_vveKkc{)FR0sTK z1|T7TtIZ1#W$1@_;J9oAv}}yElZDw6R&iZ@dV91qi+x`JheO!Gfvt-Y5fM>9K!Ai0 z(s--GtLC$gVuQkX==^ab10xX13nT2Jrz+tV5=!%UWMunEwoai7BaA6T3dd=Wd?j*QW`5XV&dnzU3@$W@=O|OY)bLJ&4~BM7}gN zHH|c8V`5^;Zx9m88j02xJnITQ-$v_EMq-pP+JsuU~yCD)^Dk z-D3S*+8tHf>y}-h*bwUSdp3h0f>8>ixGbILt>r$z&E*QtVrjC6=c@)+0+z`ikwZ6! z8hk_Mi8ABqhbGz%A;d+ zO{t7|za%Hth8qJtl^DIwsl~oub#AxGNT{Fs<7Qi7nBq5Ge*+xKffMNMdt+*RWFE5KZ<*4NmKiRqviPT^H zO@Jc@6q^p#f_l8Yti3A5hcO28+6twsa=7i3ua0j6XLcH2a`t)led6z^_UD8b6BZOy zJ;k)vRa|oyK?I^>DI1Cls4gdwD-fMb$k~+RmrpJQPpz15 ziojn8xdj2SB_btlx`PpM)U8w0F^#GJ*yT*!#*Rbap75A44HtkT0SPqhT<>SoX>}$^ z2}MAzn>5xu^(+}A84ycd9-Y|y_<=PL&)YO2kYR(T^ay;cndw^;o?w0Y-eEmV++ z`*$j7L!=e=qaIsQ*MGY{vi1*qgvg!NJjANV?C>s2u1+Da{%Iy3PW6UW;lc=JfpiaY ziZi@ZJ%B&k&ldz<1vwMF0+;LQ`D(h<$NK=de;}*VCCJL4LNws(=Mx%~Bg_F6-|dtN zj0$GE7yuU#I)5V?EnygVXo#PJl!`d_i|ugU<5XoAJjV|#ZoQ1RzJn*bab0Nxq<7Hy^_>FKQ*Qp$G_&?R(? zxtBPf=;_?|!}Cr@Fr)hBc0ZPU(f%iDRkO$&X+bACB0sWjf3Bc;yOQ|O)g7_otv@~$ z&66Ll=lWp6pASAYyL>-92Psj%;uv$B*DFsQvE=D2ctY0k+uzb52R*mx_vhJU{iz%Mnj=#*O)&RaeIKw{5iFXz;|HUx!cr7n{goR zL~wOd9WQ3^9b^<4RgW`5Qkj8YC)WncY52jkOEE210x3k1L@I`74OM?qZ2jj}*6P%G zkZ!~}56EA-%F(!Fzk7!RrjfVbolxMP4?)#SlvUP>0UfmBjS#?Caa~DE7)AL(G9Uvi z!1qtn2FX2`_R$-ZnsMI3+q^zjRPlS&i5bpm!zn$f#Rp#FbE*fxIK_ay9;v2n;oaT= zJB+_fu6QsktCjkc67lKt!0UsUp*Xi{P0lwsI8cj{{O|lHu?e7+uhk!uAMMAiFA|&O zNj2TQ1|9s6w2dcB_w{uj9KZ~3WR@$vVz(v;S0KD7=8>&}BSc90Vzv^DtV7^pIbW;f zaqRV407)$z#fL)%A+&B|B9#hxfVcq8Y@mMtpzh!tWFR$$(j*?tF^w%!cLtgZ*PRC3 zJwdQP`y}n=ZdLzGs*A&1h%_$w_uA5g*6nL!h+IskI~qD;*`(MOrcz)yzyD zKL?XQu*b$UhVIQ#LufVBpA>DI ztQyEp^lCwI{ZO{RE6>BgL;?EBkMKDrxxP#Zh#xi% zlu#9v=8d z6Px4W>s1$;0A~MnOcosIfZ3H7)AOQ7c>ZqyXXYuY($ZgTB<;i27)$Z~$t^#7x4^ke9WP ztq0&i8W9=(k*t z3FJUhzuDQ~aS4^W{3SBekK49m0{$Ac9Y7rF8DUc?U(6!jGklxs52MnTkr z>Z_Y;CC}yROC2#t;fDc8n2^CniK={gdExi&WCFFg@XzAFMb!&YA&4UQCXxm)L(<+j z2On825oG=Wsvi1NCi-x8mMRixE3`_l^;rvySSR|koWm7`D4BxEG}&v0hWM0SeEHwm z?+1p8U=cQ*J0PyO&4mQ*4j(7)APx#E9vCHBr77;WU4o$Y(je}?|0%uhZG;ZBZBRpN zmbTh1n7ZCoru>yS6d)HpuuFL&_TKurAi#lYW;`JmG@8EH&Ja2D{9swxjMO6)xgc)ZGVu3){QfD`1?*%(Rzpw@$z$9 zTL6K;!$R*MGjny@oxqu{FV}9j3-YT%VOez_AmvDj;qjluYs_>Sz)0SWJd zfL4r*#`+Tl`#~+pO84OhBnP=vK>7R-IO&5f&GS%wFf_L-@rTNhm!8|Oy034#1h@k} zYhmm4U&#k7La1*4f^cegt!fN)GB3P<8Ic7T+=`|+&+DRT+~-Vsh-TzRIAOHO${p{yP+~VmOpd={*w()8rjRPQJD2>*Qy; zV-NS^_q#YV4&NU;(U)ss>U`cL75$TL?ZVC5)>5rYJcy1;n7Xd@DS({>9%DfV*dZO> z$OAgp>e}$q27>qx)5)v+ND(TinMznLRpXpBq|mMpJr>v4|MD3+Xmir}6>*@AoKUEn zdLWH>Lz*OM-OQsIN+k5qZWh7xc6t2fcWhNWbbh;?Qx{`n0tGz+yg7O79^7B0iU;{w z#JBfA0x@3p$zj(Hf@gs8X`ViOl>Duw3RH{=vQoC@PI(~DOj2=nq2n!Z(# zVzXg{d4wy>0>Jvw#w1X}R|hyb^^e>8{QM_~9>!_BC*yqRluQ6UG!pZ{0=Z%3=a0Yg zvE#f%$b8rb+L1i>mLQUU2{^5=GLBgt{J=LZ3OV##-C<~4xo!V`NGgud4dgl zC4M{QFgO`0pa5k}45dcJQdcz&0lo^a`B4G}UWqr*!FLn&zJkJ4WkH}M!3nHCj{$K~ zujiv#xID>8NdabntV@WWHK5i|&#hc1X3U2TUo_qIp0&~_Ca)46luFw5UA{l*#0zT2 zUrvGmfTpaaiT(YWe`-0rp|xeT7BY$mrj??|FCm}nHQwtw!BGvRQ?r>*=f3YH9F>*H z)kZY}IQO4N=sg>nR66S7*r)Q1%~^;0=oPJ-2nLwm6!vE({~;6@UcMB%?J0-J^2*YJ z*yNiOSEj;q8fKE0%=+ETgy%pyg#OqN1%rh8^}1R0UAR#kz@w~J?uuU&^Z&3dSgm;D zTd6=hSG4Evs^?X`#xvI~4_H=l-IbvtxU19m6c0QCt25b-7M;PS0V@}sDn<=N@HaAW zD9_dB$XFMry_XwPSNrReNv3Mqt4H^oRTEQR14{u6HrFgKb;m6C*Y=-It>{YYc1_d6 zHwuV-z^4a48rc+tDB{z)H4{YvFfQ=FU_4!~)AHzc7iX^fm0DZ&71uH-1b-$eMN3*Y zDX=dBv@7>6*YoDiusuY`vA;k5sFspW(2hKHu?knNrW=2h^w%)edGK>_i!m14@L?TH-GH%jA_Lin15NjdF&>`a3s5C;rrkz>8xuuRVhJiy5aT2voH>EWCEb~kpfrB+*jQ>}f?%`)`5>X6 zD1$s+O|9%S>XW*Jo>DI`k;L#z$>bj%(a(e##8sEp2kYv znItj~BR1XZTmR4+@5>bhYQZ4-R%z=u0fIWwJ9(@abZ&w4bnjgCIIiC~L=Juc-VFtF zCI=vV$^hRC=8DQQFZI^VOAvoY_o%iaLOV~^iWKw@kB-pM(L;iQq~+!N2h3WXuloeY z`T(H^yv5;fJm97lvGI@vMU{riV3jFo!4<@oc`C1HS@RHhZ*OuiGFw{mMMvJAdJh=au`@(Oa8Y7T7U&AzEmQY0H6)*FZx=d77@Zh zgsRu{5R|4;?mjCNX4d_p)3YyzWnT*%xLzn@{YMG;_})KCNDadmKMv~80VD->g!|W7 z!@4=x8Sdhrz{RhWTl_WD?7xCJc^nZRN0bVl_P@Zva=K11z|LK9(C|(S+_s`JT#_mg z!YaJK+|-Z~6GL7d*|jjOUhlNu57_U+r^!L%m5=^|6Dx9b4vdzuTTTqlK-$NS7A>kh zJRh}a@&Y|zi9;NchX)QJ`;|*jm20V^zI`*J?=-KCY##TIaxy=Nsq)8Fz5BLEFq?os z{Dc4Vyc_U5pV9n9Fw)R&d?9gE6Ly6_uD~#3Kut&VtmI(XCtLeaOid5hznrG1F-47; zdyJ0xRL!RFX?!C$8FYI%%Uk336We>K0z!Y~^kf>b_=2n#vQR#V{M6Q5#|(D#sfP!w zb10B>$e+jFXRWgybxm~0Y5ui5pv~T>9UlIdtj2m`fzxW~pycM1lT&uoSG=}7V(07p z*DzR^Tg6a`KJ$5$qAm;w1=sfbqE4swI`rYix?8a8&)GqXI=#kLTbq{R zHuB3C_EXAV_{#!5GY320TZ8Ae1PQ8M404-Itu~2x2~$sR_9XNpn7-E zP#=Ztz|D0$mM+sfTl47Vd>!*VE+XQ`YL8hbshP=hxfI?q=WTUkxvqYf*b+i+Thfim zQpWok2O%+I**0^$T-MXAt)h*wh|qsjo?qsg7Sp}xy|0VvJ)AX&6C!@{*vy`;pj5k9 z>sR!|^5=WY!(KJq)Vk)%@AmfgcX35WKrgaM{x9KX3>i*)5EZs?-?zF&F~K@8ricNE z0c=|WkRIGO1b^u_S!;oQb4PZc_p}b$#xwZ+bi%uVcr={wnbTst569c-q+FL@+%`H7 ziF+BJ{c3RC?>yO+k(ALS@EuHV_+qlyG(bU)6qH1pi!$a?YGj+b!*#~M2M6PMC3kg= zYMnM8k}zhD-_t78=04q-+C@g*ySUJvC{Cfbq+BrBRGz!?;$}K+ty=J@@x3iE_ACAM z6=+~b9fTWw>fNAG#uc?b-o71S)~nh@`a&h&24C8*z*gCrbS7is*2PIx>#Vx6rq@SD zh+LOisp$)3>OFmBtuOQATsDXIl8NI;_+mfn{jCA*^3W;;&F(QCKGf)j3(I9l3cyW( z+w{Or7@nFxIf&YQY117-P7|RLfPZReSFLl1zZ>t6gc-Nrp;EV5c6KykgNy64BBD0d zG9b9kWJx*o185n!Z1p6qGm}YGXFyn-`{yAIb*R7-7#eS5p?pJJx+v#Jn3lMr}% zoJ_)3DW~A7xD(?#b~QXZXDb)a@}57Q-~D~jF0K|ceJsEkE&cv+qS(;w$Ts|PwAa|1 zOb|apz<>9Ono!L4zv}k&@dYB%u6_<~zkcQDmg$(wX$oi}w=MO;vMpRI%F3oJ*$@)S znagE9mj7X?=&L05i&xQUv5cOFYiWJGXx=a2KK%-ODtM8nq8u4|B~v=7ua`-VCZ{&` z5|&;D%UD9tS@N}ob~2svQa22OWH^);1UNq5!D zWLV$o)BXJO?1*9o!Oh6jy}=sC%VA|(EoNwu&lZ#} zd535*x9YAur3Izelsi*NzSV1PK&Alb9$`7o4QzJbhOi}0XmWC~_wkrnSqGW#Y<7B+ zE)1GHnk|E}s+Kj~F~&tFNWDFJbKUq#Q|I1;wQ(q})@ElFHD;<{MZU`ykeU7cDKkA> zaUY@E70lLcK?#l5CsD*LL3= z=xl)ENS_=JOxci%zuZjuNB6o)0CcZo^Xxtc8)P^i17GwN-QCLOBkFQ3i*aqG8eryQ z^S+436nt|&=c*qNKq!;CkgeqM70Ys4CWTpXu!g&q*)F7l@Ef04cy*{=Q&Y^#+fwVYYX{W&782c{ zPKAWvoa`^;%EUdu!^1abgqi%RU=H=Ngqi3he}I0_BRBDVgz77MTM0?O`IfU7Lxx9x zVN5754DqW1Bp_jy@Xll(!GcIi;{iF zX($@kLSN*SCqi^PdRx7FOP{a9Jehn$bbFl;m_pVhT1S|*or%S-6D@Yd-~m8!tZ6if z`nbXI%1oa*1FY8}m>S6w& zBorm!V+j3pmF;T_5A{;9(naU>6?b_uU7MuRi`QOP}E&J{xE ze2pLSe3X7fpmWVv2#(>mB;g3QBiMhUAm)?K zs+J>v4L|~=N4X@XV1jci(!k%UmK6Gl{u*52;eK54Y5)8}=m#HCe57it^Oi$d49v%6 zxm9KFcwLS0Vv?zCk(0~@a4HUbcisv=A>^2B0ArWlm0aFCyxcCu)rAMQ?^pp@5SL>* zbcq5vz$4H-kmhi~aT)JFx|ajm(^e2X8I&uKnY#|(ulx+qrLL#G-=C`5FKql2mGiX0 zzPWH9+Ap+DH7N)RI2i)*+tVyS!9Z`f>{;t5bNVzDY=_}hQ>#l2w zH@*u;5j8RF9b-p1mwQ5m4S-m5;d;cB4_g|T(511PFIXFxpmf_0|4wq{XegU`^&yy^ z4tHCztn&mzrBE$G5}QZmxDaS+>F}U0PV_S9jQXdEaAZu?5!dL)M?-`Niq78MuiNOX z>lI4+TAi`|y(mbb;7l%y$!=9hA+t2=Dz^`Y9?=-P)avwMfgR$9`ukjN_R_Bll*UMZ zwz=yaU^@-Rk|JIEzI?AsqvgXHUMQl6c6xs65>&_ohM36rOn?q6Yn&Qvd=1Ha@Dfe$ zK0gXu*Wn8zK#zbB0rNb;*EK6qLZe$Jv#cgYPpif>`U}k@bZYoLH8BrQH`7@b8K1Y< zE$&G?a{AL5+!u{cp|M%y1N;V^V%uo~jZ|TP+U_Ea%Q5MZQT?D0sh3}oP}^PbigH1b z!R@?+?9n(f`_iO!t>hN!p!ASgL!PEg`W?gIjV+p*Ccn+PEVAa{hV`vPk4#5+y! zTg)xLd-#ojDx=`>Dn1fKQ2?Idq|C9MBod@v#g_}ZA-5P&C(Ckm@~A>Cb#OYQ8}Q1g zwGo`4WI{l|laTDJn#lT^Jjw>1;3U(r~YR&xXQc=nHAM=4=sL+^tE8|i> zXVmaVFz@tw`3gmsdRZSL*G5k&3m~M=xxt<+#`_e|uT$Zw5&ELHt&nuQ-<-)+mFPUw zS-~tuDHy8^)6OO;1LPYGA)ho|!N$UDK}7S4Bj1Ps?ORJS_cal)Jq6sZ9YK8}1Csba zI8Hg~_f8WS^+Jq9=f}n)_J!sWu($TXgE#}BheqVrf^Wg{VM6k{cm3`H!h|Kt!(Oura)(`bs|RE`ARa*DkQjHd`jJ?AiOJ;?rPF{DvE|+s;fa4NYZGN z5x^_qG>b(b$F$Su5u^80+-PNFf;qm1wnZEQG&E1hr+OLJ@)w613RXsvydq_8Wnp{a zV3D2NUUI7IPI>jIStZQ6QsIr3_=9=@zgh$JX8NgFU9c^mVNM1`Ht%=2`zpZ&dO|gv z2qFZPE!bsH^u%mmYnNsmf&jWsF<`=zbF_79grI5n}~2 zvat!9UXN1QkH=GAqbfiUJtbjx3AKXn4?9!eLvPD+MjyZisa;RQcT`Ko%K) zCuyE(;P#O!L=&AOBME#5ly;3Jr;h*jGnGC}3NWAuxK>#=( z7n9>KzFeEvXDTCZ%fywzWFQStKn=RTRCK1%{c`@IW{kyrlx!4LBb%PTxSemQpy@O# z`?gI9Q?fdoGXne8kDwC2T^AO74FoKkj0o|e&yY)Inow(QC1hIgYfTbum@m3+~e2!X*tbE3eQex zCp*nl1-F9R&3EpT*vE6II~uVOS#Ih%g+Hk3XoL^?gM%buwJ_ps#~o{dA+&fcroBaA9?go-0EfH?4}LL`F&l|uY7nMi6QtE~q_(d;*EIaw__Oc@D8T(HLk z_T7W7t5|gzfE25cB;N?LOW7&^G!&zNWyep9aWNRS>u0Z~t2)*evONCU%5eiL@VG|?X zYeodZ_}@v&#S~GYgp-zNyhR8ET&G%mj2Hbsf!h7BG0j_pIE=re%kF*?=VOryRh@(U zPI}5ZG-EPx6AU2>LfvpzzToDk9Q6};Leaavago9EI z4+{2q@~^f#WzzvxAp~o-^jARl1%woxFns%NmRtK|sIEX6mik_w3?=n$M^+9bR8~h1 z=wFl{o~wEgCsb%8zjg0jpoWbwn&4BHgF74NBF0cWitISbOAAtS*92%_$kVz(WBzl> zh%^%^LFGgL<%S<6r+>ByONM}+G5euWNKfYQaLzq(ZaWK&`WxBQ&mdjXddvCCbt+n6zQQ^)6ToG{j zlirFjL`z8o1PHWI@xtxPyXUw?`LOB(6};-IvpyWNVIswxN4T&`e0^w<>v#jpJ%P|`{p zI%TFWiyE4dLv*^vF5qvC!knRv!0{4@XOwiL zV<)nlXl}uc2cXdzmI=3x*7N9f|KV|INZ$)ATs20nlC)C~N>damCs?^2-QBOn@i_1R zVMM;5nfnS!*>~Cy;Pk5#wg_$1sjPYMZak! zk!E^kO7TG{z8?1X@N9Df*(Tj7Z~Faw0ejT~|9-Hbhk2M!_bvm*_%58M1c*~tOY?;* z#Lpk-uE4r)Q|a}KIB;zO+<|%8c*|H%dD}}e{D|(dAIqC9)a%aYsiUROrKOgVwqTdJ zITbx2_sH#m@eCk}bl6IMb)o9rqej|}mBgj{cN$qdhpJOIjIaP>$;lwaV% z;uvAwqFQQI}J8 zVB2=0YabsH$ZLz^I^*v}uy$8G(##FWWfU-+vwx>uy$t0epj&F6f9QVeCG0^TUL3{0 zz8l(Ll}v^w6OQPnl?Cd8QEB-}0J!i4$H?vQWlzIWD@Ro2ay7Uss8JV^h>mf6c){*m z(+WqI1NEX1A;&g=J|b)XUE)V*%}MJ>nJ|k zr7Lei41$s@qmVi4y$N&!_IKBS-1a#FRyD8m?pOHqVz7_h#bLbHF;{t@<AVT-9^VYPhJjiPE~TC7`?4K1RZMD|0;OqL&#p#H^pHY+#P2k74KyxWYCUp$Ne@~$ z2z71{skUPglo@EnN)U%ojRSzNSat=oIXHviVJZrCeiT4{6H?n$u_d$s>#4!Y-H$U{ z@2LYil6$q13hNpE3=tNeL%+G&rmnz+>~LR(TGHfKfSpJz}m{&mQFPQsm>YrCqs*v&* zIR*f{(;`o2mmCY+m?AW$D4b8KI(K0`KL)GtCI`@h%34~1{2HVx{Hmjl=MNxo-TZJO zlx6~MHRW|FZU#oRXw(kO{yg1Q+GI5XgIeEQxp&LxT0<1A8|zcedeJf&HGA`*4=4$n z0P+H{#j);<#+`wTvh;XT6vA{?RK2A#hnZ#>Aa{XNC1Nf^ZcD zV^3#>1i!>d6%q*zh+DAxR}8nJoLVY|6;L!=3uc1R$%l`i-S)T?zI~*J-V=ol%P*}Qo)GVpGkQ5X)0Mcm|*es zCo6|j1?;}{kCVm`r-^Kv6EmY|Jl6cE)EGd<+KCbJ1?BC9MTox!nDv0_0#0M(H-TQZ zr55J0s`wz)++4a`X|B?aK8iyQM`W0lu&@X5Vy9u#wec> zjuV?LpLd_V8v?9ww4UfrZaqL7U1ljedQp^p#dJ*BX)Bw znrqH6#~5>Ml$0;j^8-ZZLeKCYdr_3Gb#a_(sWeAHF!B*x-eD&1grs}UkVVD-jHFrA{1vmj_Phd#i6Uf{4XJcdm z0tVEtWKoXtn%$m;By35~_3U_hUeSGl(b)M1`|4o2Wi~ptuVG_ z)R|=+JH5(^v(h_QjJ1nWn2iSYa*fRM7k+fN!G{KO%Mx)~@~V!gSZ9pYE~UwGaoS{z zHkxqC92o|keFP`^S>0qebIEH5t~C}9Kd|K!S>zn`UBsECiUU&7ruh^1Z244e*HI}l?{ z(j=Sk9Ox%+dJD7wIIjC18Isax+M=v#kHA<41{+{)B-!mCz2Q!{_|A>yN-qWD%Rt%> z)2)2QF5^gXMwXzg8GG7jW$D(R9UgWE~ix)9#Xk-|^T}e#>J|kJy;n`CUAtY6Lal0H2_d1VU8;);0Kyzgn#7m{MQs*9S&7rF7$v+8!8^A0l zlOo>dv-;QpbYSyH<5h`+3OQxvkgP1$;oHQ%B4gu?+|1%HLmwm_c$1ywemUV0t4OvA zh=Fg6>Hd}|MkTMxf&^3E2@|if%1g1T*9{VcrNuH6DE;rTq=Tx?yVq}Wn>b*M7&%Cr z<#hs#v*~~}&%!uWbAkbcC-}?&LW;#W2ocAb$94sUgyTuNn)srr+}q%DxM;Tgc*^pW z&CKcVGxl7+F%R(cf##YNn)Q>niSo*yoq91`mCX-7^B=Bu;i7^R-l*~zY;hw;4b21U z%nhT(j+#7txkA_+Y$gmG0KBmPLbZ)0Gi+XP^b{N>glV2FmcPIqQI&7S%;FjpC94W- zW@L#6;@{nt_CFh0zN_3*nwRqaDcD;w1;q6}s#=!OD2W@Ac74TW{j& zTU}7^a%o=ueE;MFKo@AEz^>MW8hDNqM|g5bR6jb8DL}!0_bZn}R9Vz4Sx9h;0-GB| z_Gz_5izrqqAk_=f-wDAZNsqu;-Gj6HxhIj}mf825otYsgUYlp6n67tm6YnsEiyJJEOY*P;NM z?bJ;Y`ctgzV@0O*Y=eIfimsUU)WEhdV*!jHDsD}DgQ--`H36?d{W&wYCb-^JD&mW( z4L%iy(3Mk^pAh!`*;@ks9%jo>F+m}jRtM?aWWN&iaKq_&5qRjqr{yOQBQ-z)WdZiw zIs5`N1~Hh)mnn+l;xC{Q(w^t{gUZnjUa!I5nuJKanWt~pn%xtQS%FPzahFX&sk?7M zx|@UfRctLM@Y{h=9;Ve9p!5W!7TD0c0d}CYK2Qjka&Q8pS`*&V)AQF~v(vw!Ccvl% zN5+y`p$5@kTw7G7dnnsVxACKXArD;Qivs-)&MzG)Q4Z@kNocL1mj*;D{|EcUzRs3L zvAmtAG{jc3zW9JFfJ7KDp!@AACnO@Ob063{Oc-Z_{7GqT7ikxH`hE?Ye5+PwPiqrQ z^weel3Wf==5DM5tD!gaXmM5Gx#v3XQbox*I6=TlzX-0EtGYiKie+EDJ z_l?}d&d$a@f5d`tidmU1H5E_Y>g(X-v(66ufZwuAH%H0^CmiZ#>e%Gd2-!B@N0L|l zl=p3wncH$ko+W$z;dvhPB3VCHVzB$srUuv{vjjrZlyY&jJd`Z+x*HjI`s~m3uvc#J z+i|%J>b6}WIlX-{xE9u1eVRBusN>E}D$N+gTKS$_U~)R0+czb)Z^7iSOg;`zmIdic z7P%_G)oy>|FO1Cyk!DZTzaflgXdI|*eSNE}?D?-F!;pemW*&yok?2t)slx{A=(1-n zWsC_*Nc69wwz$YR{+bcTNPN2dlRWXDo67y4GkI%Qcsac1eH*WNb0)QW-)eG@1?}=) zO7iydc6OclqoPm20m7;=n|+#{RL>~dljJ6uciF~o7tBg6%Z^?NpBmZaJN=31l2Dg$ zUW`!6kf%RxA5&Q*{p$UZ#rQ)tj_iAZ-nK2+gnPGMZR#hFw0Zof;3}^0AEVD`c3jUm z?@GyAxhcH#Fn#4$MEHAy2MEOPY7dgc zICI|cS^pq&JFYVyW)hy`bfI~gpgv6|JA2RK7xw)}%x}t0W$e8&c|8Zy=$20NHvORh z_PjW|dopOzS5#VY{NrMkU!7I!a-k9Kcz1B3t|el?=I#4^%}hYlDL6Gre0s#Ast&mXE)vr;zkr`M3UJ zgETA2r)5ZaP_cEKK11<>D<%4t+v)vZ;LaAJVV^FF!m(?ncCJ-t^^`qDYk)1ZJ$+jl z+bqX^KV^JA1hbAkRCPuk-F+A0lTco88b4y1$5FJfpiG3JMiXJt)8?V3{+|4R?E$lP zHH@OOUn4GGl%*zI*m8DGerI4CO_a0bY^X&#k&vh0K?r}hEYh__1-$)bBuK{nZ&SMw zTH)G0Sjum?hJNupyp@%N*H`;cjY-jxJ_;$~Z0dtoTE5FQQvlcL8jY!O+E>YTJqNlN zSHkks)RokE2)qP*`y$7}BJD|S(5$d&L8-Ie^D;;21eO5AT~%emJTVtHMPvYBWo15A`$bg)yr(RAQZ zOrb&8Dyh?imzFuyMcUgxOWPr`RV@QdxCz>9)OOcb)H|bF9|ZAOrH~-5DN)A22r{V>dz9kyc+seC{>-FgNf8?mu5Lhw+zM zi+VJK`)Qr52SkL8P{jKg#lPh)a+9pNu9i{buW!Zv9!)6Jm2>;cisMV7+z$sYl(M`d zt-n7Z)ckqlD@D?CE94#HZ>2aoixRa~L*;zDf_!i`zpmow|cGT{c@f_5|uiBzLgsq5pPu+P%2D2qIkJl&HLo!-AsY6RxeMR# zkYi+K1yymV7hPO_t$o9{&mJ$~1p6g_Mp0tIt|H?SX$S}C9dSkHk^Ia)%cKc*TGPAi zZODXiCxy2a@3&$L$g*JESBQk;H+P9v>?frF^ndHt$95n0$_ywfV^+AV)lR!lO2{`* zsT><&tWMe42pMFp>PM(uz$4;oTaOosP>T%PJal13Z6ggPj*hbO6yd6%8Q03KiY^uU zmRiEC?0-IySG&uytQ|?=uT~q3&}3xVlXJ433E<<~XxY9@hM+1B(`l&ZX1RUN65QD?wKY+Q$`;eq z%|pAFHN;y3=i=7&HQz~V#!^{UFj{w0SRAALyn*(-8wvlJ#0}zdhF|fid|SJ>$~tAE z#hK(POw!jLy$kWGldc-4J>N}rcQ_GNC9gH(rJW7b{(E|cWL}FSdc3u&1lj(VwS2eY zbxPGp5vIbU_a24bzt}-LVZd5BWFtswl(hmv_TI7hwun&{itOIIgUH{_&PC zx3^)?Nv3NUgVnbVz=hYJY9v3@6EY@bpt^yi=*)1+{zdfC?s!f3V5VsG#lf#9;lvxPKl0N7ZEE7oF^3f*QH>KvE?{4;?~PbIom>@kQMyKRXJn1T`; z@+gcU*req8`N^!ds}^bHwE3}%j;QkWs2KD<x^kz#2QM$VJn<(lNvY7%-C=?@7z~d|8l;O zgY|9}jf1GvyVPIXckrp$N9&sqxv(@cX~xZ0jq@MMU6S9`qB05MHr!q*bOS&#SDE=& zpE+0V!P?xO;7lS}&hA$|<-Bc)>u#ExIksB$W1hprlauA2kaV>ACL_+bS^USJ^Vrc~ zgbqiCMsbGhcJZdW1xZC5t+!9rMRO||=ju8p^I&Pu_|NI?vOf-Y&4YY6jzTTr-YfEE z%@oLZ;5~+H{|}WmX51TjQhB&r*R6{c0SO^+Zw?G3n$sTziB2VW;=NcHf?Js~alAM_ zXgv(B(b4{991ItA*?icytbF(cygQ=>Jx%EK$DQ)G0!GQ%n}=psU5Ud ze2(8G2)m^ktGQ~J-MmMVxBN?nPwZaE)Har!C1YkC`tlYaH-KJ)PvsquK|4+LI>DTM zzvgG2gi4C&uN*Y^E|YD+$`Ems&qZxND!qo!sBHMR`tG>AQt3>_9#D_Q>TQ;c%tlT0 zID~(2@q>e|Dc>6g|Qsxg3hqU^#G zhpBM8#Jow$XYj^xHJvWw-Vb)n1Di2T>CY=3SGGyL#i(C6ogA)m!G2w>o3VM}H&#dz zN-=kz!me++kEG4?u6_P1zp3Mice@;yi`S(p)w=bIaa;Zv0XD4Wp5Lo`BC+bt;Y_DS z8`FEyEo&BYMx{803P~SxW*X?qIS}pb3?;TyRU@!UXj}LikQAEW(yxPr$|DFR*j)~; zVNF~c6LOefl*JKk=YYh?YgX^dZHG_s_*sCBo4!B9WEQvs1zaZ`+r*yxxisE%L0k#< zN(md!Yo8(K%EX0~M#}PAC*gD(jHr{dka=G8cB8Z3g5msgMiUU9eZXo(0h8<3l1$%gFFQ<6ej zqN|hQ8+lc6ly&D=j`=-ygF)%$_GkZIdz=Cr^;EbEJ?q(98kAZh=l>#q1o8mI$m`-XqK$_-`93rpoe?Esa+2JcSFI1Vtq*ROde7+9sMMz=ooNLQXK#M6+kFsqfNF7nFf=LUZ}-=v&{=Y8R`JwnF`TKwyw1|U@H z4<&G(uv1nw%cWtr!Yg&(aMiJIwN3ih|0*_iY`HBBjm+)|A79)9f7;upXcW8^sV};W z*a4U4iFjcBU8(bzeR5(MpVR%}Zoz&j4o9J@rB+Io13sMJ&BUiHxGsM%+9o@fIPT6H z+ zWQbt!|24?UI~mL8p}hn)h^92g`?K@5W^jt?Fv#r8K@YeND(UAe$H&3hg#xB0hI06x z`A%bYRdb2ycuYucm$JAa-pkY^^$~-058G^6$ub9ENg5~jUad0 z#QWXR;yY~LYdwRRIl;o?JX=ziC%>i9h3QMPm&^=3ciXw9#aR1av!2g@TrbZn&ckmp z9B!Mlf4ha?c`aNjfQ#41g+*{PU6;|0;kayfuNUP!N(b)X4ti?oluGFL>NPge^kyE| zSp;!;pCa@ErN=Zt5mfywyB_7anJwqLOe(AvolR!`lJw4(MjOU}jn);*j5S@y1g0=^ z%P2y?=BEHD07nk|;qk_FUY6DT&tiyd?&*@=yageBQVb9EoUJESJ=t3AZTX>GP7z1z zJ2#I@260f=D^ElHmU#(QbK7ZCt}YDc^0aW7khUJMg==`D^NmTTAA4`f@lj9H-dAY& zx4Ab4SL##0Em9`MwC4jiKW;$<5p8P5^XBwd_v+AvI6w#QSSp5i5Np9t3_v->=lTt)PUOE!r{*8qd@J0s zg&c-}l}L!b`7kuniy|3*uD03VxVNxzp{rB$)}E{BbQBGLF(S3Hd+9`Uaef+2wiPhM z4a_VIiu)Ov0qj+6OC~?In&c`4MqAn~|FImAqSgZMtK;;nTS3Vfc0KhT{Smq)z7g(C zKkbk3|23iiWLcRtl(?KR;pHKEO7PAzc)o?_Dsj2;{WLS7;egi8w~#@$8Y%l0!l#&< z;(wQq*f-!UP=)oC)3oj_&110g5<)wtla8Ut`zP+kZCHsKW#HWQ?8{EUfo2wEUCOXU zz7Ja~p!XmUr375qfC&=|b?xr(c%S@KZ1OYU=A^8NaD+3e9BI3fB`L$*FP(&uwa7o1 zXs1(;LXsY@tJ5uRceBcc4Qhw~8DJo4Y*5|we5ve7t!*bgXbOuQyd3 z^99B9(9#n4&f-nZ?sK--Z#EjtDG*2eUDCV9D=m=@al?6Wl<9wR!$U5$m1UQM)Be!$ zov&pGpqAuq({ex!2qF7~($89jYMZ$apteKqucxZe1x(9zB}64M#yiLjh!Y9hR@-({ zH>l|8?&IU`ZMxg&2>0dJ)i_Fbg8|bqrLWM$n*4Kc*4^&hhtF8QHGq^G6PlpX2vga@ zk`u?KrtJFW+=vL69Goc-y7l2zOu1|CkTyM3wpr9`L+(#tt8&zkP{>c8vjO$yKjL~< zjyVO(SAi(+g7|=K+x1IE@;*uVOUpcT63V}*bBTCeEiKj86|&XT0ry;I@^=o_hQd5h zn1Aq7QuJz?#eZr4c){8>`kpOt5Y1=8g@3(EyPVkAC%d%6)#tYb2|wY)Z4?^3r(-B% zIu_^zZS&mzPr{rdXJ1RAi7N`SIr2168|#vHc2DYsPH=Q8+3em3*j{!Q@VC=ZnK`B) zs)xf?ld{vBvB;PJ=hLF$4wfAKk^HIw{>0Xy1#VykiWkZuiE{fT3iZ<4l5c_ULr%(s zCGfmn7s%%@*-!7cgPsuW^ID@DJ8}3d z{G&L!1|TR&Bc5K^y(h~H0{(GTw`e67XN#CdHBx%llT{4WK?I4|CsKm^G>90w9vw7E#Zvi8hOc{J_H4lxr-s> zh})G-w~{V=tsZU>@~AsGm+{CEwH5bZ$$Bdt*=0*kr-gKDl;Lwmi|Ah=V%!Gag~x^| zZf&CV!srxq%ft?!E+LY-%&W~bxt6bEcE01|e@EY2BuS6^Z?d_+4y zBz(?C`Ph<5Cmo0%W||Ard;J`ts<{HuJ}L=XkM&zI1)sLVx@M&K_VavFuJj_Tyr|QHkF>V~==ZoNN( z`-J)Z$4N8P!B`OVbG_xWGA`*@H4?KDUng*IGV8+D|M(brq?ocnqPWF!)dGTvG}1`3 zmWy`JLzaqt%|kS-wtNz%zsIN;WfO*;`j5p_+Z4?L6^CoWkd)R8CB zaWgoirFa5#_xzCKRKfLa3iMUX$g6FWlL`ucji^;@mbMhc88%^Ia4EEKmC+o&)enkD99X5>*mAn6IPaLOCgMYr{SBeUdw1o@Hxa%C0Jx%q+NoZDMa4zE zB0R=G$IRt8$RQ{HLcU^eIP8y&6o!Z`?nfN_X8~GTk&;QgR3yb$txsfrcMcA#s41G> zDg8&JgOmT@e8>~jjLne&$UDUWn)8rS9YhEz;qwsg)V?$U8!HyYKSxIy0CRh!X_TYg zLkpQ6a(PEual)g*VlcVvq4v$+dt-O)5^9kH$5wYm5BPLwJphrVu7#&7L5!Z z;u2bZ^a0f{JieP~ukG3D6sVwNl5}#|kG8X~ID>Pj3R9%`6TZW4IH)$=FR{f#&B9R! zi0LSuV18HK$h{gb!dM21P|JL7o= zkIe?Gr=dg;I#F#zcEJg1eN`~9UH?NPt-}QvGJ$0cKHA;K?Tr;OguBm5+UOy{|Ev zIVYP#zZ~J0^4mzjHvd9Dtivsy7%DUr2}tA-z)6Kz%ocz+E$tQ>aG>l&(XYoxW`gA;Z5Pn|n zF)8Xrx4I14^HOLjLi5GT*DPbd!#Pn%1}tNt0~u$_fF&IHRXAzr5xE|-2dt&LBZKm5KX$B{@?%!_qYpV$reC zc}r>=At$v^sO+L6*%aFdY*J7MzhRAi!<^a-i5I6hWhWLiE!!AbL+C}bc;lC-{@A8? zN(F?lw`%WV9|CyC}k@I6i0Ahxq9Db!ZMz6)>{IYS(HX+Q<^0! zrY!wR%}W9u+u3M!3jc8j(wvo`cK(M=1|L&kui4Y#b>~#)>PNuqeigU-&na)g?F@Vt zurSMJO9qlD@FS0Adp3#l;WXX9Exb7AV*%0N$90Af5h*s#6dZf>D_5u=JWzW1a(jC_ zEiG-c=oe+5f1&m+=@;H|n`?b@0(!CwJzI8$=WFhSb>D9{Mo2x{x|649d|)JZ|7}9B z2iiT|Yby>THoSWL12Tzny^@M<(xHdqW&YYrz`0d=3R0ri343#c652zxx#hkN=MHKg z=~~f$mK%tp1EF-8IOJ?8DyU}zDXis|f*$T)U)blAD$)1FQWlG+c^Q$TPQlYTyEQgG z{z6z-p-1)QOOGnrJt8OZ;?w*aSr{V=K=ZJuY0@u4oI%euz57_AtkEkyuUX;$f2G}h zVZyQ9c)Fc?hZeHxk0rBWI&Stq90qyychM`Pka!3ya_g9E@a^0zidlBK%7lbxzxXP% zI@zt4T;4Dmyxbyga~D{C#*d3LF1!hPUaW{;tx|MsY39VcolIYqPG4qjrB2_)Cuz_3 z82pL`H3Hw7yKQi9ogP_pM*0U8HZ?Vsm-C%6|E72B+yjLRiiOK_X?!ET!bUTWG(M*8 zc_TIuO*4F4eH-ui3YQ65Uw?8dTDc58PVy#ct=sD60_Vy!U04rVml^d5uhNDs?>3)K zmpS6*z|NW-ugX4ejbnzomz+W0t2N{9sW9LSp%kH5Sfh>Kave3b?hK$?0BsN8D#_eskAh*rgp4=ngFbz7X;eK{?uM@0=V>D& z5Y`<}D+i30IrVHQC|8OHf+TVtk6DM77`maa;20^)3~4-9?87V&S-Wk`)J|;D@YZ3I zyk&?|(AC_~aDII~CMcn~HA;=%aQj%!E4F+|r1i`hZ?e{`ATg(y4>;TWOdv3~?galQ zP+unmn^++F2D~@J-sLLjAztA>zA>B~Oo{HE9b=g}`mkt{V8Ea~)1H*A(Nz3P*kuXm z`}T-|E#PdWQ0(c;E=3ykotL>&Ui+^CCI_Zafr}HNy_wd@>MOYKJ~%l9A`b|24bcB9 z-HkNm8lrLRw3QuyByK|J`&9TuQaZDNB^x(eRfc?v@U_22!v09dgMyHpX6a{p&z#Th zmJ{EkUaHw?$|Tv+uwdNs{{SY0@ap8{5OcnU8$=^#Kb5ZiSbP(L=RR_LGjfvnw*bPt zfq9o*~kk&UfweH~TsG!(3> z)8pgV&ktXmBMhKROd8i?+q{|2!E98z7pY1d;f~dp_(S9$4}Za`_(~RNwRybQF9$DT_jZ#__>WXCyx=#l>tKo2IkS#Yrsii1CU^Kd$&55g|iu@bbul{Nz=buuluh@&-B zC4YPQ1-E(pKN_e+3(tiKA36VHqlcywj7=z)4MSJN_9l&-eC-tyic^{A%^qq1$)E+f z%;-22+MA{fOw!MeuDP)DTx8SiacaJ5-91UxTmIk&gfpJT2Z^zvPmSzo($rtdnKHde zAJO>`#}`@;c5IA;p>4v&sH>}*w`1d6#jR~n@J4M!{6a$2J$N^6tAXs*3~l-myfXC4 zU*F&;VeM->h~m9+oA*OO!vVc=OGCflv}UVjCrtO*dPVi8UTN&1Ged#HsS4~{t`ahD z9bBsPg(K9%~yWYt6e5KdMldG98tGPrRmC@*^BOe z(0*eWvDlj;t`qZRH>Y4vy>FV6bK%!TTc`cnXi>_q_McV$-`{>YwS!EFJ-RXBdNL_^ z#?HjFS~5dsS(ZAq1{X6=IK||Bh7=AOo2PkMd3^j)_8N5+f$!MMmos$Fx9drOpSkZw znbp~Q8eSmuoAAO|4j!^pZ4{u(%cO}Qlv+XOx)0(?(3 zDs4ak0J-bYBRpvXpGVqhW=+Qbc<#Ej7QS5)abtjxpKEb1-Jm@FJ6Ege$hC*e8tp?@ zLpgxzL|e(^0Z_ZZW6G_Qjsq?E$1ix>$7BmbUCwABP2*L?Lk0)$^12hNRK^NaShwA> zZ(&gMR$iQ!EmkdV?JUq=?8M^p@ozA4_KGQwhQxQ12FLlwE zp?>S=w6&+PHSBHx8P}CFwPSf@L8pD1qoPx>mFQkEi3g(R8@C2_KCRgo6reQ*SSq;W zsHnbii-$lA;CN&cf!Ub$DfQWlIK-Dn_=^eILjgNt?2KzBeAs z?{iWgir7M86HqGrH+*#2_2aCuAUTLa>7yLYxrXXMl<12r+$0!^0MrP1?dTgCQYbN- zrsrLqOk_$?cHjH+V=o5lsD^b)QwHLO@52+FbYA8vl%Y}D&A|2pF=Zl- zhyBH}Y1P4mllbwo$D7zZLnl+72aX5p`-|NK>L)u3?eNQZo_21;>GM-c+sjRx0fMf_ zi;4K_6a4p1Jd=`Qlv2LE2!)^VV|}y}#D7-p`2yY>dhS(Qvbcz(II}tuq`kNkO2R4^ z%~PO$T%6l8*tZ)HAb9@1;p=32n)4`@!ZN?eN)a9BORsU+S2C`I>@Hc2VLMCdNv~D6=dU_%l}yIl`%k!%RmA7N z+$VXX`RNef@auj<8eE*`R`y}3k4ZHnY2RGnG_UN$_v|+}N9olHY)qWp8XmDSBa`NI zVu)s@t$X)S6!0uatX6_-QsA!YqiA?e)^c1y*B#=sKgCs_EZdr`Q82r|YeeR<8FaKoQRo!2f z=3qzf#b?)x+XK1tB^7inADB!S=`Q4tA~-4I>b8#e_=WX;g!ccu|KeEkQ9(q`QRi?Z z%1(FX3Q(jxc(DP4%ON5RQk91uu2Dv2ZD@ z6j+?7@LY^j9B{4uT*AR|4oRhp=3b^&j($UbdRaHxeMdO;mBG#u8xt%ZeLlAd=kZeR z+!R*Lw_ou{y30S}UEon_`I9zXJgi@mP=%+gZc2&59(Zf%uGMZ%_I%=5tCTDDa zu#{Y}ls%67|C}|G(#zuD7p>TDE==Pf5;=R*ihl$?4l{FPaef87%69tD5!e zQ%<+;_xV>n$};D%+Z+~rKiEx(r1rG5E&B&Bn_^NczT)ncfG)wVu!Xp%08TEDnzu9v zjTsnlHO97a8lk=C6SKOydj52y;-F)9smjohyM^m}d8ujf>5Y55T;i(3W%gW4Ia(T| zx~kmor;K`TkxNPQCy{&#aw`?O=|`D(b3f$`{;zv*WIaq?Ji|@ z%rEdOPe0uAYdOGnbjLfdI(qAqPl?k^nO|n5^s+cejbb!iP0hrxtb*C8^wZxM`VUnv z;4!udF-wL_=NEckZl1V`*I;}F>m6ytMEG|sU znHEgLNL3z9DWCC|7OjR(!x#3+z|uhDjl5y340dR+jnYt4%l%dYw9Ls?U6l^L*qSC* zxR2hLZR3Lpfyx9naGL;R_(;&pBT)B)#D1Y0Nd3*+P@rZU~?{+8@0T^MCQ;qQs?m|7jt#7zfy9 zn;JqH;OYY}8j{(B=tQLOw8p9jlLx@hXjzp_fSC9Du&|Ww>bzC1XQ?3}NJ{QpJPKia z(mru3%}h$5AK^eW zS~U7{zv|sdX2D5I0oUarso?Y5V!8(hgr2IiC5qv)vh3e^qR()gHP;`I`5BMG2d~fV zY>ziXzRME>hb|EvIlNV+U)5|Mm_cafF6J}WpYk=sV06vmNKh0KXWpcw&e~Jw^Lf;Z zb!RC(6ABu?i$$-UE2#eJ&tVk2ksUE$XO#3pV!yaRUAPCHs>`o1Uk)naVfSOL{kfzIER z8}NknEw}~l%|{f(r4d_R4f!qAmJQ6=+l$P%zE=ZGaKl7+zC|S=wZFcrC`)Wx>WWVE zQ-7e^Wepdqv$Nsrk-%f#=6gT~BP2zhD?jvQJ~0x$fpOgET-#3UgUa}LuTIRTB zXbvU{8eQj)gIDxHq}e)_t2b-@HBa&_oM~trH^IJlj^x|O#M%78qS>IGwA(Blvq7V) z+vb$1(@A=Fx2lv8Vt7`-#WBu6ZWlq})XLZ$kF+g_o$H@A?u@yRA&`n?xwupIGGI4X zq^EK5g1U-*vVqE^$Z*s$b6o9Dg|8d|Ct_$aB9#qM{tSOE>r1}vN=<*d5$T<;Vf~9M z0XpSKzugFh?G26NspbB0>2NtE(jd345rf@(^o^3+X$B{ICku1okO1lV<>y@0G|4t& zFHWs-S(8w;&gzQ^|G z7?BhozudNyh<9R0Nx8puuvs6})MVkr9ciccJATPeoxys!XDyhSzMTqrZgIP#(%5M) zWzzNhbmjgl>0PZOUaI(+e|BUPn>6&+q@*4*vlb~bcj?O}n57tSu4~QratwQBRZ*Jj zS!vw67TU=R-72uDeLK+PBM~>#<5S5ku9b&5lU{H22qT}_ixl(JeP-%(5H2_)EGoZY zwB*vIaCA6}|Kde#Xt)!ru7Eb`dX>K$kLpd~Qd2$tqs^89rR=F9n`GFCFibhXZ}U-N}}``RN<-W0)Tg!qWX@7>Ji?`uS ze}t9EFNQym6|1B&@3g-<;7_(7`3SDvuwCHIAyggfF+<+H>mPcqWCGbyd5l`bmEloR zf6holTbzx(D$kX9sv^+ybz<>D3uC#JHbx4@b#xBi3~rhl7)XBk&&^x@4$2M~SwJyD z=@oanK7pfQ-AD|BWu)R=L=gNs$e<+3|ADdxsVbQm_8b}Q>vq_Y3sAWvUuQJiB#x6c zIVgrM@k_;nP4|60$v1)Fv_?ZVOdQUX=9#;ylY(-Gcg=ibzMOk7H3o&H$Ok|QTUaZ) z;77ivvbjc+9?Ppnl@v;7=*^CX7EpDv{-tQb@fPhs?pForyP7#_#XHvs$H~9vfOM20 zzq_fCi((zXAH7hA3odKqSDyTeld7#_G#yjMi}Wl^$t*MgE&HvkSo=%8=oBT*5zR&6 z{C`q6pRk`6sAc_Gl#o|d*INCEH!FBJ#gFdU-J{!9uy3=Pvs=@XD(3nwu)LHGRV7^x zr%xV;hTC8C-uf*dvlc#EAf=?Uf66rZu`diP6Gg=I>KPQ-_^M zG}A>H^X{GgILB4(R?26*lU;+B+z(`)&^VzkhM2rYGKEQs~-#p?R6awN-~J z`@Fvc1db6ETe~)8oQ^L{=E<&Werm!uOo9tZo7s6o%HC+$bAa-HpQOCpKj)qH?=k#k z@GIefNGft@GTTsBQ<8 zPgn?d{SBYL7;eLM-8dSK#q9Tz)rUn_o|Dn&TLGK2uiFL^q-W!`kFi$OKciZW za`<|lel0LR+3xhlb=dGcm~c3Ve*OZBb@=UP#`)1Wqxc1>b9-iNe-dUxbD#rgV_d<} zTZ3)3Vj=LueK6=%D=Rsx(h148|F9D5-4BzVA&P5dGgzaR>JZmT-TEDVv0xzzBf5N{ zv43R8D|&FrU#h1l+Gh~z`i#AdesIF)&t7$dM7X;cED2GS+Hn;kqRk%R{i6nTvR6=z zXKLc_3`Q^$cxU~4h8O8AkN{DWdy@(ITTXd!$|$#Ywupm=Z;eErnw9{ArSqAmzxi2a z4qtBcjHN${oA_a3l4ktC-~~6aRQ6O&#G8A>*AzWI4F*jJR=r>4<=FZCfbs$Vbre-U z@?%jW@fl)UD@Gmv@#-StJ^sR`w@mjMB5u=z#PI)I`LZ$7?`uap&p=Z@ejyO3mS^Yz zOgcEi>diPr-~;NbT&vSjvLs02S4b$0xs%Mcs$r^%?*@(zV|pj6)w!M|_-q!RQ3Vi4 zJnIq>YN(o8u_x-~mg(cMVIhu2pI86XSuD`~2qs{m+0*L&iak=`lZ=gNAOX|JD ztIDeZ8^8PrCdDW!YQPMPvcqHYfQJGaM=KZ*;)}y>AugXXzKIaxke%-bUmba6%$Mtq zT@807AJ_j*pl0*}x6^dp13sZ=Ns_-_-C1X|^-7$0If}Sl$%~sU#;oYH%T&)U?I}uj zSF@|9_Uc#_W~$Ffp0`MlYiuKkWpCzv8-lL$NlE=DY@T!%Bp0AfndEzLxCSz!|K;~s z(R(cxfFc)*2G&AGH?FPZ{2So)|7lQ==+(rW^zd%LT1o6(3|7GrWewj(p%i6$Lm&=c z!Qd8FA52Oh5T=j*r@2^4ZmH%k(cm8#nE`GiXlzE-gz%w5sJNKM$(((XD-KfSMH%m#aZ#911xaY6w)%GleKC+{=t@^6+Tu}i$t zCMnrVkXwH(rv~)BU2LT3>4bjv6b2%W1`O6<6m7Kp2UhoBFrY5$X2a48=cI{&Xle17 z-E{w!A0{Ft{jrs8fgo?Sl4EbEWU_ugCVBxUgg4p8ko)JvG%vP@*2_#BCn++|Wm0zb>W1H2`qIK`#P|P0`-1?;Phm;_YZOs3 zo9!TF`4dAKHRb_M4b(Iq4-RoT44J5r5|NnO{hAN?<8Y!N_0gO6TJked;K(`znXuIz zgsBNrR8Isfa{ z6wVJJH;?6TwOw8+DEc?Lx6A}gSe7JvgBzI#1GNwu+SD``aQ!TmdBL2@PvpLdffe^e zg3@chT4ma|n^^5Wg8K;k@917Z676rz|0Jr-@gB|=2&F9YJB1vIatCOw3b@(=oln_I zaG7Hxq8CRn(S<6ZWzS!-11;;PSafnQki66g9#?El`_Ev9p`0WMKR{F~M@!09#J9;3_ zP5MlD9*VqsSOb$s!?>K-kl}|}ZVTVOt@x0EY-#tl`5X+YBHWp}#B0E(iJIOc(~m$N zOTGwvdzobDgDsX?mh^;tNAnd^jcE+N47;HmP;dp?J?`dtgPl)*$AO*umsUa0HBsab zp^#C~SJ;F%+-RlRlD2<-1%VOFsutNH|P;cE)Kx_Hr+5T;+fC38@w&Re* zucY-%u`oVhw~+ln4{vB(ei~isLbTJ~08JQWmlJ z&n&`V{DqBgmD9L^gl)Z>%hd)gKiDF zr`73O*Gm_WMT?;mKqYz*!-d3A2}lSFhTp*E_{Jq+0fz2i5QuVs?z6mA!m*fOa5Ri) zVW<=!zlMNrZpvtY^P@^|K7s?alAn3rz~g`w3UD$^6XBSxY-Mx)=PLDyq+I{6R|(IM z-~Qk3W7K{4(=~D*w2E7D0ySp5S5Vie?m3q9@1kKAL6&*^s2G_11m18$_~Zv)Jx7>w z@i!fU{JHNDx}i6Hg(ZK9J>|^zhw4*3p3&^voF@*$j$JdJAn~$Mj+!mYO|M;A9})t6 z?l3W&!}U)9$k6|z$jlaS3nSu0!E2mfMs8zM zNA;Qb1c|S4&Eiub2IW2e>$HKS%|qm$J789*!3>T2vGu+}h{Zh2E7QC_ zceT(R`f?eqVi2wWHO)#~F?58RLnz1JfG%`bPnI9tz+gb3Q~;Ab8X_Nn3@um*2U2dq zIDC`+X1GuDwv#QUoK*?ACBTII+nb2n62VP#UltSuM7D!$rlTUDd9nWlSsOM47qf#h z6I|p9$=?XOV9ylj{Jc3nT`uVOR`l{~L=#DkV+`lG90&=$sl7HY0d&oEE33}4*+ypN zl*Hv?f)fbFnT|UrV458h6(tcgX_hiooz`ddsHYFk7tfCQ#$$WD^hSunKeR_cW^{O_ zvVrqJminP`U-J;CU%;*adC`;odT6!#Ps7Z1S3kYOS+XH&=n%jEVG-z^schZ9@&0RO zVIh$Mn z#Ht?V7?-sc6&KEr26lUfspWBk!sosi^*0Z}eFQfmN2tm)nh@!Y2!5V~r!4K#Zi%e{ z($dZx&U&nuHNaHPhT_V9tpV{sqJh^AdQT*xoMk@kHcvyHnaX8_F36AS+55f$Vo}yc zUvcdLJYoPg=i2WN<;I4HK%4}No$P#HUf;I(5^hyYg+B*hPg;Q z-F6twEu-VW3a}-<3|$WTQoN75pXCI%iK_8h(3QLqwnPXXnr*6P_XXf7tr&aID|={l{L3B8u!? zRub8p$R?G&v-jRJD>aW<*(+OQXN!=X+3$LKzdzq`{J#J6kB;NHU-y08*F4Yj zUN1+9R>6n3=nVJyEKO;5Af*5wyDex^g5r95-U=@urh%e9(yc1+cPY+{by5H4EqYBN zH`~Z$yUX>BKChs|=({g)s#Hi9Dz|_~gAnZs1^74Rbp6FC6AYyRRRvSdUnI-YXDr3( zX=6wZ9R3U0v%-<9>5wcacE%emEePA(03Y}As60d(`%VE}KZm1-f?|^u4R}pEnZK!& z%8QImW^i&+OG5L{R1Ge+pWy{RW|4hdwW8B8AzGBNOKFMr>WMSB;P5Yi)(6pxsJ2y= zQ&oD+;Mnl^l8{V(9-hBfyrAIs0ibaK4C$R?)xUD8yb{NLr7^cADS^)=PyvX3pV8u^ z011@xs^9y31G?G`Br#VSUl8<*JHCeDH?#s*pndVK_ir2kQ+6hXIFPaXLFwU1_ijDL zUWE3D;r^wYhf{s0=SO@_jjzbay=Td%a(bVx=9RZ4FvdZh0JX%L2zlYBXe`W-+;kon zh9qC3qxk|Lb7?8#M&{P+eUhw*G;^7J3?3(C;2RK7KvhIGh*l8s=w)YlNIbD;umCcZ zF~Cns`2{#DB$B|%BV!XCxk=?h(ZcpM-Z@iVoMKf240o&koTO0B7Ee-IlK;C&*BvHx zVd5u6Y2b$7=H(@hFBKjpQXl{BKaLEUX-^;q1IVxppyo<*0gQScw_`?~!|&SRNT){C zYEuaU4}_izQkpn|*9~c;leMpqK=mM^Xy`QyJEaI!$kCGIiYxo;5(xtu_%GL=#O_P*JR~CQFRsRDjwP! zslj+2#^1G#ksww8(dM(3@-4R98h{_JJC;JEAW%-_4$D&hVb(dWtUhq+WQe5nBbJTC zx+Vi}woaV_7!Q)?^g-gU&F`|2=);lWuwqAj1T%@kVFQqac&ILOejmg1jMP1dWn8V= zte|TO)9A^C_?P&M7)WIxHjeJ>|3WOKFHwMKNfN_#!695^)_9(}k@cn9Isw|bz|vg% zB>2N#j`XFEnl?{({+qu6 z^8gI<`h_V$04P>qaftK+x5=wVe1`sW8*X0pnPuHGC-W2gNs*Nz6_SfcRt27C+d|pj zV%J9?y>#T}Lma&?s-lLpK?Wt zNNAk>t3bcuZ`O_v)xQVP`&1%`$qQ9kHGWq8*4OT%a(8{z(J2v*KgCYsSgm=!`IT~a z7`+c4i0jeLJR=y2ndZkFk?aSMAcM`+L|w%)$w5BcGkS$}2-!LBqq zEf}k~f+jmaji8(K3sIguXL^>n-D;@?G*JYnCU9)Vj{4SPreQ1&NbscUm|XNJd3yj0 z0eKQ&c~*A{TaCDH+`9E+dwamNTt)ccUHed<1jqG8^@D)@y}e)6G)yOp5x~WO%coJ1 zDAb+y?d}Xf`Vy!T3fy#b3w~ZE9a=4hliD^_Nsp?|QSL8)xzWI~pq{$UE#8mfcf3#- zz?%`Oc-)Ye&a(YW$Ywr&e5aA0X8q9c@aSDZmi$i^3l{-dr@Aiw+(^YU&lC2^)3HBq zd1Zt~wfrlsCPpjISm)fWw|+`RhbfUJE^STiFSf-eJ6!6WOmJ}2{Se~wzGW+e9Z*gD zWXyDVAFKaSt!X6IO?dz~PfICvZ2BX!VtIO->&9Aj9vek#NK%Az5hEL^t(e}yyG6j@ z!vGD$VBdR^E z&lBd^@SiTRO}p&IcX%4@HV5{48Wpj!?siVe`~qhHZEmP;UUeP0`L%!m&*S>O7R$HD zK>044@d1;?+7rm@2E)jK(f`g4JOQSfHlXtX*92I8dfI!GnU#Ruj6;(G93wh<&71%J z<|j`I*XB(G?M3TpAa=gOEXTr0k4}#()Bx;EOJ7vQ?xq#;=vUkpUw%FN-SaS>Dr&7n zB!HLUeK=7{P97iP*V4&T3|q--6k8`C!BHYhemkTeaLjVgCWJdCA7zxF&~&zQut0v^*p zY>+Q!y6Tatt1lUBz&GDmS~NOj_qh!IdbTt}y499^T`@aM(Q)iH;y29&(%P}VdQxs_ zyk2EXD03M9-TPBdCi5(CLR4QD3s;BY1nKx?sMff>GC)@n(?8S*GQA~lX7p^JBhesuD zbo{R$aZyeJCRzE7+t8AK$u{s@eE?!`lb2n5dM$rGSaxtywd14O@6 zrT_*gW!bP`m|-}1vGG|Dua$!iy@|MRpzPtVm=ckf&fPM~qv?0DJA z)o@KGE|{?+OVX()2qK0gura zV{<^kTYDWr@p2&k;(<%GEHI22nLQ;_qoH->=I5>)>sN-+pn(F}m?$qW1A#&S$)^op zhR-&uja91_C%IH^jdm0-SS-vHDG|i#WH&8&ze$$Ya!@0rUJ!)eISO;4Xhfx8UKPOn zelMp$?#m;=eSlUOCLed*|8@QShNwVETSB?D$Z6!jO}L- zpULpZ`Lm&>{M_hlmkPq6;4gm2F#H(l#Z|8MjRM;b#0RF?(<^S;qUfeC5;I*Gh`YO8 zr$me`zbGTJ;ZTrLe=n4G)w`I_OK8IT+`?%+wCkOm`ow2)eeG*00a&7UhYZpWJ(t!S z$AV);f0Rjqu$%}1>6_+fuE=EfNuyvVH>R!vc8G4Hb(vUox{pnzRHlZwK z?Lk@6Y!9Gb%Cy(C(VSfd`(VTxNUor04G^Xv8x&%)$s6QoF-oG#D=xoSKUPfrmi@@1 zfE4tLI%DMoF}r1E=9>UP^ZG@93(#bc_RwzT^3Zx6wC|%Y-nCCdoDAuj1E-RcuY+?iLg}A-j94mQBPb{ zE+DQts(_+*;Zn{?HRXM6tVLF)ey5QfGx&*doLeKL7*c(5}g`Xe)jSzdd0D44?s%K zI9{|V5aiK9PYu}k_uM^^MRS!)m*omFBOz8!)w&IeY9%}Bpx_8TwdJetnAjx?a>6I% z9swF0cH5NwV_B;}J^XCqnip|ij+L3V)Hw7Y_uK4&O5OanLehG{XNGs+tBqHz9RDvv&cEd>qtK*Y3w~n3qr=7t6fSAGD)0h?Np7?Q7&dDg+k78m>uAq z#HsS#{K{a&1Vx~O$4zJr2VC)|2O&GJoW%NbtDH;k>rcj%)#n^M65@SZk3g9V_8U4- zg;TG*xbJfw<*-9v4tV3A|Jh9AAmJWmT+pic3GB#IZ_4*0*CSz)% z{8Io@0JY7D|J0D0YmoBF(_3#gfLnw_=!bZ97GXT12j3xWQy(;O|D7bWI8_dEnt+g! zr3ZyA=&1v4=Cg@VPv#I?(1feSL9wMIJFm=E&Gn|;+q#A30R>YoB@yV47?#2Umw5LR z-T6cg(rv+QDr6VU=@28glPHXSzGWWd8z7lz8&Am(m1`kKRK9izFYNEGCO5<-b<4Qx zly)6t9UDlLam`;4P(N9u+7dR11iuIJB)1ML#njv@p~GCoVc5zX_9E5emQ|}|em*zz zz(4#NRsy9~BT*Tkcf#tRK17mv-tk;G9OSOgzXeG|J@Kn;?|}pa;k}5 z&ek5(Yd=vqF$Tl{Xph7%C2R(EtrrT?hK;tRfw&?8rxG|z5PE^)gfcDZWowy!IUNl2 zxIPd%*)ykwLunOPcqR`pcdL4k_o;Aol$LjYmH`w+X>UhS=R7PWojYNCdj1=gS=7@NsqDg*Ms|IGGVK9qGXP6D zeQ5+_7zCx&U;qhs7H0aph_>JIlS!b0r~8-%*v!D6aQaEsxJicMdVyBZ2Rc<%kN=K` zy$@?UfS(8!^~-O(=DdcOBI|qQpVY>Egzcgk*{`Ru2%MlGWeGAGJyh98;$#$~_&Ma9 z_w+qN{C-f3MzkEviQm)Ls$!@GFmfBd>(X5Pll>CqjQQt1RaTo>jiU{Nf<94+0_pXW zDajPGTd3%7JR(>4TvABlS?*KuqjLzqviyUItBXjxHAI2OV0?tOT60;!y~RV$rCuqf z8G6@=VC7)kdO=LvZ+mQoM3!>L!p8x{k3EJ&$WNokz@6WBKe;RKfhGtBeJdamYc@Yr zAH5#!YstKbXNTs^Y=`GeX8c{CzlQ$-Ry9gepxzVmhIPVlrX)@AJBFF&U$zTt;^jtm z9H6}DtVFbgO3@xK+#TJqw?`XgiI%f5nDc-a?fmM*^5wsuH^$1;jeh`=duuH@0@t__V1W}VrldbTm~O#;|&pJWMHMyn;~LMwtxO!@!G*5e~fBmf4`iN=a;rG zw_KxP7z33{R@ftX3moqyg8c6V3B%(DY34zUh&YLhRv>Gx==W z;aoaN8!mi3SF(u_6ayWJ^M&bk)7Ner>7iX+{eG*2P)sNaem_XbndC!h(?|&waKoEW zRcecva)Fy}>Mk!ib3EKS#_2Fl#uf67GcKc4) z=h@^MI~SjRUGzjG`2`V@`mR@v>ZA3qD*2J+$@Rw3=MNnxqT&prtv}3=*6n4$Q=B(v z7BSrj(AW*J^^BZP6KYd06De0cBO`7lh;7OyPzg;`sO27STxg!j#)U#x1Y61kN5$Z}X7>!vF zOFm|N$u6Qnb~`#5B{E}ykcmX*mY&_kF!r4ND5i33lJP0}1Zss;+c26kOKaWBtnz5S zMrVn5%6wU)skSP!(Cy56DNj=Z$=4()9K{Sbb={qpch+D^H$$8XBE%Uihe0(aw7@Lsdxyi#z6m!b57v=O@yt%e=ZA^Mh<9?)kB7qaSm_j4{CDV%q z%$Fn2v~A8>jJ40mz|)AHExdi2sg*f8f%iHM|3Jx$z)z6-`l4i{;GgFLF=_ZSn4GU; z{cfJ2IC6i;LM@P@gQF&oEt}YUyVt6b`mz5@SN{S1R(#Pup@e}BnvFg#p9bYRdJjPr z$X?J$GrCX>e(_lipGKgXG2c1Kj+T9H)rV|Kza%vG1>6&1PfQ7 zCcgGrb0%G$$}e>kc%(N?2ojuNRw2Xvx%TfJAqE919_g2aOnF7eA8J@&^J4Cr5q#j^ z1gHL8({D9T!~?Mr@>G|?_mS!muAXQ3E!*87R)OBJdj!p8FQMohw3$ayz$PoNkh zl&SZ(_)p;uOHwX^`Ft&v?hfQS5ezK&ve-KIUsfB##F{CX_ZT;Guq$w!U)BJEYJw_q zsQ+aQ)jGnNnxy`sOb}GXH&ISA2i8$y{IWor>?QnjDX*hQW0OMwfWh~|YATF@Y0 zc7hO03`zaLrEc;X)h|5-&~1P{xhN)JCW<8@Q4fv@A2P{qJRl)!T+-~Pu~@eE*c{Jl zZiSP66yR&C!}eU11ulND$QIJuXa?v#Iosp!TRH29`jedCG|*65b9){wjobpy9x@m3 z?~4Spo%o2%p32==Rw6V8MaGP(breF3k_s-DdFN>YMj5MzkLO(__I{rK6iESz0e|xK zuxHdxCpIck*#b7y2r&gA3(lV()RgBQT`n7HK0ejCTAyGuWzB>9n=?i3P6ZS-GifS@ zF1k^(j`$O(?Mu9lSQc9~@nQ5IJn}w;iNi99)kr?vtUAr=_as8YKO*%AS}^si%42H( zYP!sKWlV|7JAfPkeqKLHZ-B#&ZiNC}v@(y$17S?d;<@Fmb2Me9`KRC}@2G#x1#bhB zwQ1+sA;eIKh@F+_5W207hhN2*$dKd8A@}h-eB<+pr;g7v)wl1$rn{-PKlcxt%E4eks=LRl@Q(1R zjlT^vflECV#eD4prSn4-cW*X!!V8;0N*N_9#Ai})rSA6rMlB5{Cw`{9&$w@(x)YXM z#x?_?`JrLy#f$R0hN|{LOU!mSN5iuLmhhM)f~%MAP1{6DmA9|q=LR8+Vw##;`nc*L z51nKdjz;^ueg=^va-iOqD4uv3CvKU}?}2bi2Ux%9@snxFH}o8QBNjF#or@0e87q@# zOPHDq0?w8rlU+3$j=$vY{-yY*#QQ||y~0|*3FrSx#3>m(OsjcO4~_BUFzmY>+pXni z?rxFuewHYUVIp1v9@A3VeGkE3&-&=T{JTU5V+R6OW6%RhPI23y5eyh`W5&17ZrKIv zH&`*>}DTaqX% zabv^4;=y?2ltpI=waucVsI;|dQ&;!bCbeoF;`jxgSW!Bc?GTTEB##+UOxh;DQCFBV z@Yo=_rR!{PXbj%)EAz^Kh}K9ua5BP@(uqo z-DlCV0{Md+uNwkI3ttHNRf+2yAlC8Vl5Brg7`tfGNTuIms9%lw*ty?!oxgaxqa<(D zC+{f)cXDpAQroyb*N6rttB>H}tP!%tBCbZqBMMEwUY)DY8yzIQI&-Osr#C#-iJtSp zLEaBOQ|k{YRK+GFu0-@FC)J9f|D_Wq_sWTrE>ukfMU zd2EuLNiAWD3SetF$}Nm=BHpAidmyg(A$|5bPyJfl(AzG{5eNJG?&uu%XzVn8YT)Sk zG8$&G6h9FF4=nZ)YfB{MZQEWutS=44uDdJ~LO(o}U`Or_r&@FM0quFwvz{v+jZVS% zf-{I11qji>M0NMCXsiuqNH^HSB_5)^vouQUD`E=)5CYuZZB*>$Oa!r*RA^u2?&3j; z2FVdBFJemUYs3}B)co^avKa&?-kl7r&-9Q4;>c`g4C{A~(1Dk$Nu&>Q#s~L5YEy2H z))I%_>2RjB25B7TgMgQ+khkg|zrSwl5E2#LZGOXKA?&K&dPospu%>_w9f1MbpwH*` zNLMaO2}WR=D6pjIXGMl9XYDC}eHWv~|9P5c(76W}`0sZFb-~8ME_*j?r?xY1F^kbS z&Ju}Q=Lxo(h&Tr4_g3C+zBR4JF5Fd#SWE;xcr4pLFrtwLSn@1}-%iv41G zWvqhNcnNXHa`}8M^Cp=JbnP#0V{Tx5nN~|qjGjisLaq(YD05XIlkW+UlE{^z`9RCC z3y_u=x_uMs!@m{v}rC26J8@e7yG?xZ@J zxg3?H96_k7{UrMF>qOg-^dXjds6{5$XDjpvhp{xSsrmkRM^D82TXA>-+QS%r8)HhnuP zO;(c={YiuS@4C^N_~&j)-=3}Ciedpb!%3(@$FZ3ovG%TV#>c}R%VykU)O3qp6hDu% zJ$tsS^30gzqekY}&<>ks*1;;fwnGGwiopS*0v&1)$S2=7jRHpSPPANSKRRLgS;5X& zQIOJ}@|(->S;uhc4~5s&Cpv!CwQgr8JM8i;O*}M00Kg@$zVV??s;-Cw76*S2CTmT+ z{vyGA)Rf^%OO!G(e`5T|9=*DBI`s9Op31|{I5^pxQZP(Bi0WhJ5St{o*p5j;?B(5Q z&(^N`M8z4xZs~wR{Q6?1e=A|-%K#*GqT+K98N<_YZvdW4HA)bT)pscy;TL}(6>=`?Byv{3qnhXQ(kbFb071d}zd_IUM-*#VrV zDO0W`mCyaE7v~1iu!mtY#z|hfXd;w(k)fbRZZoAX2WEJX143XB9TaVKQhSmi%IsPy zAt-W}XxJClg>uC(AqlNP8RF8t-ArZniE0A%OZL(*8Ujp*jDg>WZ{G1|9cs1m%tsnI zR3oTLES6JR;vpS&Jo^FK{ogTrkq~_?@9P)2u`PmvjgPT(bzeZ)U@GkN8Q+Qeu;A@+ zP-IQ~)nz{P8UnpASfqQ$(QZoJjR~&McPR-gcRk>k&B8)Cx+{0RnN$Fr68!cb~Tzw&(SWo#^BTV!bAK z6RGjICA7iVLZiiWbILLzf;^!U6$bLL76R!PN(@A%c~)P!Lt>Y-=a zQJ7rZDHjwN_s*1F+&jB?xY|;ZSLN<17&!4foVWIk-7O+pG91u*7*rNMS1pREre_aS6iehMAT$uo+CKL&gB1*&u)BaF% z*%z%clLZ2ucHtCF^1`az7%g|qWk8qXS=m&=__+8k$wA))(><#VP zrPZKwasstE&X90#tFGOd66x635~km9#eENisO9qHS>{>9sD2=1M`YSMS39_KOGr&; zs@otYx061EhD|=2s=SVi*!KW$=mDh(5>=x}24G@96+G?DojH^emk=;57UuhEw(CB| zSLYgk;jy*1-;Um)*Ag~{&e`+r9!O~S5rce(^wI-)91IRWC%8>Z1hWuR*Y0^J#MhSR zz5W=og)%i91$A>+t47MN+vV}&?l@`Ug3?9)wVIVNE|LTYt6P&t>^R3 z1sC=4G9)6iS}#^mC%cxf!z<^Uy?G?Q0D3A1i4Bt{T5YsDk7h7qa5pfZOjXq5_!#OP zHoXq1nXn^C522eV0g#y*S)_~1-y3>5c=PW9G2u-YmLcB(c1TKTc@w$5 z`(Va|?a?Tn=m1LC$wsFoh3#Lx1$OsM zLNUY#?^&wUwBcLOoYf}7O&W6jj8E|r8itJ*u?N>^?g&$*g_eCHy^3~-R1EGciS`+- zX87P9WND7apYZ7k6C~Q4W;H2BEB=r9Go3%K4MumZK!HstC^q_b99k<<)gMVr4jdp`ARJNS2utfDyWp&E> z9e!kPyV6zgrrfT)K$ic-wy;(3RQxMRqZ>AVe%$d=M`w5sZ5}(3u|BVLziC8Sk0bW? zqtV9?U7}@0grG}B`PbcxApNPt6?<4BbQ{4c?Ahp;@sym-+;9C|qDFWFU7(ME{{EaK z@ot~^lZys^1hZHljiR#F&I23o^>8EQE!3odslZL;Oe;Lz8H5=Tn+!N0aws-QnJ6K~ z<7E)o6P%Ajjm_CJGtNd?C0;Vs4q_vGH$s*Jh-!|UBN;$!`9+5SpOrUB?<3ZFOBOoiz z()JqI5}CC<<=N1Ug{CP4agn~6TfBKm;9HiTPFPUIt|>H~^uOrcv2eq_s?7F8HW3mI z9PLlh27wr2){Sjzj_|6RJ(`**S|cGH5k#HvO=UXirbV5%?|yK9L%{uhjM|)0*DY{8 zh?d0;zjEsyPBumU#K$bMjBSJO7cST;lva29gCB}Hr$A1;u&HQiN8{or@0R@*>chKB zqjqR%Cfua(If2k=0*nCkHa{3mtO#H&tTI*zEcCeP5B?CqkNmo#P;mWV;pd!Md1`HM z@)SK^{Pv}z%Ot_Oedt1_iu9XTpPA9;-AaomDc=uokkws(8zFs55Bs?b@q`8Tohj81 zDI#ZqJ!V5pwj*&vg~54=a7)TRJY3K`MZRhB3*)kik+^|Ajop8MOww8v;2>wBj(*3} zG?MP0ik>m!+C#o@e65h))>^a@FNV%*D?hKuw1#9zm{^(sL5)(X9Cz{Mt9xkrX0&we zxGrw0+IVablhca50UCjb`)MY_wwkV4Ttqx(7kGpvWcrSu&R`uT%_e!#PSNnz?k8n& zwutj22IQHo5O`v#w~l~YL+Y;Or+lY}bl?q%-{&*y>!?ECG?pc9HaZ&My{tn1t>|_$W@<>I~Zx`0EzG4Q&l=&yI zt9?YgW>-6_89XWpBV+96*_}G>X+QRbno4B^SragbO>LVyuemZ1ORPB-P~`3-{g2XPL@XOP=*ox*B?c zL>_TA#?2k!m0;bds5u{GBeF&#le39!xG>l(NPN&vT2W#8nfAbsq6p*<`|r+vxcwTF zIswl$Fd!f!GgD1X4Um8Z1>7g09RDstZj`X=ZlS}4IZLlp(l?avf51$3gbiWVfct2; z6&)w-0i??)j;@ZU^5EBF^q#l<4hlhGk;CJh^X|oqysh(-yaP((_X)SMk?Y6{HVaQW zcnXzOXXQc2Q_Y@jK4dQS7sRuR72*=&!0a9g@oE#Ta~ZeVPR>}$&mifff&mEp?H7Yp8P;ZJpF*JqR+w2M<47SRNC^55`*$^iM z^6QIcVv)usonBp{Gil~G=i}E$#JNMCQCDnmlU;P+b3<>|dfMnZ_^O1U@%lz)uKuqx zMze~WJFA+9iS$3jy&2Q3v&1}%JC3o;rL$1hdz#b+KL{C>Pcmal$;hm&tSqpr(0#w) z!SRPHI6^q_Om$)JV)2{zg#CTQxxyI9{hopp#4ldWcho4a(s>H0Vazr55>Gp|cYfy2 z^`w8S2C?@faj0W>!BQ!>NI1+A$8XmRg4({pzqv3EyF!5o)2b4DV$E^w*^32#<#2<+cz4l`CcC<#@Qb zyH3Sr2FWn99y!QqliXYR(h=s$8|}Ml39b3 zF!s#=mW_>m99YuO2Q%LjcB~QgER^n%WkFogXiA~7va-E{19=67j{mhR*UQyvw>JVc zC_k^>g|HSzqibwTE_dE{T^50aD-LBvppS(1Zt8gqAew>K_*G;E296N9uZ8( z*Uy?C`cUyAM2SXrJ_#Wc;tiB5$UDc_0>-_~BG>oVxKE<4LQd<^WupD~$}8K)%hiO} z!3lEjr=t~T^R?DtLVUT$0G^Kd=aJ8*>!VXIZql8FepznPt>~!O9cOAT8cu}&@iaZU zhq61oxN*B#GcB0rsu@u%L*$u!5#)U2h$5^EEKy51fgye=^Bc$$pqUvqueO2_&K+c* z^&Z@*Yjfh*G*G?Kk22N7uVRzCeH_UA`@7w)XHVHz<5SnC(C?@$*xd1Fbt2~1Xj<}r z6#N;1K4<%ea9xbywMPB*LBWw$Lad4~$O9f-8juW86AB?Tk@vWXC7kQ;r}jh@%Y89E z9w}1n>BOgR`CTRHfJYMoHT{>zu2Os{m4 zrQn{s`9!E_F*yw-t9MK8&E9( z(QkD}8HWsUOQ~FkS6+q0KW0ir3PPZMfh?1P((|jvqUL6WX{v$=rA~!xVB8HK4|!`L zuZ$t&ZL**1ykAE%SPrqCuv=fVDYpwWXjT&bIaWLBCziUyH7(%Kn^)p{in#-CdZjDH zIM@2Jh!-U6r1nO%w%xdMBiw4RB@nASj)%w8w&?_u%X#AvJ5=V>9)~JhNwWSDuZZ;yy|j54EO|d~NhYF=BO! zv0eQ2if;%qr9tjPcYNbVh5F^Q^MrYC2E28Jmimhvopqw+v$lhesOPDkj7$b#D^?U0(rAFi-S1IUcr=(DBe$2%tCwiP;yRW)D}jIJ8#8OsnokUe2m*KEAhrZ#PgNA8#_yN%o8V~(icc7lvZmAPiu&$*CFq!6f4bB@)1S3I zM#5(EMCYEvy?d&Tw#}6H|}U1MmR|bII3LJ`wnSTBuPW&|FOMUm4sXnik(k< z?m;Y3{$)Y(aaybC!3bkOr1R>Zrd_?UO4ino_Zm^d^fQ%W4y_aQd1G^`V_L-tDq7Y; zGPg!lZLLC-M7BcY%_Nv#{XXBn{AUMSUpi@p%hTPU4mgR+(ReBrgf;vY595!414sXv)dIK5aI@p;~dD6ed)wBA#oh zhWBi!Zxl?c78<2$pasY$RoxC=q7E(!t{@R-eDI^>ws2|$Buc~$Nf?_)RpA>me=d)k zRVK>9Tig5_(u}O9e+MP3?^LoSZPQIl^Ahw3EkCerJj^-&uoqHsn#g9=z4NMd9B%6{ zzWHar%icevxXnEND365ZWCCc;LYJD88Dr+t;gOlAVlq^@MD{=g) z)W}z|*nKU9ePKZ$Y^rfC5|w93x?1kpdp_oOreY#i zKM6u7=y61Ty)k%4fnRd6cK2;Ka6%Wlu_DGZnCPpYqZ{q5Px70Q6 zNAIu98*fjRkZwGZ*}k2yv*uRK+Z-$`_Mc11^Y!k`_Iz{oIal$wTm!k_)J!|9$(L3< z==qQI3KDFhDK7%ys>*Z~mX>PlVewQK{jwyw>6dqOdA8Gh*E71YY^2$7tvYL(O;0ws zS4sHC-3t@C`=crg9~82ml*nc`2`>+%NO+(5P+#PVmpl*(7bP&{CXVOB=XoS}NXUC0 zN%HbxnhA6O@7Wrd`r-Z?AG?O^EJpbn8X9+eE)Lg5wxWeM==y_)9#$!(HmhC@&R6U+ zH|`6GNzHIVFPLRYrM=V8U38kA&nZj_8O!RyI2%k%@Qo#$wJe-}j#`K+e{&#?3M8%~ zanQu>fft9$J%21}*3pq@oqOKQ2@FU;|2QpUJ3lyChPCy^MK14vs8lG$Ji~E|~<)QsC*J$bXdvwoX{_WiteZJz3(|=7a)MBSZ zr_lHN=Ym&PLdv*Oz0Wi@HlkuSOrGj4d{xVvDeL&v9;UE9;4i#C|L3y${O|6jbC0zy zvZhkaRn+7USt>-+4h1Th!z(hU9t#mf1a=Zc6`buTY{-YRwsN7U1IPn4*1vvCQd(HT z=&3+`pR;p|fx)Vt_u=HlnM@XAT(zK^T~-d`&=;$&GL!o&<#;Cz6@Tw(t6JPu@yave z)i--M#)V*#Uk0Rt4u%1s1wfup+qiCB)Qo`}?ZB30* zPM$MAUReAnvUwivdS+{ibZXBM&o@(f(I!QbH*VM@#Ct%&RSe{*%>(y&0`c^&xw8{R0Zxsa|cFOb#d) zj*OCD3<&594Ut;+y&x^Ke(o}6Ax`Uy-NPc+l|JPSLYqpxab=Mj7bEKLQX()p?%_Q5 zKnE1!e|f$Cy5J+?*fPp$wzJkSa1nqYarNVLgw$(xi8Xun)V9-dlc24=l)G3y`%($6 zbxs>I=AY9B6KwSS>UkSkRM+tSATib1A*P9bEAK`R=Llz`TAO|m; z*g;u{oZoe)Bg>K~Xk&Th-dcj-hZ#zVC`#999o3-Wky62V<(j%D9+3HFAhG_ULH^t4 zHhd?)ackK`dqNzxATQ-j6X#ojmOluH8;Ap4J?+)~r_~15Jb3(BKdx2N{;!%ul5VF& zoA2!6c;0)nh*u{1lIFqNyUl^f_0U2W3rs6q#EG1jSsYK|c3KQPyW+wzJN3m2oM}I@ zY`=xK7?`4>d4b|zs=mEkk zD3s$fH`K$A9;>M1A?snYp<%!V!6zd!OS1w1{^3sF zKYk61`zrVib`SwA6M1(VV4ckk_btd2}oV~Q1TApL-$Le zl5nb}`=j(_R@y)Pfw!pDxy2G|0$#a0m1k+m{X$qfYk7s4&1U50F_h209vyMb{#&QU zEQ$F%DS{E)@HG44%kfX=gLZLc-(j$V{oI2dS%2dpiu^OWAUP<;K(xka)c+JtG~eHL zgC2EaG)1-t9L;hTv-)SZV-}7i2kze6fF&Wu3jz=ka(4=XhptM;doL^D{?k{veoczx z&R5Pl6K2IJ#*K{n&62F|yZeh2%Q>$5HqQHrY)hwC?- z#gRrnqOxmQqqmTpxkDQ!V@GS6W)t z9N=DH*lZu@@XVQv4O#(gX%yHN8(SjDI^Rjc$q}MB^eYZ-!o<|?0LziQz4Saq`uVxe zRxFN1Bl|pusY|Pbc(^!4Oi8cgMbtp~{t|RU-vqi?u_uHt^C?b;L{O zAdzQ1>rN$xJHpvC{e}+m`d>cDlI4`d5 zYO8|A*UE`Ltf~^5I%#!3H5qxIx%)T=*W&(uE!DLR+}!~ZaZA>B&yHS;us}f_ z<8l@kv8Hm2NLP>Lc+bT4w}nG?koL)c?f%L!Kop|X>j`;wqDY}brs?-1l*}C(!~k}- zM?)~<15ll|2{D0+z<@vq7&JZm3srV4N!w;(PTS~BrN@AHfXxz1zcPytyX;|q?z3u? z3n%y^Spz@V1X}v#{E=lIMnNA37+(7lRQt#o@DOmgPO> zDULoo=zA_xD5$Xa-Ysz;DO^#}7?d;_(N0C-(E~FYcgNK~_ zcow@iP9Dz0W#r4r*RAh6iYLzTcb2fBO>FW3<O$`rqy}59y5v02D}>2Nw9e_$uf?kbkd<+r4FCqqn^?m1P^Elp1z`(VGH(WxGhaO_FoynmMKC80 z9^-%F)6MyjDlgjOmZQi&jQ)Fz1#3{+#b589e_6REvH6Wk$8Q zSGX2WM0BEHss)f0d$!M#v4hFLC87SqDT1gVfDyWr-a3Aa%A0tt?<98;%`GS1!aNv4 zTGcksRs5^7Aw}3+f-ua`0I(l`$>dM{gLZM0Mu}HoViTVtEw`zyVH;Vt&42Y!k9%ye zd|x6z_)~HEkPtTv{-aeaKh|%!MLj3?U3W=;@vx_ZJ?ib)&-46WW5q)^PLDGN?qx#c z_~glVPG!A1QGw4^Fn#~l=wx|+&khYyL0TVe%9($j&Hz)|g7z>PurID-^>`k&ehI*@0ZVZXSIC`#A0KfyJ^z){Bt>!Vy!R^q^ zW=UWJ$Sdr`|KsZ~OG=cM z?k?$Wp26$dd*Ao-KEL-H-#Gq9%&eJNYn?!WbN@z|OpEqLOcr0r%+1T><$C=e7y&6e z4DOIrJeysq12Tn7+ESo~%G|TX4C;_J|0(-EV1L&ZGfW7os>eGvuCgm!rcxF;Ik>L; zoZod``iQQ2ORh*$dsOT%{G2VEmSp<>$rSP~EVCp0K=!NcmzYTAc?S%4+_Yk5%ui^w zowuaD7EXHi6#?$td_Q*DV619D0i@Z*oRY+|6!N@ZcY!YeqWXX-tCK~nKfv5`Y%6&P zxj;TH6<`^F5$&UQHWcOGtMfvDna3P5&Ab!ZH{gAAT|1>phy}JnuB0TAJL1iY#pT?U z*8Kc>l9rkNCCbXyb$Zal(Bk-Cv~5(~F^&-4oytK0G)RA-8NPZ4_=NJz)0>BX0*ZTY zLJYX&7=xR9tDSjSF-sQ+yxKH@G;J9d9%d%%Jmw9x-7_0Kp^f7Y9VN@h4~WFs-dxl@NPIm1V=$r|L!kcu0Lv*qJ{V%^0I#*$)J`&Fp5N*Y2{XXKhcrptM~UBX z)%9;?H#+%i>AfTQiahqp?5&X3E6X*7Ja`A;RSQ?#J-Y(UAl|tjWAW=)c#ZQdya8Z; zx!>(ohgqQXXBd4p6fY5sqjG9SZ4r*v@=jT_+1uhUgi2=4k+)pOWHN`+Z;) ztHvfvL6@tYqPlA{gY=1q#Wg9$T}nYVlZH9A60NMK*#AXN_>Ni5{Nop|GTF}ZTuC4kOAEGT>sZiWuADTbAS}XPCnAUSw)!K z&<-IpZ_f}4aKldGqCSqrIh&4myAMa@1*p>&Ay%bOiO7%-{IF3<%;x8HtLuf)HXJ3e zjHR_c#$N*^o|P4F>j0J~6<0g~#wv-Wboafgj)B9Ak1LGE>I@aTjuBLh^W(Cps{V(K z|G~3=i3I;vO7fdc_a5PZe&L!F@5LsKeHt(yXo7fpgP9#ke*W;+Zt-@5J0)uD^MM}` zudBW|o@xPs{#qe$80~%2%=>N(2yCL8ck}(l34o<0hJ+6pU2O58M2!(W<1hD3!urk9 z`KUd>>^A|PZAy{3QvL;aJaa2+1NT7UQvYNJfxFkcf94n%ToB;ru_sKA(ktNJkQq^` zApiH?^qVKS&ho91mwvi8F0k;W^tNr7IEEmNi@^9=Vy$dRstOK#cggDXwcIQWC~q5n z6KL-z8%ElHu)3~u{YdbEYucxIW7wD*IK@8XT81nXdag~1JtJDl^@DNLSFzS6M}r`e z$Plvn%v6g(kJEt`D)FN1VL)!SheA9+FCfo=h)%luj;|oTR2EkdJP!Kv2w&obWSm>ugHEkBB}(ouW-^Lj@2yqeDhMoJ!A7*JefPb zNS?+9{qsQe_!Im#Amo8%VT9=+N6(Z-aR4oTg1E>lJn}E;^!PGyF-bd(;gG2T?zES?wL>9Cw`{?aK7Fpm+@Jf7`v%GQOUBDA&HH|%tWGmW2 z1TQ9a-l80#ZhJsEbQ8ZaG6fzd(V0lrWN|PgGGLH(q^Vj2TSJFY(BsYe)F0)gZXnsL zpaf8$+{R2n3;mhV{4l^7#1rB*UDzs)2pP|_J%BS3b1)!M?Vl)I+UoW*a2Fad^ElJx zSGI3OB=^ofd4H>CZU0Gad8rP?%xTw1;>n1(w3^@603ye9FkpSSZtU<54of3RT*xU?xX>eY#B) zETNF2B)8O~sI;13w_-zHbGi@qF5ft45HlQrAXq8%_=V|{Gtd)$MP89SPZ@_#Hp47U zniErfzKn;Kx2KzVHQosl_GYu)Ui?BKBrirB3q?(4K#x@IUO<<>YcnW!^V?$Y+C48#VDW6r3= zlSrFU`LY6xf}1NwVt7w=p|;c1)g|Hb|J-#ZvswW%&LvB;;^^ zU${7c(m;BDoicp;A?L)P7>Jt%-B2n9}<&%w+r*1i0dS!p!kk*%w z{A;B>Q*k?iL#l>f2?Xn_?3~k2Z*gY_($8Z&jA8^vr|LC3{PeZStfCcyG{G}DcV6*lG<>#?Q^UK9QDV+YE{sPWVCWDa zj07~Oj^!>HkJ3%9?nOV^Y{jL~GaZ~`mT|YAzjM<}pdsRS*SFv)Em#4Nvidu^F3bVR zaQx`O>5BO^^Y2k%n?oulR%wQ+Lmx}|>dW@jv&!};i|L);l!(1R+)m z9ppXIOF@H{W*;xpS=Yquaf4Gh_Z`2xD4pYX0PUCisEXJIe5=P5z|`bj1uz3tKA>b_ObA0CtJ5BC$odK}tv}mjs#Du;=;LZg&*0swKEDgX zp@lh!mn0_{LO0A-kEkQJLZc`KRTAspZ;fiHm{a~Y5^{`` zz<~q!1qL!`6P#Li3M77dbKmh2=y>UvoksQ$eHL0!(1WCR*|}FT1o(4ro1nfS39Z(G zVC9crQY}{>wC=kStxsQ5Z`0Zq2`a7N5`q9CtKusFRS=p(yW#k?@r#QT&x=3d9<`-3 zU!VYSc8K@OBdvF6H%#$C@L((b_n`Po2ab2>QLp8TzL3nf~R9U!x=;TbQzx({**g^W2$Kce)x6&T4;kNfjxB8 ziFg=^bDuES-&x5-4;MWP*2-gJ@_8A%y^jW!>9(LT+ z`?w~Ql6LZi6L{9uII1ZNyHRUGjQHYf@ABSQpGqE(G*AM=n$jj9=P7>jTjN2ICY^in zZw#CZS(=VES)k0g-~69iiHP5jo?fr+!kIOYPWz%;X+xPw!o|^Q&g(iUTj8wmBV%bA z@^9c9H(pDNtz-P<9N}26HHFA4zJT7`8}E(PX`uARLIki@N(A{C2jP{%lrV0m&HxGU z`@z7$aVxsPbjU=-6H5Ie3Zx z#7ZrX#bq;!O7C7ICNE#Y&#GWTAHEjd{_ImUwaDY%{^*=v6a3*(n)_Yle|nyMzCVHu zloP~$%^{8X8WU0D2EMp9wwSsh97VBruY_=QN6iSSuoQ1mi~04X7b(XJP)68_0~wrK z`V>^jG|(7kKvQwNKmHwSSoTAD?IJPLV~Z43&kfXwuyci}YGZ{3vYgQhO$3Dd!M>@x z>&xaVODinWNxuz@Kg~An*Te&3^w_;~anX)2tHS(iFp;@5Z$FRX@z}84SCA>t6!v^T zOTSEVZTHM<*i>~OzEjqUIgOS~{vS9}nzH&_on92b`nP)ueezRd^(7U%)4a-6-md7$ zS42kJ35G~OtvtxefGT+gr7KKl5%;eotCXszyJvQ)pB#)2 zNy$Pdg1z5wz*NV$pCg8ayTHaNNF@Tm6!dOfAIxz2e5K597&b0lWS)@yR#DrA^n+hPKs2;%c(5TB2XrY=T*9tXK(9vzMFa2l2U7S> z#d{(O(GQ~U#_eyG9RP|TKH5mFP=h{PC;WVzqk_|dhjUgUQCh4a|GGy{ByU`y!T14x`Ir5^kHq*4|7Z`);MIJp#$%0&yv z5C`xzXIL;JH?KV>c^~#q*MKMiUP9SsZbU(VDe3)ttAW8USI*d|C3rz>j;(6~#GK_UqkzOa$x(LDMo630j-)+Y{9#nM6c8Ym59YrjI=h@v21_)!MDdey#o3?JyT8PQZr!BEA{p<`9%RM*&po#lX1twROALf&gy$(n2LJY9 zyGC9wVdb+i!AB(Fa-bUb(vLKl>|>3VQMW}Kd=(ICxr7BEk$t*Z?xl{X0o^xe&T`wXa)&ja1k0IBhF zkQtQ+U611eU*kLbx&*6&_H#+Nz58z61zxqqwN=UuR*>){voe6=#d2$h09vlkwUoMQJM-*fwrj1#Y>8O;lOJ@IBZi&G$!kl9xH5Tt4l{Si$6uBKR|0mA? zW&mp`lP~3n{|;Sksi2|!*Egy0-O3Z--t%cF*{q;%YPGfz}_37u`#t?zJ z7ew#dBn?e~exS~T=LU@9hi(fD7vxcJA)x6Oa7hHULS&T1E1Q*IoF=r*ous6j#-}IUhscaR@Fk&f~3}VjDBd1dRA0 zB-m5sTQFK;1W(#@0jLWf-OM6>ki=aW^s4#j4?>wTGL#4oXL?S0wG0Ap(Hn|UMBF=c zOeP;BH_+EoW7XeDCX7cRm7dj3)-&YjmnZ*ctuQmo9APH8UMo`qYkPkJ%nHD)4VZNH z%xb$yFK(oRP8bH)&4sxTI+AZf6A?!aiD767BTS^_Ef9FH^mG>%Fn9Rg zZR&XqmjQi7QGQv)#ivkU9#q#^Jp(f$er)6;4!UH|L6fC>>OE;A0VWvQDGW&$vtJZa zww8FiMl#R5p(_Q7pcGzYSg|^o^+?v}L1QK$<=4v+slU_Tm7CDyuI3ZEk$qFe_FA?9 zo&Wt)E2fT^qv$VR4e+ zTLgM(Tg$e;BBag)EBG!T0(>(t|NXwp1hf~vxvX9bwV-zVTHp}pUMYO!1`Xi)-$4q| z1)PLYAbUNQoHG6GCJahkc#b@dVhHjtVYaZ%*l?QC`m&_p?`jP{WQVn{@sX%o3^4$O z5YRTb9Dpm5<&DwG^Ka>(TN_4Nn9VZ)sstAhM(DtIt5*B0g`$2#zyuY3D3oCm>M|4V z56@!qeq!u^*u1ZOP6bw)Oe|gfMfbEt%pnj4lu#G9k<|iNdN{YUb8+db_?7@XUqJeB zjSdUcfJT=wS-O+>tq<}#esf^Xe@NsbhWUMR=!VX0Xzq&F881Tqxi$*%w3j=eq8|VL7`PUoWd|#W zxx?RkaaA|4Qem(SrR7eYf&`!%5QThuTVO69GAb%Pv(E`hz!UmV~l zKtpH+!N8d3GDJ(wTn5zR5NqMhLAwq1q;a9Z`$HQ(m~%iWi1%GAcH{YV$6kaKOnhXl zA>xWYw>AJDkmdb^$mQFfq${4_H^6bRH1-^9F@O#f8&w)}7d!bDZm0(Nmw5M3(vveM z5R<`N=gFmoIvBfrG$3E(Md6B+pFx!thu2>Vc{iF9?s|Ep@%(a9HtQii-$o zzxk+dA-~V{l1&X>oOna`boI>mO|J!NaZ(NRg6~Q@uYpMD+Pws^7YQ2B5T_unf}5Nr znQ_Y+-`HY}2o!aoD^y=69n4hLln;SwnB*A@-{E4^$-kg=2~jhc)C-cT*a2UkzzJPw zZ;lT=sD&8{xC(@t6N6jC_u&Ml{aYW}n~lW!pYB0>`FfGsVzFdG|7q{Xs^iIYkaL1$=h}vlIizU8gx>m-&@P=dsE6!j8Ctn&3T{;7={Q78jJn z$jA$b9spF9fIKkCca8Nx(HKv;Ql^4bgH#`YllS5UZ^d0aj;ogr}cZr!X}I{hvC z$9x{_u3mzs zuNy<(Z}8kQN|2G3+dBM%{#kbhr8>-V!MwJE3{Z_Ad~pn(KhIZhgi?f`8oz|^fRxXd zk#~)+MS2%=xbP7$Ym!cSQ`ne-MFoC<4OT69r2u;b0YT!!_j;)Q+Y1R7cpo14I)YEq zp-lyt)PM=&m@TQnq}{!rceL%*d=|@NP=8`coX;xK9te%Sl%xGOU_nZQF&7*wNh(iT zcGxn%mJWh&( z$AA$_F3|L2$*4FA_*g=h3M>HuCL)++F;&ppR;8PNaSpz2IF(TKnnQ^S(l+Q~+mIRK zS1r0uG{u31hN=VUGEA)i+(1h2BSRIyOnv~t0bo7gK{kI9qg?dAo5>G}X52Ojypb}W zzc#?f5P|X>g_xY?#Eg1Tyx|ubSYZq!#nLSn`+y>Izrfd!o&JScKo3>T!15Dmp({}J4xzbm+XV(*uy{ENVx zrO9K~fjPuih9UMqH9!nqFa|>Lq%rQdE=j5p zv8bU}7Ou|=foVwJH=2|0C9p~0YgW&Fr)Z5Mmi0{@Tngy`CHkMPE1CkDArP{^psiL` zp~0d60>M#UvunUF3xr%X9xBRa6p67KjG?pQ7 z-e&8UfBerLf3iKa0`v=mLmnF2HgIQv!R`0L{3a~hOb&YN3?bO!d)J~$M*jCEh*BST z+`UYG1kN8_w7?S+sk*va17r5T#IffodN7S_?;>9h?-@27Gsvrdik@0`ITuif4EI z0?5cvJ&J(Uyt#`M7>R&8=Rau{JZ9sYckyAK#hddPzN?j=#YFil#QJRYDZn7>y()lO zLIrR6q9u95C6iv5aRNZ#G;~cDNB(ECXMmF9^@`;ya&(A3uMQZA08!)a$vZ3f=v&qn z2Q2)3b-XYn_`l#MnQ6^B(AumvwL)VT{6!89m0()w1EUaVU*krcW+?@26|@f2cG?{a zQw(2HxGW=1w)B;0g$sCrlG6J%`tAOgFDVi6c-k~s>b$X2j$W^%cq1VGb}`H(9W6HP zs5_dns<3LRn^U*Eb9I;Y^s};f=rHGgn9xoTf^0X%4PtG@QJuBkiB4E}; zJ{aWGH=7xv>7vfJuq3W$0N+A&gzSjw-CVvSY1=V3{dK&3mIVjS?ZiXXbqxm_wf8d) z_STN%`12fw4>utt^*XU3tH1sbHF}T~*Jky-{^7%rmq9#^lb3l;@6{uOx$iDk`6Rz; z&_$M#(NIn>TPCgE`Mi-;a+4qHMiiO2%euVWP1Q-0=+j)Hr47*(FCO^sh*;emgQz7k z-)1t9lQC`_JszP~BtL2+H#-N!=P zYxCICObhk={U^%=v*XV%>vRAJL*!e3wAR&Qjw$&ab^hN>%knUHFQ z^P?MYiwqJ^QH*QP1D8U7^NDX4=TV-met68Wgg$ND14FZAh{!MNX>X}m;U7V~Um;)N z3AY~qdH7rTEA?B0@w1Qd-%n9&^>8LNy_q%-HM#FLCNNeI7I<}>WKl>mb)#!$ zk@K53e?84$eOO6!zcui^b{-DhudzNtL&WdCzH{5&EwA+5_YPH$67~D6^0Q`#R+_m> z%-m+lvA*24S%1AypH~U}M8T-+!mr}BhQCa=^tTQ3H=O8xj!7t!=V8tQJ`08bI9+JeJ>Q&qC$k=}`239Y@ zgUtmu_oI)`*zE~?S_T#5;rbjiKWY4vyv$>4_TA~V9tj48&HnBn^Dw$A6_v-;xKXd{ zl#9;A(uUaZ=-R}xBfp@?=eG0_cOH!EHE&BsVE(ga&rBcI_Dy(|sP{*SO#*&`U34hF z6%MoJ!$eG}dL3%9GAe$3X0T)zw>QP^W;u4iSf z+w4pSbG!x`)j90f>(=Du^r4kOEmXB<-PUmY)+@kvkXUe3I_*fd&xgtNV0z)t0GUU2 zQTB=Zo=3&XlOdyRHd__+3o5M&=0Pe`LkJ!>1YSQt=!l_X{pWrlU={x+=bgP?>k#pu zM|o<#UxSV}kklL1&x!6i9{xZ)LRwpPvSe(?6KZ9*cgM-c_O?3^p|nCME?8Roo(i6)fz2%+DKx}>&Lyf&!{6f^yTNQmKHu0Ln7-i2* zGsW@r(=?l2VOWxs?mKC6Y$DqtuqEJj#qeW+I}d-V+_bchIg7KiPoN7Tr<|&a)^CeU zCR4mD8bhiuvp<2N{pLDDF%_hX+Z*3M9f%sTsD*|5C?db?J5CQ|bnJ(%ySt$SM=fwiH!WycCiBKP)*;REVt&R9uIM z``@ciZP|(ZEQnNW2P#f21N5SHgdT-1J~`$d7?@K)M8PVvtNPkB%gZ$4&NaT4mb3Cc zQEy&O;{d4;l>-?sll1Q49MnAUYZ!9y+Do>Axpa+|I11W*k^cV4Pn8{k6$u?5? z9gowL*OTAHZ-{%SK5?zcp7rVeC`D*^DSh`gna5CzK^v2M1)8DpEVqNlcjVVHO0{1f z3;up1E+4LTRdpR5JRc9>fAKMU_JNKJ)~{mEdTY{_XPR1m1c4}xP&V;%m}B1nJku$c zU>vE})#l1EVSb88y3%2>k5@R+j*xPF8zm$7uHO^UMsf^JEY+Mk3~n3@f}Yx==Dgx| z(0a*Qj{VO5CcM0~;|@6vPv0!mA;q`L)i*`RYBza|3!G|XfX^lx5x@~5r{~P1PLTXj z(kp8CGuhwJHI9oeM={3hTGP9KK)JNhezV{S`dM~%WOYC;W+Ewx&2Ej9<-N+gSO_zi zkB}Pj5KXC*%?J2@58V1^MG!(yIwyi%5GMr-5?D{@rZcyK*5ZY01-S)(D{kemxY52) zbNVt#WMg~y5Hb5?^w1qblofGxKO8Vqv!cjmP3-(#&vQow&$n|uvEF7+KezxGEsbc4 z+ls#d7dp0#SpTrC$2@I#(aCrA3xa~&3I&1POm(wEAmo@2Z^?Sf4+fiD81Y+7`pYHj zA8aDa2dEgt#=ak=SK3ZZc#?){Isc_QwZ1!AYnExnNGb8N7tsnP@-tkf=C|btM+#*`cmhWl45G)w#FLWyYBY+S%_}dK$85D zS|5{%^3QF1;JAV27#ZK4n%Nz_g$tHL()fg-L@Rh1Ryp<>olSL~BrmIU%&rbx)s$9p zoYZ5rX35JB^5I8!P80i}6tjv2@6~?5vv5GmWUHr9FO3N4RTAC>k;jD7!~zkeY0W8f{E7GI&_3NsO@7ikLZTM!NY?hmyv60U`66hCu5J;& zk;TnM$xV+_J%3SNe*xkvMeXU6SibEk(m(tg6_AP`pl@?LDwidR&^{YAoq#G%kX9k) zI%}sR(Qw~rw6)RUFtH^tljm|HZ}XG> z+zPJ&#dTIp{8Z-R1DR>qgnDC0p{Bc$LmZ!^$VPgaCOjmaYn$fB^iXs=XqkQ#hTZcG@EXkz0y^QP^4GC?t^6`L^lH1u)cAsdRZgqCMJr-}UUI*qh@V z8Q~H9+K=qcGyC&}Lv>mFqi$7C_z(-5sQRT6>gddxVMBYXWvZ$EW<>c2=V3a{4z26e zF{}oC_eBBx=Vq|wh2_h_hgG3JembX~oWT-RU8>iVS6|H2&U#;an6{lF(x3cxqGQaj zx!^-DeHld=z02*HMei zTf=&d3D&6<*Ham+jC$if9bzC(##BXfo!~1iCcD1c8QOdc`u)J5lfClsl`_Ju(7pId z&h8Z&Zn)x!lG@T5mVHX2HjiA$@8#kZNu|CvS59o+ zCoZ7bG0XUSp1|ugq!5KU2Toza@V)|0G4`zB&%Vf-HczrTExz z;J{Qr|2I*U93{tJzt7cbJ-bbtg~G>7F3y7!fYdp%F{Z6jXxPwT-7jxQ-Td^)6g<_P zr(e57)rDK2ofDCLzh1F^rugGdQKQlKL=vY?n<+fnRZLBp7TC|P*aDSwbj{0ttB)pk z|FC7y2H0V!`PnwOosmjMmnx5jc**=(iT%8KaB7{3NSo8e1EC&q#6awfi4wg?u3?q? zDQ$JjWan@XZ2|g7-IcbKA^KEO@bPVuS-A?v+}F4LPhOAh`qTHa`-lqm+;*^63eic1 zkAfz6sN)u$Sx0_3@;Fb}pA;>8#cd;VR1la<`e@1`mrzdBK zdsfWJREFw@My!8-hT>EnEdtAsQa$QNQZ6B`gp05w*KJ`zd4X$~X-^g?QEyn`f2U`hY)A{O5(o>%>L+Pue7P<~vJrTVE* z73GI-dRS0?_~*8aF*jD!BV+tt<3w#d255K)?EUy{nRil?M&_Y}2Z=94NANnizG1Q~ z&tVgpdmZgN#sjHM#DSm>XC;P#I@7?P_YYR-O**5;LpMn1IL+}F8(1zD5f-`q0Xa$qK`0P->Og)u>f7~RW{#K z_7mR>s39T~+Q;3wcy%W`Fl{PgQ`z!k=Nd;df9kfXeOP#cT#c#r(ZvXPU-Ap?Z}ygi z0~8gc2oAmdPuiwt!ye{pRgoJKA5q+U$e%)~O3+)o{#*NRO~}#}O|QWlU$?rvOhite z7#$t`<%@!fN`T)x0#DPIBpp8(0;LUyoTI;eB|kF3?#@+TV%&Av@JlQ*ps8a+~ zhW_vU0Q?`VFZsE!3p=T(xY*jx4htP!_+d?QG6GH&1H$Mhj_@!Aa;V}JM)BRadUK^2 zQ=X1jIzQ^-30}l`w^BDRnQOq}Ui=xQn@d4dbqyL8MeBU^Z2Uyb$ppRZ3Zjy5kB3MN z(Iopn4?K6%E88$AVMkVXL~PYnadwm%g(jMU;9l{YKrOBSI}CNK6!8!owV`wU%P!0k z^V4ABl(=U+qT~x=8IEo&STXb(0wXRHEiEnm{dgJc+uPgu`HXxExyj<-=z}7rGF_rt zmB6d%oAZ)u^5Ahp!fKVfLFBm3C#jMkUEMG3vvJ7s8yLOmZ|x{s^~MEWY&cI?{G8`( zP@UqIN%EdCmD4ND2;sOR)`O;M$=vFhn8T*+>|0qfb$!b-Yst|s((<3hU&kAwUWt?6 zm=KAsxA6%+^I7R#{WPVrnJ>CFp~D{4tIKj-Th zydoQEq-dRQDO=!IuX1c=5NJLBaKf7ga2?*I(Z6S3q}!C2!ZhG^fc-lZv(g|~`tplj zHvXUxr;M9E3L>>ps;imv3I{BBbCR8%-Nw#NN>Z}r`B!w^j?7esA8W&1_mFj)FC2w? z+tlupiu~PVi>XW4!il`6x<(3F|Hm3}84?$j>{$&RWj+u|WB%V4l%emrnRr$5aC&$) zO|9qKzqLmwMB@H`pNw`hMB@DNd3R3Ide7x{y(Nu_^U7?xT%1*tCY@Za6iYWiie5z_YJ9#iA*uZ$Q( z$)_s{ois?Io$_A_3A`T0Rr|8!X>fBZauHG!`It^Mn_@&?N4VXVb0=QwD^A#yXcdAr z^#E!*$|vLU#6^|d;t(x2PS;d#{@)vt+yCKPN)w=0=ukN#erZW^!Y>#3RqxaPpGRwS z@m?{r`8k}LV?Da-#(ksucl!+cD*EJz)H=C8hXWcvOMM%adL5{%(`TTKy}nF4{8IF- zQ}|a^l)`5rE}W=xc|6f`{^GZ;A1&jiRJiM_8KX*qBia8~G-Vig9`d1~nH$3!3(FDF zZQ%(@<)4D~{~b*KE^?u-bdx9XuEoPBy%mL(vhA0+QZeXzb`hGzIXPHde+0_(ii`L> ze$JjLtI)*7#@^4AD-dNX{uyDkI?KPo4O^lVG4~mloE5ET$+V=|zqJm{TeyaK>Au;F z``Z6`n?DoFeCv_VLxt3o#9!K8w=eTWp>fOD(*-dj<=^N&iJ|U9o;kss$+pM%Ae!4@ z@|>LFz;y3z+%t{+NhkfD-ks*tt8IeBkcQ}hDWP~F74hc_2AOgC#GwvLUEI@xTfZ}< zOi=wEb)qvAB`5pov}3y;P1@(Z?UIx#(|eoT)bc>C>_p{Rv?*1=R*d_zjMn0!Q|D?W zt~zJCuAkO;WHwb<(tkR;-UMF8C2X8Gp-x5{2-bh>36&odx0B$s>SAtKr?wC8qlCBo zCPgEC@69i(!X;^wfIFkje(j%7$oYA?gA&poGI8b55vpTM`9*sVxRob8D`R6hKG~?4 zUK_}{A@NI3?^$P?ac}*}((gx#hXGfCAz^;X!O^&ZHLh$Yi7+{sRW}oybSC^su3wrQ zr$hHAA&2cLk)b{=EB_sTUazL-kI=@-On8k4aICBdJB@SM^l#Ei8Q7#%m$mS1bcRq5 z()bm3asGI`E7Ytx-lLE4r))+{9T0e4_ak_b*8jf9{!QdU&n}lrQhT;LI|kFPmkp1y zZaOkeePb6Ki25oRhK~HqbP*A&8V8T*iE~@0DhpvG zkNp)2iz&Vz`I%OCl2iwmOinb5i&U$mh)18Sj}Xl)4R_*pz8kv*1oPiB(?3r81!4Q>Qs?mzJX9WX%bZv561v~o70rq=+8N{AIg-<> z@{m$f8&CFVl$>qBggUJN_OPmo>CbSFa*aJ#Nf8OhfOox{%g4ys-UbS{fx0hvGICQ8 zR-Zw&s}HUGzZ)9K-f5T-Z@o~yQzzUQ$X`t)4hH?k^h(bi79hLDk4Yrtyi{CDA_jtH?*i)r(ppTl~R zTf@6RHl_|`Uv??>osAL+vr0c%|_`|+UsbFN9%5-%kxCNH;t zBGRsFOHV_pyqHty++@a!1Tot#t17I#x1wn_X?R^b2$%~ih zZ_b|;^C0cLxfAiJy5~^UqKxn=H?Nu}SuP8E?rq>7|4>yyljXXI z@cgg`tTOjc%kL39R$}RETcY9-y-E%AKW_fv{7C;>`Vb?%rPyA8`Q%iCt5fJPe}+Eh zPWv6apqhK1XiNnXG6+axS!5~_7ctov#FTSi(mZEgPS9J#I&n+sKreoVCpU|(o*X06 zvY)?M89~ganT4;{U2Zo1BPaC5?x13l?P|Zwc}5yz&JPNckM6a;)(4*`HC&vh2pc50 zuiv1zh;l#m1FBSRB85*BdP{oP)`3)pzd~za@F#Qd&d&Z{s3cKCRO>i-(4{8%4RbuN z2bKQede!#Xm9=^0Ohn+1#@A3i!jAawot&?tUW+JFv$IowR>C1u`M}h% zw3H=tiKj49tk)FrKwm)tF_fHax@u1`XN%5={%;_=P_4jD8OZ6>5Q^%_dQ%YXfi&ui zWz(HB{c-B1-uS_v<^S9Yi-{){wG)cPbk)`Gs!LJT`ue<1cgyavj7HlJ%87EhDuyI4 z3kXc^9@GV*(5K$8ofJmZX~W#zsiJm0;3W}ga1kC|zWVv4PDCWJxI0vSl%7ds>FlN3 z^RN!|jB^1>1wY~9Fa@+)Y-ebsRw_Qv=539MP2}LX7lKVEc{hOSQ3z+rI0F-x@@W&c zuHDV0Bsw}uyCk#E_l64277sU?N9vx2C&=vVP3R&kd)>~6RjY9qS*CDedN)$$c19)B zH<)*3zpfM%($_%5yh-SBSJ|Q!Gjbp{PqF94@6b7I=6$c$t%saC{sM`gG$-_^@OiM* zBM(Q=j!e+jhDzeKe9!4$5q#8LS*$I|ucd5Y=1>+I64PdQ*Mz}Q;vbzjNamog(@OV; zSW*W#9n->gkWi=yOoo20uS5V_qd;He6(#z@SI%`t|Iw?TO;EE`3_r&sas6FsvjM`81ELsFEo`E zsMYO)d=>b0w4-B4JBw$xjFDy3@^eJ+eM!wB{pgi~+`JnvhUe>CqOLBEwpM1w$}Vag zm_<;NJf=v$pvUoC6?fz8@x9`S3kr$9(N}bs;yt{b4dz}2t|+yy^HvpB{9$^`u0(RKWcbf*m2y# z#^P*JVQ`vQa567`Kay^*OOeDo-*(}Rjfv&Q`&8`?0i>aZvrQY@pl7;DBRa^_61I$4 z`i1Ihd%N#^uDXn5*?kvW@B(WX`@7!7yPqFqNc$5R{`b5Cr6S`OYD>;*Df6z6+qC#u z_(;wSa;)+T$)2^48eJXLi$GoEl%U`Ae-_|w94FwKjhDx8nc1qu*2SMf%zhxjrX9gd zkP;-Fn*YQmGqGfEdM=4CP#wmjVV;rE{(&!0i>au1{u2P+L*ts)wc^&1tf-g6O@*4x z;v2D1ZYr21GGlc!dXyW#{D#$CuxOD>Sop-)vFe6WV;Z)NkB_{l!|hty&BjX2510#7 zA^U!G>a|_@5q3adaAl*{mWFNN!{2Xi?CwqWe!6w>$o1gPB6Iyp@axOo zl<5El4yVhEM2Zgfhg_{`)XSdA%5Uixuh4RM@WX@iB`nFRpq+|&WPGbEvobf=(_zX< z^Ws__a6AIiX0vho!19?JdcLfrp5r{ zJLrxZA6(x5|MPr@K0AAv4}UFK(3$@<7KZ9V`8U;vXCd$X;0fM+Q!gLpFCmjJCH2Pr z!cJi4v3~Jd;5?PGRK0wukbKTNV!tA;;6_W!j5t9p;P{`pBTm63nSZ4k^0Q`xeqm7Ax8u+ zaYBG-wYYW4zp2=@ZyJS@vd|`^ERkj!{Ek?gJg~`{QVMxz6Qb zDKX*M9p4peN^1|^n&fAkoS1jsq5Y$jE4QoUe*aU!yQez8Go9qJLc$q^uhhy-*Syh! zr<)&LzTGu(->VFA$z|2FwPJD2FNxvo7A@ zEuY0p@>g~ecI^qBGeX5ni@#i6#EJaK znTCrc^R8tm9ZptO7t-WQugRLLWd)vS(!m1S_0m_)_#geHz36qW<8nYmlZ_2&3HFh! zFN`M`WJ{n4ca!6v=0K@S(<9fjXO~NpfbOcaxg^lH>^3V83d!0waXN(`_v|oXk?v|oI{*fGy(qVMBp1JU%W+Bma&eNffOYQ?nsD~@-9R{<3EAM&63 zIlTWsK|tWdr14CuqXCb^`2B9#mqDMO5?4^dK)5}F9GIFqm}fvjO2Nc@#BZbDUfA$D zY_B`KT{a=SJ;37_a(O&o6>`@RWK0nt5YWB&0}x~=I3D%#ei6Pr*-8i7%* zeH}t|g{j|h?5J9MO60Q^iUtH<4!t0{wVzd}ezE*KARs8Hyxi#b=}I3~m-C|&PHv0D z(5c&t9JVOxE*qR-a>i|+T;FJ08OSQW?ErcfOt5PO^Q8X*w-&3!KxqNQDyxtED) zSjOS?%bB#uww7%=DH6)6>8cgaznPrv18PU?kGAV8{YdstPb}x*?jk=qc}0thBj-bc zoRszH24+8-;&Lt}YsxqBxgV-zCRM(tGOmVE;O_XRcKmxws7(#Ot#X&pbC5G9qxF1L zEy=I@e_fQG=FeAy9E{DeH?1?Cu^zR{eAsz+KF9%K`d*8q=!ggHg={DW#$=Y%wV|j5 z&b?z1+tRAa_l6O|@=_cMv{`Y z^bMcXs@0U!`vsWSL>&C@F3f2cqTTVe-@1HOUFx4;{Bu~gNjGBgaAbY&;p2#4h0@>) zZgyI|h(z6tJ5P2^HFptI97Q8nMUEpIC+>IcnLJnaw? zvFlMar}wGsL?Druq4xc%7!d^pgr5ZA4H;2E%zJ`EMe-N^J`WB#MsZu(TWHejOCA@4 z|1Fr~+O7>CW-LCG6V=yy`tdw9aimDcg@fKAW7{cm?K58_$*qo9`oZL@%*-(f!jrRU zF;v5;k^G8qjgsU>w}EU59tZcW_0j3E3X2EU5?y!0x5ODYCBJhep{dy2J2EDPEFgWz zk~Y}z&z-=f_~BvDy63x41Xs=~fnkEK5A+C00h#be%=R#dE(f(e##b zJBdY;<9d(C4*flq`*EJ*QTI^an=TM{{K)lQP<{WmEsWJPkc*x9L>sTatYl-wQK1xz zoftr1wWU^6{pD@_FnMZ1hag}dy(jnO6w!0^Do-(S&YZYzn|-wtH8a=sioB(<#G$?R z8#=t44ddRqovyW>BtV*zt*6Pd`%lkc7nxa0Ddab`yTs?jaLpD?^+-;7xxA5*DccRM%D^1Yi4h;fqqVHm&Xj+dahWNQp6C-2T=AjrpDDgLle=Oo9h}dC}rG zgQ9adHFREnk%G485;Y+M6KM@SDfb7x`*C!^y1EMA_hyt}v^t}XMX8Wi9r?dDTX;)? z^NQ9t;v?e+$p*PW(TS9s`P{vD(djt~IA4sO!le4oH8F@skRs^p@THa-zdAzc|HIW+ zhGo4jUlSrqN=bt#jeye9h;)O1q=Gb3(%l`B64FSgbR!*tfPhG+q%=rKyu*%j{^#AF zy!MxeyJptRthIjl|3JMrFLurH(2tTD+dO`i@(ZCf`|K`dCglmb5U>Y(;jmY&m}6*^ z+i+{^J$@T?zuX2Bua@{B@&vv9_46xWJ3tY@v?&dU%vMd2w&|e00rLVl(Z>Y&6ENS1 zr!!tenY{hK9mtLEzB|7J7;1{GSvh|ke$cpkg>j6;?ElYItVAgt513~$i%bgjFa2io zyILLa5i|X zA8%*h+{x!-dpKiubO7Wwy_&zmG;*igok89FsX!g*b}zh?B(<* zdEb>6?ytNUv#$SE4neZ`lclGh4T!znm~R@0euI{-Di4;nHa>2kD<`6fs-)sS-E9f{ zK)T%qlIQ$iTG1CW}Jw!a|NN9-4u(%4g&Dy2mzM!PNjPw)6hmGxJ1a(e_FyY&B_5sU~& z-^Xg%ee+aO3?oz&UW&Oe{ek1n4#oapqD4{q_(?!W(kekUYdwL7Ln zYf)DYL6ZPC_Mg2K{hosH!tK_vnb7~fov2~ap^z+_T#7|qv^=I#HY;xFAD>gVZgHU7 zS_GjyBBe2Gl^Gg|jNW>aAk1PE9@RU3Uzm&f`kji6W{~z+|KHWnZUajk7_eqCOuO*4 zBRIjR;RBhV1}viM`Bl%_g0poI5QB8l{GAX{V3-}p`A+>iPk$BF-Oq1gV^LV4Um8#I zaY2{&&d)_Z+gv3p)Dg2#A=f0~=DUc0&lwr7Tkyra(1J%a;fzoJYv^=iQTKhq*B!2m zNB2m8LVmqGuT(MNX$`A%nnzL(a!_+AJqPSDyPELlpV%Sed+o{)$Vw&nJE) zJ$uks-%j%Tbrc)n%H>P zjN%R$6aW1La++(6r%pB9A0Uks3XCs(|Nd7?5940!iM)%tDJmv2#x5J~e2re=*JDuoH4Vmpr?^4uBG0Dt z17rESwQ-L>k-jBE26oy1`I&WX^)!tJ8&>kaUR(e8J<@2H_b>vTwFG#d+ca4JiBoai zO(l(eHuH-KSzS(uGS|Z%#_@`W_x?$WI3vD6zyZG=JwRYY=a62@8TpHSpMLt^unD|z z?SPUF2%CMKa1XO)v2w=ldj974Qq-O+z#H^Gg5jAftk0z2TLn?h zN2+aJea3NIyrJm3#E1exz2*CFuggZWShshI@e765`^gjbZ%`=>NYdQaYBzOyMI7VV z?8f8CIGBQ*Gxpwk8~?wHOckg+z9#nLqE;qJ{G9~|x&+R4<#I)2OdC){XRc3?U_%2V zX$jOAsLX#Vcosc(kYP-mFDj#q$ZYBlyG^90)07^l*I7Z2#yGj2l0O{6>z{kOnUx4A%bx2Cd7DIXMs@Xs!2}yw^cIVAgqX9<$Rbk z^0@iPApxz5nzDyVQ?KLDOHb(4CD40dOzJb9D%mKzr0?(0s#o;yK6Ive5LF*N{Qv)m zsuzty+hQV*w`tJ-dTk-eTW3kHa`0rya}1{0nFWC1Ec04<7b!&qN5B_{o#yDFc;#g0 zj@f6uhxVM!SDT{!Q{jHK6;sc%vuVA_G6^6=6WNGk!w_OYcOc5zTXbx7Soz;8dWcf` zkdzYSDYfxP_XsPxE_=sYNN4!m*Dn*l7}2o;&4u7hIMQX1>!@U4glQV)?os|le8jbf zlAoj7firjCmaO(i{V|7uQE^~m6|t_muD{GP5(pbP`AnbodE6SxfcJPDjdC5JGH3@K z?3)R9nufPu$9JUgYT%l87a`<4RiWJmAr}B>&RI`RnHZOw4@~>kG-QF5Ub^(c^1}jI zm$LfOhZaGx0vMp#GF^iEs4HQPA7Ua6=RBuy|OS zx+y(w&y+Ex821-peoNhDDt&C8aLj)Z}$nNicYJ zCO<5&Me|jsUOh@9k&wI6+3GtsAtN!BnYPuYFy>2qbirK4QK2PkjQ+5DkLv8X ztdQz=eP&KV=5M%FaqRomDe*zZol%$Q<9m)Pq~&j<064rw1+0?F#f1UHGE}Z~ zHSN{t=wPBXKG;Q?K|YktV8~pZjNW$}Eb}`^_Ii0`ed0iMycKoL^}oDyERj(JZc$!D zS&3lhkIDKSj0$cKOSh@+Wg}!H>0htrlhCz z9G;FGeQC9nCRk)$f5WO3pLk%M)_wJ^RUhHNLg#-fwqpG|XJUaJ`!_{P%PP^vZ(jXm zNAb6l;T$vjs1=e-TRT&UQ(qZA*) z{I5Jq>Nb;D+!vN5rVTjBB}=jr4>@(3yAOvLj0WCMrTkeg?U2SjSl#Nm7`JBCsFW() z;5w3#yqs9+pWRn5?hsEb4ot$*_43qwq^e=NnCdbvKGa_JNO;_Hisor^>V(;m8$$&;+ZZ{JK z**7|If>ZIT(@j%Nsy1m-Y~~IKS2_7@-%etv4}4zn!pR*N693aPbePWA#hfO;)F^o4 zsP=h4WZim%{^Y{``Nlb zrt%*v$3ZLn7?It#fdV|G?AV?r9%gkF@9vswybtL^-3WcNAs-YNaztDcP@_BKm8 z{h7?I(G;azaUD|hJGu&VR5_@RO_GcDK2UXlxGvIV4hs^M_dkiMS9@2w$#|37N@zPf zcz4%YU0q#9MrL$sXB~qU*+}Sz&GPWaD%v!K7SAan*6&XhPZaNvmrnmYN|>+Mt_Awx zI}YCy_IHqbJ~xGkRJ@V(NM=3FURxT>UE+M+?fZI_XG1MJ4YOLHfI=xMg*tM2u{FAf4EHT!$HBP5;* z7kkt)O{$ht;hA!8%+X|aP4cm%7cKWEIEV1uJa&koD?}?&1VOk*j zW24~sv$60@Yj`$o292p|$o1<%8TA*hq%&QOE4hVLfy^R=a`ICP$qKoN@-JT3o3%^?%c!l~eS27>NgvFYi+TAvS$s1u zaNL}QOn#{@&TWuoNwy_n*k|u{!20UQo$8hJF%N%ZcxWi(D525Ae9k9U*HXiftR z?d7R-MOk9|x+cWlzDD}AcQ)8%UT{Z(Zo4~X3rpwog}$~n84HOP^Yp+Ld*`pF$8Ns% z4uPz-KPH#P40h9c-hX@B-a-a4y;>_wPX>I5Sw70exPBk~hSGw5A37$~e3;Uhn`lcK zamh3NGdxX!SKCCJWdEJeV#RRQs($R()=BP-=i$kcbCmek;yn?k{QY6YNJt$0h8%x?ZojY}f_*s=m)MjuRD~9wv@tOEqN=6Eeip ztx9}>p%c<#QP?`YeUppyvZIg-uR(`SE^*4~Vosso#O$ulNc1g!mMaonh2wkqs8WE{ zI#XPNTscMdVsd}K9PDlqw*9w|-@n_~NNZ)aw_|e4>&!t!1aV^-D5$}_zJojQ+Jsju zybxg7fQ!aUScV-3gWe%+3@WJneaPB zx;a^+nXT}XiNmXp(@rL*!v+WPXVMX|i*2b1Y=rBYnBo?#g=YBI8*iljEMR;@KypJQ z8Y%5ow|6MCUGjj&hNB|R2?Emb%e#Fe}IU5lDlF-cbcY^R^&yz{H9K=k}TB9i_ z^X~efCSLTLW4g}`UlM>)^g9)kyy7qRSQr{sezZ@k)2{XncH*A4NCt0!t*0{W@8o+N z=hBS^0plv1dRkv^un73LX7Al^=>Zv?T?v!!=lje z*|zGGZi>sG0I9VLysx&q1p~R&mG{?^>bg6afpqV@6Co}tJ=^g5*V$k(l=_882Cem6 z8^7|tWJSCiM-HOG&s-Na)n?otzp)k*OINi#OzCxthBe-)`si;Y0;bB6g^+LiWpZ!Hu+@_aY6u9yW1tPB(QN!;QA~y74M?p=8)xXD=h&Eg5fFg4_V%86BckL_u+6R+u%7a$;HR_1 z1X=F_65W@s+=rKm(jGqEY+hriF*M_X(}yJ79;(hp!tAFfBiPr@6-|6yXIc4B3OQkV z-CMNI!iuPOUeej3+s?S&$y@sdgK>Gj&--ry4^b3bHNZ%Rr3%F;Ynj<8gMkHPK8 z$Q<$I9d;i)PMRkHFRmdeMm=4-O-|j5@5Cu@&tePYOHl=Yx0hOCXg{ThZRmCyFtj>d zt%|NPMWLiAP8d?l`Dv|twJLG+`(m}gz$@?86M1hF45}-9lv2U#D>V8+cH-HO_w0YQ za=dha+tRREERm#8-(`MH4M!eT#7$i0Fv;&eks}ycXJSHH@T&b>8I zCBawcF_s2UL78yUH9230*3UVIaMT>s;RCPOqdrD zy@tOR9?s=%tm(i-?^)1A>6mV#6wS^b#H7&VFWJBUx^}F7;EM38*;i`wy6Nm`jKA%Ey1%Y!3)JODRtN@& zpos%N3=nX=n~aFogoo^eIq`fIpLVY7*#V6%sz50NpK@3+!IRalbdcqn=L-X2a?0-`jYb^Bp>gVjD174|fXRx$5d!UElOM=820Wo!1nPI&Kg~C} zhfXxfu4IiXtkdWw_y>;SQaUc61?{z8CQ-Y5g~*AP%?^8!z9*OS8J$(ltG>L?_#N5# z%J!=LkS%Ew*IuUSwPrjR35HX3783aWbn_@?IV;Zj>A89tp7^@E`-Z7nw@5lSdWsOH z9$>#h1x+Kq2FUU=*DaTr3*TI2WLC#?*_3Y!z?VRF4*5lphVGJ>nWg=a(6sx8t$CRn z*lGltytN+|{q<$c#^7lY`gHM?46QxbT__KkD@z&R>Zad(#?5tKrF$T(T)6I*jv(Yr zoIjynLHi#u3bE-#YqBFD&w=a7g6?9vRLEvt6)5|O{_fls1f#Ip9hI;1AwwYV%$e(l zM>GAW+y+ksgqKmD?0Mq>hlgutv;1a|cej^&U*!m50%$eaQj|aZeWJ5Yr($bjM#GY_ zX*TZ3lEf^@3poJv%DW8;vaY|V*NvI{5r_ZcatoWo7&CXa>eC7;N4{CEKVgyNOUr_3dEQL{|x4r`#79)!QKDUa`3xC9_FO2ScsyZNEA_ z22?=h^62k&{Bu00>o?!!zVG@75!W{TRJd84XWLy2R16^fzVDy|Z9X5gmR+!{TCVf= zvovvQ%mTLpCDal^|E{IDAYZ{ajZM7{hn=?F#7{DB@%rlb896*98~ZJ^Pc99NP9o5g z&R%s0S3Ib-E=P{VNYmx4fdkg@e4Xk_uZy90vv14$OGNsx?S>9%wTCe>y@HO$&x6lv zA2;7$OG!byHf#ev8s4iN#cTVAzr1y9o@K7_k#eA3Z~JKg&83U*7|hj8Ku^Ap9@>A3 zff!kT9qR)ozy?I}C2l%P7;kx3{Br~i9!$-o9pV7j;C6GNoAm~v!;&nj-2LL5P4fix zd(Q#T)e;VoHCG&e{7^SP>j_GFv*S)Oj*)hBgbBzB0u#1yCuBJU#FvaPFKg4;9$?Fz zTC*~c#Jkp$oZG7VD6T;yJn1?CK^aHBHEG4Rm`BvI%#Q%Y9t*zA<_(l>)XKoKz75cg z!^B-z#R323`6_WKf`9rnZrx4+z-5pRGn^vpdKq#w=7B?yEW6E{=~o_oSa#lAR@{A1 zU&B68C%YzZlF=Khe2rc+uzOP2*WZnfKtNSwbxYH^|1|ffUkw>SYx3Zor}P+e9?dr4 z*dMcvhKMc6qQvQzP!Kp_SWQ&ldg~as8(dk4epL~L|5Ubbd-Hq*UDrg?yTtf<2Qujd zmUM43{)=DskkT2X@5f|f&s9=BqD=V=HXzQHRDPZ#ANRC2Kwmk8DqI`^AkDsG12V2n zR9OZUWMZ)TIpgP1TO@eX4iZwsy+OEdn4|C2Iw)Gc>~OUn$2XO=GGC-SWw@DxJ{pvG z1rNWq+(D%O$ic1!U-_ad8b+VS1 z{qE+qFqj+~Lk+hEeYnj1m{_-1Mv`V;w~Bk${0D?so#NvL z8eI-RG9<^*+5AsN%0s=ADSQ4>emWRM`zr{K=ok_b@|H(nX+0-6+eOD*t1I^!<+K zcWN-tfR)>o6b5)Qr4I~6%BW&hD4{Vs8BU$HJrG()^l!IqyDNpAwBir4c<@R9YY=FC z|JYL}zfSEsOLd#Yt6&}mhAs8^6}%KNWFTGr73>Nl3AszIvXUZP9UYifQMafT*MmC& z)3qcFeMrL4#S%tacged0ES?}w3&Z{)RqOMfhk0|I?WHYUGIx}tli8!ll`m`)VCtULzD<|(?aWH)`r137R_qNN8? z%r$<9QUsH;B~H^1hQ`Q{=?VNl$5T-|MZJs#soZ1B2Qbrw%bhAvCi=j&QCVj1rPG}z zXqV${ z?I3=yRl(jvlKY%IXc7WV_NhV7;Auw!Rs_u(8wGjonU&Db%3DaM_&<1fDrw6-Rg)lp@hdMIX%ziSkRCx6{w^7#8Ik?7v zbpe<}DbUhndH9uZ1wBU4@5HJPbME^6X*IzYnW&1~;a{{AQbEco0d`I7wl$DDVJh+j z(z)Z;W^f`f+7~cw&>&b>9BNnm`heV<7GgjCA%|=;&1ZCu8@7U3B9WEX-U79ULD3Cg z5!YlhOVAXiM_53>52E?@CIb=n#TCJ^8+SxhSyT!7#Tn}7RRM0FwBrJZL(+5i1y7%~ zK1OFxS5sNEddbh~_enCUKk|bE7TEf%>_otNIe$jjhvqtjzq=(X3H%zB)L58Nc>o3D zSL91Ev+6Mk6}U~NLv~*v++O<^iR)YoW|29(l@X$+s@eYh4a%^>EGGk|SQW0?YSkDHg-nk-n(t~MTU3|en zLBav?fbvU?Ely`X62yYnOuRFQ_R6EG;QYm{s)6!e2ZN)bkafcaiWop`2$OH~rGYRp z49%vc<4}l?kYjF}$@JNb7tW@>4XhgcI)Vm>C=Kqg3KI0jDQMp@wuZAmKeDWZqi6px>!;5XkJ7T1<2>8(C)Z@O`N z&H>BvnK?23it4_h=%8V};u^4kG8u5xt+L?k$q~6ju>IHr53PHIN!#JvBeF9+Vu#Q5 zogty`?$+v;7Lp>2yG%zOtWfa|1Hb=m-zIlH!=XdV#D6mEPc#C&Co5 zsO!VuWJUq5I@>7tUX$7d7=XrJw-)l227!f8Kd(s_R7?YwWVc?WuRr4*AG4bEfGP`8 z9;xR6jq6ed1iC+^t4q4Y_q!SH7~Zz~*^XX`Hm;;u9YgX**cn3%QI1qGe)!kUGU6$W zzC*x(04^i=`bgGysdQJEBdUTsiYh)yn#&xE{;C*I&J?c}n>nW!ru?C!(oNCwL2qI9 zk=;sr+Zj{obqp314{u$+JTP%W^0*Ln^^Aw-FB$T9n!Jb@?hu3n%W==`iooBKPOGsc_wZME zZk}A0k3)h55=>e5BY)_ff<0gMY*p~dmJhshD3PtFB7}R1#qxS!;JMu#c&=RArX#9KwNoX??iV+fX;YIjCyl)6V}MIP)bj|`d> z$$t5C_KNNL(Dt<_*%HFdW1#{o)wL!%Og$99;a|j{As3I6z{{GQx{N3`pK9-sS z`e=ybynJ)-_%8(?RTQ(VD<5PqxyY9t?EF&c4Q3T$LD9Uh)eCIiYWBmN)`N7>raPosWf&USHl8ETk^>B$*n3A3qd~
t|-ON}P^Y%gsnRQ90%$60qR{?=ya2C^phsT$_(xe)s~RhF8RW1f=zOh2<*?*aax| zqNBu0@f~0XbwekWhAbUY~@G5b7zjSi32xmPcNy3^H*LSEbQYr;0h}^{PgI%~W z!2a&qa1t^K#JBXp@*d@X$^jq^-{IPeCe}XeReY(VLKYPi?K#@I33hAtCq~{H9~OW? za|oAJ=X;FRKKezLS;+1Mr8j)N{_fxo7vfzsntWykNAQ{j|0m3C{$d_D$f|Vb7;uX) z;gY{%yRWB+`fTQoy?7(Sko=5wN0nYr zqbrIUil@T3_LXdr{g0!xP};;bgie;u+Pza`&|yNrGv1x9bV+{x@~F*oK?K^}Oe6F& zmv=>f41IPt=Q)oSBfm#Om%Mt*MeZq{(~tG!r%)jR$<6-6G79j)gX5P>p`HQb2+zBP zNUdgYIV>AFv-ds)1JaqmPJq;+FzUT&N|w90dxQC`K)4}D&~3#08`pGUAvnT0o;c|J z_+Bwt?s*@uJUbY9U7};vM!dj$U@P_4I**YwWt^48mufmm`lx`vj1*7NdVOEjSyb;B zWoeertH!B%1++c7m6iC}P(uH*5j+O#7pf>#w3J!aq4E;3rGg3#oGGuL%^O#t;*$+k zM&JqpXXaq~=`IqZ2)n|MC5^ywY}sXMrGCH%z0@(A;bE)!0OW z9^65F0QhO1J)(^Bt*6-V$|GGw@#4C^R!EcsVU+t#ZQvpL*CTw%q6&m4Sk%$}n2YqH zA;<;tG9F$MlgL)g2k^{fR9ChEJgq%`IV8)l7oGT}?3!nZT6$Wz$MT3dnef_67z|tM zy20DQDQxOigLHlfa4ZsptYAiPGH|7HNGk4y`z*K<>W!|B@-v=|jI!Y{Y2jROJLZhp z3ASqFbg@{wndOI`Oor-N3zUG^XEYhyN#gtS~6F9JSRzzc_<{}8+^b)Hvli+lwJ{dLEcm0$8y;Tae>D*RQd z4t!j3Hii2H>&|*2bgmykF=X%n2+;PUlUK$&ET2E{T%mgHaEn#9c9pf>n22n>IYqSn zO*vh77^#zZ+p>K|@3VDarRgMxy`!W0#`bKEMcWl=`OlZL<}#)a9OHLZouN>1XSLYb zpEa*@9bEfzdw1C2g)`gnHznRY#)rKJw-uZWC>sA*)g(4NJp0OiVv^uo`h;bqTITL- zy+s(h)v#JeexN)a_oF>@>N>CJ-krR}j!#tVChvGt_0V`G&#_3%nw+vZ|ApWz8I8bh@LElnm5@AE0)20ob$J`>=(<|O*gz&H><6Em9hKj)pSE>4$ z@SEY%KNk2_guZfZ3bHSM7Q#5oEXry8CbJWHB;54v*%`|^iq5BWo$(%ev&xVnHy$tX zE!wk7=W-6g@P6?EMY0$&k45hR$}g{Ke^%^23y7l=BrUw1z9%ymBpXf-%|-Pe^%`q-#N1!MQn!PLas<4EFf(32+^Lu{hmg| zrSc%k36d8w$q=1fJ?dF=kwZ7i=_zV^WA|;FFC^U zl=HpjPVoX3=0G&A;MaH#ClTF^7i!3NZM4GKHU&pC%+c}pe~<=V#CdA;=mxCvp+A+4B9+9;l}O?@sB|RBmM1*;chR5hD)cmy!ZP{o zu&D*BsI&4!WJ_f>pUvdwC^$8_H1*4!3m_7URZ=C!{^CUK<_beVW+aM@9(Igcy1U%6 zK-My1@ImOkn2wunYLc9#2)m-7T=Vx3-mBRDbZ`E-TbnPB;4BqQ^#kT6*~MSV-=zO*);J65F(pnHFCY6X4y2>E=jSaEcQMHHm96oy znyjiGF*udwT4%Pdi+ACKF8`6xIP~~~#vF3TWzB(ILfI?`#h!t{J~xSTA&&Bn;iSdQ zSv(PAhjw+E&8cXmXF`HZ3XP2xvf^_owc@d+t4mGi3B&Pt>8}wlH1#a0>ToP#X^h*P zzS*{l)C;^4Nl@=F=SvOCbcyZA5sqTNG*gCsjeCLuXL^^u=Jq>g{*|rODq>@y{lTD- zce|m7yuB*ejg{a9|>O;54(8S z{Vr>dE<(6AoC1RVPCFeQs5!Ho%g9;!1gK!hbDWc;9?7<(>EcHTixaT!6&w%u2n4ujd_V>-(ELJmEN0-AY37cQaYqv8*yUcHJH|Y@N1V`o9Ve~ zNLI}KLBUUyRV4Bb#}lr&6iEw}uPq)`E7TkYHMi}}S${SCCLY70Qd=x8lCmV|_;T%K zO*9YJDWcL?_Rr<1NM43unW$;g&TV7!piXZsR*j4DvilF>`}Ij+u^H*;%UrhcOMaMR zorVS!4WD~aa*2{n3~uVDcrg>UEAZdT3W;AOH@cY8zg}=seI*yfAjdZJuDqN%)7J`7 zU+0$yrl&Xp}T*K<+=#iMcpF^X#!Gad2+y3miA{4 zXXYpR-1;EqC2dYjk1$SCV9?1ANXPIs1GJxVwA{M;k}{EVGYgj2XluxP0Hk&1H|?490i!mK9U;=;uUUv)$!0 zyZNSGxJDw;fKTfEVFo5NppWPIDzu>WTHLwe~qNh8-%dfHaqe7eCHGjfAZ zI?=<-yiXna-M2~a%M0CK>Q`5x@{^u|7-cSx3WvGgrojJbi_5o|JEPqcg^qC6GLyFB zJ`M&)U-a|c8C*MLYs?A9w&wanRUJN>z}u|w%);DuO|=hc?!u+LH_#s*_FyuPg@ygx zj)Pb=Av!)^Phvaiif5`QS03`pBR|?2MVvhGH#eD&5?a!*QuZO0+?N-i&e~w^7WkoI zTQRS-mC#b>^f>C<=k-X-h3%F-{^T+rtDMs!-bDT77dn}`glh4*KMf{bx@R9@OuO_N z_NnDH9|{ra54)Cpsoe6OD($#<9lJ&5HKRQ$`{=3f9&VPpZEgW0V-;mn7eoRZd(6b{ z7o&R^=+yiiOO8p&o5a#akI0f0tu^xv&XDub?4D+c7BY{$!-~a&}0ljM4)FG3vbKL|RBhk6bv`iwqCC%h$e;@nR5~Gy2WS zywkiWSNtin(RPP~w zHa_LNFYNysI0J7v!jQ>drJMa%q~&_+PCBA0Sz_x8YetdVej_3M!bR^b7qH~Gh*kNC zL|*B+(iIiSTXJ)48*tZ|r%j^Zmvcxy<-+05Y_ zS!ECfHM}LsVA$C5^ZQWi^L6XiET14ofBy^{co9*?6n~0%bpKR8!=6Eg+aj$Nd;G3V zY%!9pPIiLC;RK7=FunXE#(}QwQ|uX9_JnJ&6Apojb}yY> zLRzdgnhxoSRqK<`^vauy3x7KhS-bSlr5SA$v{}_v=pfO^xTHAC8qv#`x+SeUP8vK< z`M95A;qg*`;w5+RYhU|@#peWZPcO*I)_uh0oV#Ai?GFhc5Fnwe-@X$X`Z{`KU?z*T z#X~c*ilUxO#83p2O-Xntq7w$WAyK)oYcdNq%O{*m_&c=pH9RN@BdDTu+`4jqTQqokNV$b0M|w*`q1Z zQ+|ZjWHl_?ln>ZKOpv=u82C})ANPK(%|s$!MJkQqtPr%$1FzML$m36`P+`H(tuHDS z7MCwp9$U3Ym+;_?2h}o*=PgL9>POK}eEzzziUOA_n}jcFLXyI)kBNQD&F5IRhP<(V zx8kup$%p%c{6-@xA~Z6V6Mwp9mQgGleiby$WDaUyUz&&O?WOj6Zz$8)h->Z z<5(x7G@8%dlMf``+@?H6qykY>Lmn{QB@Y z)YMBVOL~asq)NB_iH3UCW3ydm`CM^S;8BNnv#NUg7;ydU+^ZF*S zlB)f=fVYMMdEjGnHVf4{JCZMwv~~QV599^xzWp#bSvLU$=;NR*Rb#E*D;7FH*U$PD z3K2IWg0pevcc*{gqPLmzQ52wMQt>&WAVYu#yFxLhF-kzfVT%=l#+Om2Lj6zmRzct-Y^4 zwqE6J>aLGcjG^buLsTI)rcJ#_nM|y_giGq_i+3_m?(~l3&wCrDTzcKuV z{>E>ub1ihQt?@pa^y{|iwjZ0?aL%&4<|tdWnaLCN`;}xw_6>uxS(Te#s0+=l_!Yz_ zGIJW)&c2}&k=L17bsPWU!XxW{LwB{ibeuwK5v$uvleo-g10oQ@WW`5Mjo<}4>F44k#aU)l2H+6IGST4h``v@(PgLMIS8(3BpBNfv&tRXsEVO{)Hl7^N zEJ!SN7-_m`G3?5syDUb@X-E)F`ZY11hnE2=N&tQBKX^9UDni1v-=f#y-Y#@gOR4;o zTbL~9o|O3EV42w<_7olj;FCqiQM&d`k7^a@}XL`=<^xW>1_^Ii>lw) zs*R>iKcZH*H+|x^$Pj>~h~TD{T1NUQ1n%XikeU#y^~eNy<>usxjp>TobEIR z63;0QA^wE~7!2Cb>;L$asMrdKLbk;I{otyjJ7-A3#xD94yP}7F#Nf%9E31&vVW$&3 z)96&K@mTd}tsd;K-i)bSKh?pI`*;wR5G-ROOm>_Sv_ibSmXkvby$PjZt1{+RDyM~ct3fRY|_eUO;l2y0`Tb+;>0c{2;l z;Fdpq@0-@1z-bVhI3F8Wk^n(1i?s{Zom0!1@m4?-MJG3ays2{h1G;5by zWM8t+eA9UNq}-u~O(Qjzf4?|C7U1rJV-iO8*VmVq00ArO+2qS-)r4aY zQ=gr<8ID_ATupx$5>Ncy{4;-InGfe__6x}Wb4pZo3@()f~Z-&@Gv=* z@F`eN)c7{q*rA$#`g_hV#y{*nry73LbuG(QAPJ}o(ti(q0qWl;YSxDC#QbCts%5yj z^F?*UU2hEV^Pjf8MjsRl?4fU0HCPr;@id!I7zZ2+$t1+-71}u((T|3&;20^87o=h_f8eKDirgvu@dI{!Ldz2L#3Hmtcl?UVSe$e)0Y*v{XC0lZw-+-KcMTCTmx;IhE) zcgKr;7{JD19fxj$`VD)Z!9F}`S2ea`#cp;p6cXA$N`(S;*h9u8c=DJ$BJ&(n?2(h` zlg;!nR5a?sdGeQ=gI(I}_p*K| zt5C_h=q+)WWVF;-c~onk zk3>(RmEJST^r8uQ%oPP<*?p%`u#Z*QgD-G%T*&hoT*=i5d2pPu(Y=aMj-Psylez13 zjm@Xb{mAQ>`qd}Kr0l5g65i;95^A~WoCsg2{d?AyL~#JlgJk!<#&b-@Sy?Ts6ZU!a zhV@_7XNFYgG_Y?Fh@IBS(S#gW*Zt*E6>1-q2D#BamCWu_smL&6#&DG~qF0yF4$(MH z#L1(N3s^dGqk{dVU9axKkt`R~N~!vb1Jz*jgJ{31*5W3eVXUu)b2*@?3SG}20Jt`43o5|^T4(s(e zi3jf_VAq{&iPu&{cW;P)akq>`5UZzWL+r!m@Pu1lD?4EZWoD~H`wgAkry@rh_PAYz zz1prPGP~_hgBWyYxvI$mJ; zgY<>k%nNS$WA&rnyf#0IdUAkUY#|$Me}N*jv|Xg1rcZ|WM=U-m9Bv%>PKC83bsTcm zC4L3GTXmsXRA0$|*_?mTBXmm6iCpuN0VDiDjT7M_3C{VQ3JTsw)b|dO(0HSa1nhh0 z2LQ`Lzt`K0>x@leAT3-=MGaBn0l0-Zniy7-LArvQ{3lKyiP@1Qpm2=lv|Sn3Ik+D9it| z^uB~$q@nRZk=Lq942j;)na@w$0fqMFNvjgz8$UTKl_Y7M0SL z?z#K`>Db~Xb9j^955KrJ!%o`6d1jB?-u3qsqe5A?8QQ;h&&MoCUwX~D)EYpN&&V?U z?rt>A{QB&nZlP?Zv|g&!Gib!@{Om6B(CD#v^6jjq^OE!{4S%&_2lp&NqVuB_zvk!A z6}!}tY;Foz$jvJD(4FV9RfjT8(S^OJ>AH!$^XwKUvODih2zV#toDgjDHPGaCNi$4C z`Hy3hvV%rXj3j9wJDn*?X@v7!yoeA;>!OqT^egW+9SWz+&)^lq7saEos=Je6DwA|b z7aV{BAw!|3Y<{E7+K!E;ZA1tYp0;yX;zqDTw!bq|(&DRzCe298mHmd!bN_Wo=nLw; zvfumAR)J@*+SYR2ykOqw&e0!9Xpb{mG2*lH7fY*yIMgx5X~5+gTu^X;oC$r|eI55c zmvjmM6NQMO0L8+Z^b&R`X=*ftKGjmQph&--meYl00?d%QJ9TDP32I(pI3;`#m zydFx+2hWJ_f_6RUB<{DRKrO;4WwbE8$#st=Ol zN;*6oB{Cnv>Q(wa?E2UQ0W8&%Fxm4WeNKu&9_O5~t|j#cO)37X@sqcY9t()+@Xz^K z20kjKKV$2LmOm6~;yP}#33N^6Sw9+&tb@fe4N97zM-n;jj}{-TMDnBCXa2{DD-zsM z7!2G`TsU*~hJpkh+JRe}Ib)J*O!{&_M|uK&s_1fEu7~*`kKClmca^|{me!mZBjL`q zhO_4oS^-U>cn>>8u{|wliy%qGSuY;ALk{Wa(A!Y;XE2W8ihzX{SiaYK<|ZHBzo zNh4c5Ht74BZV7N|&=aO7GH_u2MbCvv#=@h3N0F#?m}>t27<=oeth=sj6oXJe5Rgzp zLXeh_76hcF6i`~aK|s1hkZuH|JER-w5&`M%Qo6h2tjqg;-tQUbd&e2azZvdp@4fbl zx#nCy-VY)%-{_;em;f;Gm1Vfjq4_a>q5QsHpB?FbIAl&qdTR`a+yQF|Q_eijOs4fy|yEU+d~6g%HNyjeT?1_u)sFWkYfH z?hhZcZ?nzUZTRa7LnDOz7+^1FVg2J!_cR${N7bhvERWuf=X z>XFGs{RE(ez{i5|$7hpQC`l?9EWnt=Cxqgx_0isJ)rR`a~>Fc+cLykLt z<$4D_!CE76EP7B!cUebEq=>vuUq~xaO@iXhj0RE&Cnqv8vSo+)`T3AU$3OFqUXDyW z&|R1|Snxgnm^H2pH~3?2*UHvr%BkghY6bw4g;Ub|7E| zLp5n-J_5d3$K zpKdW@m+oZ)VsGDrmN$PU662gVc5edhP=N!+uL==qQ$aLNvixqBlcS@Aj->AH?nXvN^O=`SbR~O~G6FcxIc8AY z0-UygeWe0F_SfpicjyTxtHP6-9}akpB>kifq*Jf$#d8q9v}R9|C<-OXC$J-XZ&UH0 zl*EMJNIf7P)dB4*3V-nj^rJRw*{P-VvSr?2s3Hyu9P8W?0#0J-mA!Ln!klk>&U*D0 zFEqq_lhnHF;rq2mBP+ZNXKVM%U2FZ$XZ1+;j)a#M7u3U{Ixhagu-k=3?&V~HiDhFS zcksG;h!?{x!RX-z;fFY+0`lvYF@xIy;(mr@3qd>y$yf|Ibg}`Dn~k#`at-HZ-XT&9 zI6lkJkO~U1QS?aO@NXQ29J5KF;L?U<}{)qtD z(c6v(j`E}ci9F(CrC|$MZQvR>&XIUzNvrE+H8k?(G2_u)hOr+fN*+!-4EtECQXw4| zG6M$9O!7}%r7}*bHf)#4c(A5|#DYnQ2nk0gCR%^|fG5d@ceC|0m&<(8Tzje|gCeB< zH*>e$zIitQ4OTewmmQLYmB+pf2eq1zj5)4RSLdv3SvnRPN5GsM^d%L7O~e&JXPt{=(dBK9&@W z92$VI;N3tzB$p7`yu}_JKyjOABwbo`iZ(*p-aW-UHc!&^hvu*<-|sPb_pGWW{?`c00(CL`xPP1NSyZ*3eVB(ZrJzG zB5o9Woeq*}(;;2%98oA?9|j5bY?V7~eF`HglF06IgDM$?_q|J}8sjJ>;Q z)N@zVK<6t?{6tYY=tf5$^tP8CP_upU8Gn<7kBk;+8ukJ2x^$blpbKs955qxH>U104RXUD>f{pvNDgvjExGNMj{alUM4`uJ+KS(FZx1;D}>@3~$t=n&MI$?p{ zwG{KLReTW};C_%5SSo05Fzz{10@Ml^6e2x>?&#>ND-Uw$LyZNiY}D=>j`mgew^BxC z{@E=;Oa7TMyd9!8Z0a@=bj=iND`mL$tFCWC7qo;eE4%aG7=HgVj!MaZcjU?R__xX-Qof(yQE3E^o zq`MmqY7}C=3~waiKd_+8pO^XB@ZL%(XAY0he9$aA+b^*H&YK%l!E*b7_6{Rd;1y{C zrJ+#k<%JgTxZ9tT@3A#}TZOA(yD_`JQnruT**M#Ab|;vsyC(IXzPnq{#WmW0`sNvQ zia*(EKuY~pYeAVfo+>+=+6`3*trp!FGtu}!p0U~%*Ex7lk(+spv02ewx zGXEhHj>%7?1!Y~yu$xrd9`Wvtl%pwl%gzRyKNHM0kC0!fW#7}+zeUx1)23PH( zzw&MB<#H91*3!5eos9QFll;eisB3}Ipes^q6sJX=`I1HbWm*f(l%w5@gH}(WMDy9@ zA#PE0(o6sYjmt{#YJa-0N=)GX(e<9s6{&><_YCa(xjJ4i8O~8!p`!Zwnlni_+vP3T&_h4zLge59gF7~? zIa0w1{onHO^Hj>t_Xk{?y@!{|=2X^AcOsjqf;?yIS*OG?0uylW&vDwH9E2xGPM2 zNDu@Z1CNTYHbp<6)5$hh-@Pj&DKfY%Ct&Sl!da<wvW5U%yy8Q^F=*#=-Nk6v%dw|9iYc`yJqxOQ*=4t$3P*bqLQCPPcwhv=o`4;+Q zx$J4Geow+XV@Huw$CXzbFsi+&zW++dxjW8xaIs`=f7&gOKG-f z?I=mGUiK@O_G!S8!0~KQuz<~tjwu7(7SWh;Gu59FIu+E{n8g{bspCXl7jQpMMk7!A@B(wI%t+Rn2W4BMfOEvyG|9oGpi#oJA_L{0 zqhFZ7phf%l=(pr=Q$2lUU_7rs=&4889yL`MA^Db(XR2vRLI;;f#3IF7eOz}iKBdo- zARre|U3Yn+J4MUSzpA!DJ33X5Rd~mz?vqwMk(cZhxg%258i7#rp~FOvo%;A$Q|q?Z ziCLF}ip}9YhW)MabAGYYRQQgF?R=Yxz5MGxBkV6H(w<9cs>>(Lo=S~08a@drt% zXR|g|#S3W?!m4G)eYH*mOh<7aJley(1)OZH)<*^3@6Uey8m+!DQE`@;SkB5>Pd(Kz ze){v{wc3YvzkiT_`!?JqpcWR3EBxmbhNfoiQ-gx})x6-?+rb#{ZBZnN7lI02(I29< zhcriQdta^1M14JqX+Co%2EY<{PKa&-REm&HcMX<3S=U1p8Go>ad^mjWPn*u>E`Gq6 zt=+~oezStfUQmpm*KJ!_r}S#rz;Kpkpk&TmhAoX9k@-EY%KgPpYy9F+$gxMzAD;}1 zbh2mcB!OK@Qq8R~9Df{o@xlIVpT%DW`0l4XVQ3bwqmbdp7U;)weX z@_`pfUGp*P)$$WtMh!P{+$V&##PtaQbfkT6dbgf*_il3c-B|9=qh~jD$|pX);ulPk z2u^f7B<=Mc4YTNBIXRt?s+gQ26B1B7y?$TZp2c?kA!h~Zw)SFY5h-c#Y|H6^HM8cl zvf4UI*J_oGwO-!(!J58Li}W;Md+p$j&)QYV zgG)w>siZmqaIFrH9&MIY{jy))=TA0@>VvrS1kmIQXbn{jYS7XZg{VMf~cI6 zwjJ9-E-698dc`sAm8To`PYD@@?1xvnpk4M^2ruF&mv&VVOOZRyapHkr%n?p3|UuQDnNst8`9+Ijiw+m&~8?+>YcY&Gk2>6g}cmd1w z@A*l8?y*rjB9S>CUt>2VCKINRk*2;zjgp8Fb(!UNo7t$j-fnBx?UEab*?fAk-s$L- zeP7PVQ3yJ7-PNVZN|XZlkz&Q#Svx)baS2Vk&GU#-g0tOp+OlwR7sf~a;^A`3ubrG$ zuyV6^KaXrz`y}p7*~ODfou6u#ZcbH;d-OKEQF6o;P>Q*KS+aHpxBNVE_56>Ch4PZt zUHYO4L0XRH14^B5Y|6|jf9jTd1$TGOm)y2slvYR7XaE5TJv~PVkB#vgx!LQ?NwFY8 zg4di@**oy5E-7(l4?eHdfQlOW1&{u?Fl|juS8uHT>hg?*g}Q&_>TKpJDV)=K@$F-$ z{)(tb$5OL1feS*r#OUcJj|A5j6O&PhHG zk>x4$uBb=oG0JJMu;GsJPa;J35P{(MR`Gp}$#;9F8Xgg2+mn-|4HI*pBZtu*#KvmF1HbmNet-#4 z1MX5E>#G=PqY#Od^;R;Ov98MWnK!N7>vrgqNU-pfFkpP7c~5Bn9tKZ9rYrYh{nZ85 zeGU(#Vk|*vB_@@>jgabrr%93 z>2$e$1!{xNY*nFm23g+?dV7>5CZ~ zWdFnCDUQcdO%_?$LaY8+bBu2BQ*lApY6x6~HmWMz7t7{sPxA6~ZwN#uU{>_2Y%Bu3 zbXmAhuk27v;)M^xvi|e2wLxD76$?gt`ZwK^-!1FP4-Hq`5ceTfv0q45>lN@T_GniJ zny4Z23jcNq@T6&KH0I(6%o7M5vTNPm z?!v$W^Kz4Vjao;gcMmgDn${M(E`+@=88A=J1iUXjpTAGf?Hp)bGAhuR>9C#8bF+;v zSi=~0ojMk%>u#n{(ys7$%pvpO&a1@!QTTM>k;Ynos)5U0BP-tb*|tUQve$T=+uI|b zjQa+#kJr12tPL}!zkatd;WoGKT#(d&9E5aEY}9H3Unh)=97*4b=P<+j!ZWr;BOBC= zjv1KT8kFa4PEm8@O;#7dXj4$y{25yaLkLla>~U_GTS3_;#peyzr8t~2G{#h47Ge4~ z)6svy25hcg@01SXjo>h!HjVv_iTGyj*NO|OXJ>EhLqoOb&0jQn{J#BQ=KIdpRtsyu zyo>_vd>K*ZvZ_y0@C??Noku{5%D)BTGH`@%FVz@Q0_Co_K0hlvrc(|hr66Q+yD4de zJq2}pGFEj7H{OlxLTsb!rj~xBz?v@iO2>HHysngCi(YV;`%MIXx#Ct*LQ+~PT53M^ z3f|a$dFwbMecGq%1kznv@jPW79Cfy8RX)@&W;Mr538T=yy03BdC;w*3aw-6R6oJ}dp{`L!Y|n>33_nikz52)(|IG0 zj=vdn3^NKC?MPHiPZ3zCqBM?A*iTjKU#u~}>^9_guUucLRHO!J@9hy^tPyK>=diTz z_30?y15}F16I&bG7}MhEd;F_kmDG@Et8Z&WARy@gLoWp0@J>*?8(4>=S2 ztn`zqvgtA%q>1Kg1x3IzSyG6ASG4Sbtas4CJn{9bTE@@lFhY4Rc?ZWJpjbdlI+|P{ zV(es_9=e&I|EQNBf^H(9K*o)wm5DanXfez-9$1jxOGX_rJf7 z2v;KsvaWej~#ZjGv|mlh)1hSiC)iz#tK~9dc@HpH;-z z%53!V|3Jh49_NjY>|cmmzMkwhb$i-6KHyix5HmV-Y}+26V*Ohf=|ExhU39)=*K=c5 zuW3>Uexyi{YDm)BV0OwYR^j~Bb$TC7JA!kL4VG1ov18UsyiW|bnmTJX)!8<csE((i;H_BOGD>b4;v*@+9xbu0W|lCU*uwCezei zXomX!`@Y^PDJH;GLnduvs(d)|DAj5Kn&N)RH;6>8=FTmi5NY!p-)Ky`#rzFuUyP@n zi~ygrg}j31*9s8(i6U}NPjB~s(c0@YZeS3+idLF9R3V&PoOs50>uJe{-`~GZ+D$n1 z?h=r!xtAyw&tJ>nL7ZyfV~!H!3j@`49vx$Cv*o!Sf7vGoyEdhT@2A}QccYZqY5!vc z7I|~YcR0_KTeU{6J(yN!YbB_8ckLYge|kOtKCFKmp8+4=QUQ$rSnAh9wt1TOXAwYt zXnX7^t)|{=#_}nEHU4ex)g?B?&l+f-xkOVQD^)+HaPNHX2aH+#5AiV@#LxBHWSd=( zC2&p*xK~ikCk)sO^OJH=Ofe8GA92#@-2K+Ecg7Fl#2bVDbHaaHu!!Tdrm3O2)sg)P zap_^u59ZpW4i5MwyKa-e6*B-hmeOnT`7#n&Q6d=zoE5hQKSZB$Fbo*f`38@p-SL>a zI=cY+`Hc@%ism(3>o7PdXhQz`8rHM^LEl-Nn$W}lSweES!X~;Z5S9SO?Lb-}VhQzE z-H6r$YuxuL(W~a<7a@pt?^M6Xj36Z_J7B9zwd+~X7SL6YDJ*EnfOm+>ivXJmplm?n zHMSR}5@i?Wn*03C9s0-tX#k@-nEf15Kx@a~rVWzdSoz$^%w1m;r9b3HrxJcW7UE=#D^w&3_ z5l`4Y8mtj+J|`o(@PaD$cR3+>{@qZb<)NHkao2&r*8aE|%1M;O5cF`w?m-a-nv7n9 zg^LWSp*@~Y%Tu1@7%L-rV+pk{}QkW9n$W(Zcw21y2aS)wk9LgB-Q(1d0 zWkoG$u!^#R?&i4Q&7hfZ!#?ju|1mqOpGIwVTU*)vLZ1LuHED-O6+@3H+Kz8A%c-ku zf`SKNIRwcUi#BX)^)*P>Li+T>5AQuGqNPoqXw1+~_5AzfnlcdYYq1O4`w&;-t3raI zhF9oIAe9f8v$bWNa|Nj9BsqnB&1ax(wr#Uw{qgL|3A;M>?Du(fy3b~qKI%H>;r25FcmJ3 zFY!GzEp)%k(Xs9Uo5uHH4t34*Ad?V~K>t(L|}`-5PA6 zaVg`*zvw#MzD5}T7Sd(ba+JUWGM zhy1~Z7Lbyj%(dt~Dg>hfa)tlJ2IIDy2A?A=@FvIuK|rIcKngO|<9O+jMf*$&7UI^CSQr| z4J;1(bp|~6EJuj)IuES}XuBIdl zW}dq7A&~kqXEq5O|;`kTpjuILSjy;N#uOCL!gR~-vdikbx~KQL9Mu}?HG|aoqZZm4f9&JAti)OUZ=ToE zP+;z}p5kYO!;(L-;39BXWFd+`tuHgszKm>^7H9ZVcKjZMRdA+6N(msX@kvs7X)lq! z8-GH=u5CdWMkJnpokM+F)h;ri4qff?qcrVnWqR8G`xXE9Inqr{#ygq?sl7;W!TBC< zcC`64G5lu+sCQu%FdTE9YTu;$VDw?5c+dm|GP7?5CtZ;ETVz!3mR|QxLv{q|<$n)X zGWJ@=5215SnH{q$3AjX#pJaQ0zSQD)br%JVU`p4~Q;geKqry&q5Tg7?M2Dzap{V`5+1OV{hC z@PphA(7#amGJ}5Q96m;G@VD!j!f=>AN#oM?5_;n&XjL+ppz>BwlwKrv5O>tldHPO% z0DrIP|A()5y?-wVn3=kzW1f|tp=V2zYAnORacs|ZrY{6C+FRoe5op;fo+CLUA~QCp zcVcIv@LH+D9mGk2JZGvB|JenZ;}PW1qw=O-Y`+6^E;uUxPnz6xi}@uc6~epH5JrHS z_)+Ta!%F4iq^|+lMG&k2fNg)g_Zg_5w)0GP6=oo70y)pmjitNe4weocSoh~Focy!jfu zS7(Kw&rfRnQC}l4f(#=zY_ggJ)YGSAchWB@Y^f^A5O0iqo$xVtUk%akURTI8e&Kd? zJjo8e^0EezA9!l(_&Um#wouqEh<&_^OkleX%+F##ppW+3Gs-jT72)@TFmNI4?p zF*Gf`z&hQ4DFdvju8^LO$z1m9+Ux{1&Y{a5COFqD-DFocm5f_idnCQPe=x{^pMe^@ zFtLF)y~nxa=Hc5N2&}1fF9rkQqR=CRvli8nZGAUkDe>o^{mDh1SUZEtBS%hQ;`_4p zEXBE-yv;_uk$ace7m8f^Tt)Cbe^k zN5_C}CK`VD$W@2!E%vo!c)?Gmf75Gfd2fwkYCghI3MC4hotq=aMoSQIy9}{OxJuh| z-WEEJ>U_t1OguN>*~5;Y`J~N!{$AxZqECDVbOiB}IkY}tUL9{& z5+q`HqpXQkTLxcN3hNJGn8lLw$l4G6{8D`C+(yye+N|NszP=I`uS?q8SB{Z-I{4*{ za3n_v!($FBK13l#9gshlXv*CgIvsp<8A9-^jOyqx4Ea$U838!nwHQKshu;pxw+?QE|?G$#%^08x2JuIPSqc7;Nv~uCPmmX zuIR}2sg&)NTgO44+{MVVYmO<_Y(Ku-Vn+Eg!o?rO}8MP^zwp&t`ygpZltOnm4Zv~AR6prWAg!nHq8 z2^&ubMlY;-MnS(U?TD>TTjXD}i3GFhN!)cj=|1u%Jp7tJW950-+Whj(g^2kJtba~k z5o<%mY2BXBC7CuUT%9Ap?|j?;nO58YNDUBx}^?~L}IE2gOljA zZ1S=riD3KGNJE*`@p#VjjW7(q=z>{_8jg5mvyTb5%>_YV*3u`TD|(US@~gew-HVQ# zoZO4CiFndMQ#!ymAncrm^|pqv=cJF#|5y-w#HC%f$`TT-nn=>Q%Of)?&^-YMiNla3 zY(o3yQTSZ(gG*&O(|Id|H+3OYZ;r)M{&g}#=4IA8)-`1|X;uZho2%#N)CigALyC_j z&vP@+B(6Y+0<~af>}6J<3jQ+r~dT>;y3n467hABL$)S);``- zTeb^VM}#;O((2ETKsw*{7yxcX8zYB?40PbI<0LAFIxJ5C4GMausf$N`UWxXz^_RKp z_1iHKobnx09o5vp5wcVbV!yDBf!P;87er9|uNv4p`s&&FHzMA?th)w4N(wG0b*!h) znn87A#QCuGX`6@>?}y&K3yOAW`3ra$A_ljxx@Mp3@*1Y8I{r`_I#PBZMrnvU@_wQD zgJz6;Xm7@zALQb!<9rAWgyUxjg&=*jQVjq(RU3vEy{{AtqS~@-$_WKccOL30xAY`Z zYiOtN*5h{_B9K`FBbim$4A>f7mROM&1RBC=O8gWcbOGhF#lhaE^N)scqu_vk$o(W? z?{w;-#qiCUqJ{AiFnJ@}x_((5E}sn~YY!?$(8ez+_NU1TTD<>k-Rft2HrpUX5I=dJ zJY9;@t^xs5a|EAFx=0W|V9k#FAL$!2Y#9a=u=?R@1k&W+6;Zd>KOag10i%fGkS>QY zJ69Of>vBhCUP=8d?@zOD2evZnSxhMLgx2 zbjlBhNi~NtRex+y`sjk^{v=Vf8OhH-ztltpTq@Rtq z3Kp>y>vj&b6y?8xxHyfIGlE(lSpSq9&&40bJ>|^YCT=ri`=POPn)ggtbm-N7Isp*u zLgW`cv~=RnKI3XgU&~CKjWvQ2a#s6L8ij=4pWixt#yUIHk!dmePcd^Dh+3A?irUS8 zWEaoBWW_@KmKczcGS>?CkF=xM!qL`+2HwY{shNM=(b(fUpICh5MOL4e}B~_M2FJ&F@_Vc3rUF-r63vZXPkswp|Wc-Vte#cz;CcU z!I>7Y9~f*iCrlQDl1&O?kJW)rPS1MAzg=w2F1h||5!-TcB9ztCtQu& zkMQU00)6ly@fUv+748q<9*CUUvs6CaPzBAaXmrow(WA1=Exq?mQgR>ReP#rONl4om^YiEI1{nfnDcLkUxaPA@gkvOe`^`|9t)r{*STjF%3ZucX zL&oPh=mCfch-$<7^q-g)$VbP^iVg(;#1F2Go~)6E$Z*7w*c(H}zFo}5QW>gun3RBL zb4g2&9wL+;^Zl!HUdyQkKd4E}ycuXx%bo+tR&+?T*qx+QxGzd0gb1;W&{ZR1p=$xy zBs8WFf!?th(lW`vAr3bk7KYq7G3%A#_RcmBK{NcB!>8->ta>>xSZbBetdAYqM-7#& zn^N;Nk;F#!?$6sko3&-#&!R2ZhY=#@-pb#TZh;%{yzhmpf%eT~HO#8H=O;wk5F%*= z!_P07FY&zX#R~o=TvFTPy$G09U>hqas@Z&t`2^m-cXD;k;bGX@NX=p@O_<35{zh-D z*7WH;A<&9)@};6y7Gj!8=ohMJ8O8yNzjptQV2$k}x{vc;AgRUx^>gLyba zol%`-b}?^{B;GzSy`dT=f9O};&SqW^y4@Dn`5g8(h~zppa1&swkQg7X18mU&-O_K` z1=bgwag?dXKOuKgVtR;cvr{=!RYkK4R^d)(eLG3K(VnzhQ9j*Ky?j6y9D(XpHsFBN zY=qs?26iy=f>rX`L_?(Rmp}l)rt~+;NwZpiWqLk@omnU z`R}L`n5srF|0d#fwiN+PyZ|?d82f`#ouw5l&442k=iIi%&fSH`CJ{&b67B&AXW{aL z51+2{(+c(Gn`nt`g~@vw{*>C1n-mZQ6ylv>`4#LMXXPKHu)@1lU|5Nt$qQXlcpzz! zNz$Iz-inAaMZ2$ND#5DXU>?{`a@8{;VitKl+dASAp3+N2W`T!(0oj27kqBc=Q>1oA z0Uw^%o`~oIOUC}2sEvffagh@gd{9U-08(DkX95Clrxkga)&s*g+WC~^!bu;n%M0@6 zgU9W*y+ySL4~6_-5hgb2keYbt4yK)@$pLN(igbiQg&kPjLfPLtQ*_l~2X@i?67O%)(&!)0$Ic zA`iB6jyg_j6L05VZCUrDRD`n{%4z%MZH*X#2iAeU=ihExMuYDQQo~}B;+pJ_W~kl= z&k$p-;4rlFSHu7Da?(wwo8eZo;l+1f>++(Gp4WK>a7aLOe6mTMy83s#7h8Va=X}C0 zP!a<|pt~=?H77y%*83 z!FTM@-iRX|RAAWTC-=;Hp*U1i{%3&|<0XsLhxnrKfNXE5TtSTt(MT~$T#3r`T?A*` zc1l#(cRYx$@N0qRt2cuz-Gv8oP6*2#16FMqKebJQ^B!{H^V5Q&XY3+G8sXn)$yBRl z(UMQUcaKINclrg?RXbljE^~Qe4j}kH;l9Imx8gy0Simqutq%&s;p?^gSvzmSg|McZ zB7%)UR5+OHEn_6a6W#bScfF`ZW9fdyh`6({gg(N{pgny+kNE#lKw#wn0F3AiNkDF3 z9U%mt8^jIAXAI8IB|%64!@NTKRNgoF*Gc{vfD2+b=47$&IRG?*RaL!Z`UxIf9&v=Y z{uAsDM^l)F0YV7qnyKM*G!0?jg@by5%CH6pHGTVM%ehSWLhLQ#eA?#}2Iqe+M(COU@bsh8hJz6vAiq*>-EgCT@} zPpcC|6u5;apZW;?%*`Nl_^KCBpPs~1FFAUJ5d|~_k;cBI0*N#kf6(6=46#I@9C5^G z!|Ne=v-M^EZ;}$GlFC-pL?S+i=bQ<_To*n8b-a)l8tI$se%U~z)F=$_eo@PaV3q=r z3$Bbki-d^21_UXXhv>LMLWiMP9c?58fNQ-6N-8}A{ysP=D;SbwO;{Z%jfIPdJ6~S* zn`|YKlkufW= z-7#4L9u8eR`6sn!X)4s}8DDqsvxxhZ{hVGG~Lp(LZUPBfLkMUzK6t>;(#AGcfvTMSV1XhBnH-7&_O&?&2on+B0yV((_!7@q4YW& zg#j8M`}_@^+b8v3|HcEkaNY4U815q|dKX!^TJ{6B!(tIM4-m`y@SXi|bFtp)=&(e8 zRS{Fp&fk^Rfd}E%fqxFLw)V%!GWJC;V9*7~$lEXUTDK50ZN^OBsH-gkl^x{zPw%~S zJiLkPWD26+fC-Zy=Xtgjb%?{h4fxN_cmOUU0a=!Qxz69`3H_gAAMzh+$c;q^UG_3B z==8N0)@5%13-raZ9RX_vO{qex5m-0*^P^9orhx z$)Qe>0Rn{IEW`?Ll-EU1E5ptvNXmjf8T8kY=rNY z_atm_TIpL9(CI6k2+;42VeyA)KhE{yP-S0r&qlooBf{gFYf+)lQUv@PG{`Xe)W2G< zGuP=NhH~}%HDW9ow7oG-wIqWX7h~Lk%#gM;tcwEP$1}u=CH>43JFNPLff8aCLZ2Oo z<)kA$$cXg5Wq;BJT)G9s&M3`-67Lbc&S7Mlno;JCJ_KwFg&NGBlf-3fGv$zEvGTl- zermM&nh!7V@)-w6Gw?{k(4;`s{r6CXB*m`40f`HOyb&&h)B5zM$<7=I+jYOBLv2FR zS^(7%s_-CWWV)qHTyyD6V20N#G+8c?RAF?fbESPUT&yA#1)#$|i%kU)U(#0*W3;MmD z^v7qM#`mUZOvgLY{j<55@Lb6A`Q%iIgzbs>D96m9sgS9j{@&HIrMc(?CmK^b@5-Zu z&hEm6!k%4W_M8l2(OjAG!xZHN|2i{`GmG++*&%T~d%oScBd3-<;x{CUf4ny%7Vh!L zj?VMBQcfh95jS)Zsmcr8=Vjvw(s=Xbi_8QP{8R9Y9iTyy3sOK8m=NqREN2SKtBw1a zpQ&s^MaMYcvoCymfCEZ@s?C!i1kfdzyO9{(9wofn|wB-}as6(;} zJ);`mFQH{uB^aJz>fA+7RX%v7@izD9(r4W5Aedm(YWn-17naK0W?7`SHRSS|jt4_r z-bnLDo3g!YACPifwcH4PLf>QA>A1A>K+1a8D7OEb^Ut5%A2s|BmG@&(W%Q)s2h^dD zW*y8gGsb+5Qs8&_9aV^X_ImyAHL3E z2wyYGP(Hx+*b|2iHPj;8u!H=9a@oat9cz4r?tI9__W#~ z5o{S(TFtPW8ut9GXiuufJ#}r+EUbWsTKW6l&WPCOoo~Yz1PW?(nUS9?<4)x8< zhqpKKGHvfPUx#(&F86OCarrR*?pM2RRBp>!BV>xgl&<^~$9km6?B|`Bg_1Zic~c_Q zU>vZeUb&{u$;_zzb(Df9#=QLR256_BZKu?{U9O$~2#0YZzf&sR_=Q_X$H2R_UXx{$ ztLQhADdJ?$(>hmhk=`q9cl+Dax;dn${P^(aFor!xv<82}|Fq+y{z(AiXd>~qo)R^= z?dz58Zjso*J@#2Cx`04V}Zu`(Vd=f`kLzuZO--Q86xAeu3W&_UI1Zk-bpqnYf!W zi|j{1$0$|&{z#=%w!Y98qJWd{_pU|LCW*p$a7 zg2!qO@)B_k-DanEF7Q()Gt7dA%C(5bec68KEnJJ0iMEMN*n8|(-X1GtU|K1gl6Ts< zcWfkUWPa_hCC<`(mPthVC`L!en-kP;x?#^a`M_l&PJc*9c=aPOp5wCDQLzVj+{gCr zyI&UWiGu0(k0#A%e`$?-W_i6Dh5tbjJ1_H4pXS}2Ak|7hLKml{6CxK<;4}y(+WDs-%=e~g74Q|cd6jK+~xClSq0R-SfrlpnEK z<%r2c$E$fB;Tc_dFQOo7#JRF({9caPYbCiCyo$1{Z0G_mtV8k-l1tG9Y+jWOa3LWD zH9YxICRcx#j+tT@o+En>Ay>k}JvxCq@vRmCl@=l;NULooeRW{+?5gMzi<{lJ9DNK| zF#8Uw8uG5)*A7J?fghvmWDSMYlV*|QmZDsT>kp%_vbzRonq{B8k1dbaUqeG?o{j9E{Pfi+a+A$&wSsVg z%XnkJzpB8V;)cFH-K}=^?$tp>EUe&$hK9DbwjV!!Oisq2e?dYrMrp<#5n>d3d}Y&$ zaEQvt4Lb}4avPR}RO3Q5xiFbYyT8lGV=QZ9zoHC>q$6e#cq?1I9X?>0#2Aw+`Gg`Utiza z+S=e?tl0MS%*=3ERHWw{T7P!v9u&{oN50A0<-+rq=9TTbjh5+vbf7n6 zpy9Qo6O)I0fhC%~J%{7BZFuwuAAUhHYJn5es8op!MECdc-*fp|x?A0*EW>3pzuLr- z?yrrpFCj_Xt6z+cZoB#xn6NP}uwNHVZzxcwz1!!?H=$1yX^>Yckb+Mh{c~!{X1>t_ z)yvDvl$wB$@axyF;sV@ANH%Z&JfUJZaM5*~&~Cw>D#%~hUmNT77%?ixXK=boi(?L; z4_tU-%~m6180ihx>Xr9&^@!{Gb-2p#^#-4iixJa0RnuOp+>sQQ;3IXHmd^EWmF1Uj zO3IwNho?Wh5}Q$)=+dO2tNJZlUb{loQKB>~W-In1N0>FRx@2!VPqkw7WjEY3jOpOv ziE&kdbaC?@@+VgLj|H>YNlU>zQ<-SPW&_o3$~}t-u7$VG!p%wol3MZp6l6XcpNyI! zkl&IUxtsljBRT^QskNj=sH`0fS{eDKadU{;f3MBz9cqHpH3^9TIcom1 z(+%dB1xD|?Icq!A??a%@5S-{4Fm*|uMdnjl=6_rVbaa~Z@y9ICXzAxe!oScWG~U2D=6)A&KPhW;L*c(`Q}eP(6}l$v zjp@cW$f*oD+7wL6Q_v_DVNa7({;%`^!m!B>S9dTzf zVf4fmu5t=*HiyV9Q^q>m4C)YU-h|a>VOrfEY$Rh@0AHN>G9J^$bJV=j(2Y~BfM_qf zSz`OF-bk{<8Mk2R-9eZ0p;5mV%5%8qfX>cW@gHtJGw7345^2ndO&c8ApR$XE0R?Y7 zyxR`78V~gZ1Z{_{mb#O#-EgcwGamqHyZKmgQep4wa@iZgRJ#Ip=3-mZ>aiRynbu1| zVnOE=#tp>smOJN_%9%1|EP*$WLjIrD-ZHGJwOs?9ih>2G2uO({C0&9v3L@Rz-62RL zpn|ZJQV@_vx@*#@BF&_`krL@{=6R;BZ|`rP>pK6=`nTq_7Gu2i#2xRr+t7W#Z;Wq( zuASwq)N6M!H+t->4^K9RducqSojWhyw;6Y7pq^*RY->P;n1Pr=bayNkhbaiT~%t9BXFXCbdo zv16$3Pr6oYqE^R<3pCheT_XFwYE(J3?N9A*?$ju&%UmAn|8Xvl-Mamo4MlFil)@%0u5=vMhCWosLA;f0>(Yu38-}?eF7{PF%lp z!;s79hpT$Q**#A)Z|52{SxB7pX$+{ybWIveO`l|=a*qGV+ zu)KfxOB->$Y5VyyLEF)my;W_J+ZK{xAtCA`SJwtt3HGoSJ1Gj%N>vXr@yU*=;lrf5 z^6uK{)5y~oLn!mvP8>?_!qc7n03na44)h)2XUMkmuith)j9oXA^u851f^0rJ-CvJD zw?-bdN6AOnn43J3i{V=F#gCCsI1x2V52tSRzRUmAb!~iewR|cpt^u7TTB8%NI9DN; zDD)oJ5Uw-mKso23Sa#jc@z||c5BwG-5*N>4W@at!N!_9wO83oJj9;%`ZxCmRtan}( zab^vBsuk0asfaav)xbDzZb0fu?X%1cW&D@wXi4N&O82bhk#Y7lZe7D|spjqSkfP-e zoqyKY=Z`J=_qgwj1@~=UN;1ujVt3vp<-Sol_uE03X=`GCYF+S`=ZKJv{vH7X9V63l z_ScEiNGEYVf81rbo?s!FidB7xjM8i8HT6iDZ99#0`oXcV0YP#3qzBTxtMl78SQU%z zA#kp@m)o7*h}D{3tX`j}wi+$@XhY1cTIIT4xY9*jALm#!^0{b}q)cI?$hh^#y9TT6 z^8R$u2-XDI^@R=+;#;W=9>q@;HKQrVa=>YB!_l_zX|~A=1ReOHV^Rs2lS4$}?=%|J zi}VzUJf+}wHKOZ^H}}cu_;r!gb#)@|*;GPm#>d(+hk&98Q3QXuu$R@7ri+rf+C0Y{ z(YEgHb~YF5TvmnavkiUP;SPb}gX9d?u)J2r@UY-uvc)20KK|9IdLNUqvc}Spv^%V? za0M$X^Ur_V^gi_{Gz@XRD||RWF>H~RJ3c&5OSb%eO`SL+);YcG??tnr|!mRt*G zj2F$&18qW&`P`eIh>4bc9%+64C`#tm=-K)@X?4+3?G6+WcTzZ!w4zSm6M8w+RCXHv z$qXGWahGjdwy)VNk78YI-LvILbu9j#46`>f!eZkqYsau}%E>9o7&}!+@;PzJmr>pO zcm=t~L_lfZxF8Z%EuES^TEE#u_VHs=*y@nJPrPhix-6Od;g;}J3={pv!A8UWh&UYd z#>UeZOGNKl!+k2;9HLBOSI^FlQP!}0!;f_a0$Cqy+70GPiurwTw zVsFKz^=cuqx;M3zzp+v8e^#($iX?a4Tq5$+zHXP6jK9QdM?#M~2rKBKQp0ura3tr8 zc^|3f#YEQ+I$dEOXNI$swI#z&nIAlGi5N5SjsGnz?KL9qUa23&LSc=RuGL2z2M%*v zQwbL~;YHlLb=0y(GlBFvR@2n%w3!{@R9>1G@b=?4J!u~AUgTn=gM^_Uey_DaU)a3m zLtQLS7agU;Ja$NfI)T~3;H=&R!m4$D@xJq^UBT4o?8n86TW7 z9IK?3^r2lv5mw_qC#Ub8s{Tyr?D}$8Rz%7CF@AT#9YW#99?5;Vngm-Pk^+fc^E8zm zyub)t|5>CD3;@}hXJ~5D#=S051!rqCriH%KMAIP~nc5pCD z)LZcS^g^V~WR0fc$EcktB@#G*j~$EiO!!$k!&dcT>(iR>RO{T}Z1`e(F)vx#`+(K9 zYeYOpjZ&)4^}*Tx6`vwUOmC$l?tkxbY)`TJkD9Zi_d3e#jOTBwyR)Esf0I|65go`{o08Xoz*#9HjL(7pb0Q{gX|?eDstA7-7x zVEpYoYOEZ;I9M)z)Wc))BXz*FCC2OI=43u6o7*sM>Q>k$>StAs=(C48YN+e=xk;^q zWp$@z0rhCCB^lGk_j!^G>m`myI|X3{T!ROHlMrMX=jFk-VRJnxWN@)hC-X!7?&GtSwy@c3<`L-I{vB)r!h^t#|!EjyE2mP7;3QU^cafy&zTKyt=40l$vji0=H zUN}AAS%jw8Q%435Ye+BQSqVR(xn2DzL{lE=nEWSkgoW%bFBW!r^`*O~l7%#AImQ>O zIuM_p+X!U4{|sOrMN1OfOuY_4=`Q#BJ|-XN3yRRDhH7_gr$hfijyf|d4_>~a_tn_M zjHtr2{M%r7YS5n|Rqyw3skSqTWT96YCEbsoTl0c8F@(hCtwfg%4Y57>NTObqDj~QQn_SsyH2fvPriGhI!G+pFMuIs4>3>F7;u5|E7H${CwkZ&a!o4 z{g(`t+9wSGJ|X11cezxcP;PB4Gw-xnhTPsd#qrV&J>{+a?I`whoNdofK}bfWhuT&v z3iE-953O@kw;GKg)wr&y?2ro_kZ~^>_fIPQz-fwXaK!0aInmenwKV&pz;nN=K!1wP z^5}4J36gtzm+MgPXqDThiDYrx#ltcCdYVclw}EVu*RMw*%-L9k>*Qm5_2 zO)DRfSX}lLW^8vKDW=q~B_^wf)%_ekTV;k~`m=aNrLxnJoPR@8ns9oXL3ko09Er7= zMp~_2I4$Qz1U2^cKP}vpKn?&XUXC^-L~T9m@M4UT)V7Eeet)wscr=97EkS~84(D$j zEA8CNeq@y{^DSr0n$>w_w6rRSdbn#tf6!>TeMF2E>(bXU#`TWIGGimA;im0Hvxb0u`_Y~F1VMh` zmj~waQ^|Q=xjyIwR4mVO_m|zRd1c1LrrU(3d^Q@wgNd>in3-5q&PvqL%nw~Mw;El4 z_m>sZd6I-BoI8i_xxdy%8x_T}YE~`5X8_0M?qmNiVgUg_tG5=TUze{%c~wa_QCLpl zQqoVLsDE@6cR6ufE8-L;qlkHE-COyh`Ng7(%0gc+IoHF0VntEWSBfzTVEh}jWSF+ffAc7#i@CGh2WW@&Z1gwl_nky) zsMs(q(gzCvp!$S#&)<)-Zu~kRVLEiy9GaYnd1ybFY8l=sSj9A2{D~&**iBd1{&e-) zHBsDa|JCWLD%sSo`sb#O{C+3p_l8y!Y+Sa}zP)iT0dbRp{uWD~TC*b7HIW7bHdj8u z)PbEHKhCvs?*~`O^j^Le!E9N}a9(r--f85))hFEld83=QYs=o;dQ-Yl{g?D8_Rhr9 zCuogsTe%tdSzRLU+PXp>fXG&Yz6z+F;+iL;3W6zRvw`897LoYL_OaEnV{%9VMLi9h zQFp8N@%XkMcrX)TVr~W(A+K?fA)nCwB+0W7NatIL|hR^sb&P zJUn{cRQ&c8L&MLaXx}EKYod;q|7*~10RWZea!wohJ@T^rQ6JqWv%{~NFO*kA$ztZ; zCD|?t5U&7uhv{(v%ZSeGm@@5k3}k1#@J-&rR+?6Waxi??+_SY){kkf4I^@Tj1Gu6g zG3~hC8cFMl+s^EJ=bG?HrP;5wGO|5+cp=2x{cUonD6m#nV=lgmN+7Q#EL03M%UR@e z)`rZ4a!g?3R7W@T0MA$Q8o&7bcesa{9@Al70Th2jBZ8B2v%OXGYg2raE}f>X*In(o z>}!KARK}d|d7Bit5+kBbe!$Lf4}LbB|fy*V)RE z-NJ&PQ1si(EKH)T(tg4|T{AIyullTntCVAFr|;c+GoNDHNJIC*(a-j5fO7qPA1iYI z+@nsmLywq&NL`{g^}#E5ZVPiGoqAo^>t@Q9UEA%`jREE3O1RMmTudd}h!O*eeQEvz z^j&7KxSa-owM`nU3hHIE) zQ;-m?>enJXAW8SU-7fYVQkKuMuyaMe48=hh+GdxFk8fo_?}W*%_iy`G5Cxn2WmiZB zzq^X!zJ^(#C!r0n?tf{(4?nq$pY2dwjmZ;-6bA%f4^#QPa4?S*&+AZq+s@GUJT`eB z(M+$o>Hj?VVOPiXE0^BN%_0zP7XScG-V9P8)VI?1j58y{#*E6L+0f9Y*f7W8sbp!b z)5Ro*_f@&;r52PZwfiXEuinF5TO&uutftj%^GsIw{w_M3Rm?yi4s$gN!5oj(9PYUl3 z-Cbp(9HBIm8S5i{wl@pB>myVCWoYf}x%qpTN&6g~MQs(=6hU~aahc!mPF?goCCjeE zIYcJeHBp^F(r5I}Mq5j_4kueKV+QiL+0aEH)xi^mIk5-?hm3H}Dv6Q`)h#ZPqbE%1 zxHUh?=Grtb*v=%A8IG$FX^*GqNM-^!5TaFM+=)Cb*O zg{JZi6%V*mbq@jz{xyV1tpT9dDm+hmk^POsov8J6-_(DiHpM zEhQDV<-)LJkvYR?t%^afn0Wz6YESm`Q#2bfJ*x}{r)Vbi8GzAMY1?C$8z>`}%5Fbs zt(H41y-OSItpYIarH1POiM_?PlVWpp85|cw;=Y>Itm}~o5k=U&_cB=Jb0$NnHNb1u zsf4#*4a5cTJ}&MtSq1Y#{#(_li^;tlqe+0$o(nzQ&S~MKQ=%xnAr<&fA00!wgR#2M zflcyWtZ#|F4{wpDSCT{ZWgvieM9(7>^f9{-9i$MP(*0Ep4^YJzTLi?#_u|gv=btM( zNTq*!meM$1TBZAG`BUCy@lLLGN%noF`Qscs8iT~QiesCa=dvq@a50NmG2$mhb)wS9 zm7m;6^T1iv1}(ooK^e!zeZi*ty+B5|$xH$< zw-+p$c?5LZsGbbo39U(zM#jx?twjMV95c^dzQliLwNeJz2K4X7?Z51Y+;Qv({?ze| zVS5kZm_1&v{X_1(FS0;00qp_blKJc$P2?^Y;B5etdlAmV`M3W6!8gBN1d{IUojOUR zs=MPHhBM`A7kqlz64V22`=feKjTyz-3l_3B7CQfD>&G=s@IK#qT(C6CEdHy8Q*7V& zM#%l4ez%dr{a!5KP%Gp{NGs+$fc$Ueo&+UC2>}8jkJ&;=-QCwQ)YBupa}{@cI#3S% zS}}Q2aICv7dRj($eh-=0JUzUGa@1&yA{moaSUv5*?9+x08Jfo#4%Hz`E^$fwGZGW& zqP}JEDU`iFkREwMQ*K_1|1LMat?S%xI7bS=NyRoXV&fJ}>P3n#3Kp4HF{zFBPC!>d z>;c*_%wll_s-LVmkIAgpI5{K4 z2>Tvs^N0GX12=Bu?(UT{4iCz)U#Lb6->8}Wj?58X%6}~2p~Z&ax{29BszD07%v@Yg zFhkwq1F}mwc+_GJ)F-$I1%4M%we(?+zT6;CHEgq*bu%@mR$tWI`7DbhPv2tYlmdoL zV6SV|@Bf}mU|axMAT1+}qB!~Ft>Ua6ssD-M_6@p1Psh2){V*&SU-d#>{j)x|QGA4m zGbSEolYRL`mmxl^Mb(g_=4zUM0~1nfLPQrY$3DT=%g{t*mNxt7WT8-%ZC3-GV{ub7 zLpHT)gmspMP>!k&j{b_(mo>c&OCB%%8!E0dy!)N*01W@VQ4z@baC|Yi+zrk=0As^NBG~f6L-Ga!Ee^AevUqLv6qUrhbpoU9jII5XokcxPyhD|7vv$Ysn_SaCkd zqWlkKv4#oFq~7F2H0fleJs;X>wh_V6nI$r4-;Xv$B4j2SyU|e;Dgi#JQbg{0Un6UN@7@0#c8de9kXg`a1o2z&1!=4vZ{Oe+r@hSwS}F!sqF!%A_pd+9 z=IJF>ig0<_#iu`dZ760SH*k&4UVr5alVQF6ya5D3lxT;yW|iMON4^!#x>`ntC+KpP zt=0ddydR07r~aHWh z-J={?q_ZDpGA%+y5qLKP#XyWhNR!&*kM?ju4Vxd{i zkA0Fqxxf>0LHKb;JZuV!z4|aFK?v&IOgI9ysf$9MJSfKxm|}q$r$FrATz6I2IZT%6 zy42M@e`C^p{Gvx7yUAmx>a;pWJNCMNr-c}B!KOcX0wE%6cspC4`t!s`*)|$XkxCr0 zxX8mw8#5Jw+Gd27@wrsLsaHYcvE^R9qt{IFrF^w5q00#exSZyQWb_hLgvhe zhxDa#FG{~Sol?{C2$r&M#RpVPJHq6$$n3}^0zq9K^~>VuqeyMxYt--9Lpx5F3+ojdE7^)w z+6sWQ!M-=sWt5zaz7VK3(Q}u7KWn zenOt6j?YPi881}z3Iy;CkG;J;3`K9`K=$cP?Z67Ixjnz-Fu1weF9!h3{b@LcX!7sJrIt`3yVMxa9PV7T~@-=xMH+94*j;jrE~7 zWbv5OJF6mTeJb$y&Q83n=Z2jkZHVT)hJKnCOZJdlUQ>6m} zuHfmhMWnG3#c43V9Ft@hgp1dpe0kT>B0)(>$(_c=&VJ*SQek;a?aYd;xxKfC2j8iL z$T!f1mV+>^S>E#w+JR=FPBq>2A2!BN*ny_-x|A6#*7f_od)iaWFOwe(zf>rk&2(92 z=MyDf)~S5#Ie0@n6I-ci^W}bBr#dGi%bKTWq06>m*qf-%1Jx3;!~r*Q@i=db0oTXw zhU_5ct7MRp;j!S|8z@)V*C{M-3gBhH^~^HUO*cLA>&0d<1iz4c2DP?l4>k+LoqjPR zBdS=L3)t8mZf?WA|Ml*6b}X282h~FK{KONdJkCw8KE?$bDxIKg1x`Y}GOb#`VUB$`cK3^8B$i#PT(B}MZADCnLq z`fI+UWr0RP3K>U5R4q3_glSG*K);hjJIqBTC>W2TOHN6-|Mu#twU%76ZengXFh};0-hAr`C~?@^O>p%&GrJtj)SMqRWdUY52sB>3r@R^ zJ19nDyQ~E8t{N$#buk=w|P!>fN>bUGPIOwuHDAl;Yl(9PGeQ%i#s0Q;5&17C!| zG9W}ygmmVq)!2g7R<~+q-;C{0sCg|cmEWde@fmnJfj~$p1MF}%FN4hQv%u<)KiwFB zlAWua#O4>!p1=nyLNC&KkjLB9L|b;lT}}JA^fk$y&@&_!;#J&_W&TI()knRv7Z^L$M!sWurn{)SdPt7X^PcIlp0l}bi z$NHRzZ6Pukqy~>>xW)m~20>^KlRDuKYO)e?#*P-lG0+IWX=4hK{t}Ns%su`borC@+ zfq`TX)cw`}L5aw{4D3cng@<|{2b%Gw&_9@{nEe59d-SU$=E+}$hez*^j4m%dod7AP zF0F0RFZQwGeR(LHU!515;%Ij#e~MHJV;a}@IwmwI_N9V+Es4~bM{Y^XC(Ef&_1p5P z=%}4du^$tYWisZcrHsb|;gdd-b^RZOkvF^mxfD**xcQ#$8|QD6eH zFAmEhfh?J2S$ppc1PSp!Nih!uj zSC(0{;(E!AO*aOrkALx>eXoqPkkVCAspjHwKPh=OPaKNiG6QVLV;z?jWW>1WVv<5X zTz0M;u?J<7uyuQwcnU3Rpn^W^x@mz`4oVmV;yoa1VcYZ!dQQ^% zHUm=OtE%gPV)CrNo5stbNf^I>GqOr%6x^je*}4dZ=7r=|?tw|$3FqHsm{L)d3MQ!1 zJO7Zt(dgTLb_9RBgZy;p0cyR z)BOCapL4>&@O{Ik$1!Y-@=R7@Q!CPCdq3B82N3=6E$VE5DSs#Ik^L(MQhgs*!sHv; zTqtbmYxS=2&Wk;jm-l1K7i}?X{z@J;TElD)=%c??vs87Bnoih%ne=SXci_iHSO^ST ze#>ny5#!_;Ma0c;do?5L-4APTBNXuEX1yiZT)vD%0U}F*5oo4e8u38^m&lc4^;)|N zWa!KcGn@8d&?6xbyYR7RPO{XIm3u1(6K+_|am|VqJ6IyCX~Tz~T@&YzW(zL%NS5TW zKM0cT#7ON`+pk>W0o8I%rXTnY=-b1E?Qx(I9EoxiP1N3rlSRI7rp*LD1T0J+cEtNf zDYhfW8NDk4qhA^SEQtq$l!USL6v#H=Rf-2#$&eSbjODyU!V1Alc^ALo=%*qS@$G-1{-eBukmPMu{( zqjmK?Mr9jbCm&H4m*A>gd88FJz;~Ie2V7AiP;rsZ@|jx4f&RMA_NY}onoICl@p&^&68s#?%t6!U^^ z@%;Eci1YrMWD&E_hQ4#Qk7#qkU4vyF$(e5=T6QBg-`R}t%Hlp}bCeqg64FXxqi`XK}dZjTk(qEZ$_*Pgd zKIi_rqUQaZQa(fJD9FDt7Y`xau0got&$PfoJSRJj`lA8Y_a0+6@FhYqh=Xr|EC^5= zOW)oi^u86jap`(2&up<-cEQKga%NqGZ_DA8_{nUsM-FkowT^p)euQXsqF(?)Xmjgm=V$C|5hLuERaG_~JYAw=4B~C+QDR3>qK@ z2RLhBdW*$nYe(C298TxRH+is$Y{Y@`z4A+!WG|pR5O~5qr2yo@5?&7Jws7Wag>U*3 zMvu5Zb1HH_g7`+P!OG2i=P7#>do%konB~AwqV?&s-0?XsA)}A~!G8F#8+6F!B>Whf5T2h1YTS>+PLjQVyO<9JNh<06 zn5Tj&TGiQE6~N)XuJpnsN?Qf}KL_cna9f~Mb`4d7OE*WE0p6s;%!q1=(@+v7Kwybb zT;_Bfc5L~#Zf&BZvDCz-49?%$EVyzr!`hzn`2*CJf~DQ-6~R2HmVbAq~oQuAE!vctDK1}enS=GvH3wO92$gY%dCI+e5_{Uyt>(UCw3hp`WoFko`>y9uMX}XpeF!^>;83^ z$4dl`8Yfy{I%N$~Ik)Z+A-A6=N0Xr#l`LHnW;09kmCGZDiTcW#&i#3Fg(L?1gZL#1 zBObT60JF=7Oup|c?ZOMn+zMkybiN;Y(GvPTLo@$oRG(Aj8;eN9A>A z((1aOWH?&;1VOrviDHb~hA$8W3ZFhK2zi!+(+S)uCAe-+K1VFV>;gJieDWRkITv1} zeiv%zazy9t@*yTEnW#>#>twXKM;*$eecnHJ$zeMg*mwX~0Z)2Pq8&o3?fF!%8+X{L z&9s*&@D9>>5}ZZ{w5vEtRKQq3x9k*Ol?P;0*+bgo-r_K>1VJ?8NLycOUn;J%2Jj!tE(j{+6UDe09A_ zW}LiGk#Vc$ZfmdavwijRbp)5CMe!#jiY@xX-@%bJ8~`Nv8Uk9KZHzILlx|003D3(+BY}QV=G<_(UjfHD%DoRQV@*OqcIf zKzs&y804?TZRj9ZQour^F0k~vZz)&p#+S*1 zWx@=Im%Y@;%gCyFq2;VyXh<`!0tYJborcnkGY~{w;(P(*D!8y{<7rI~1NyK-vbKtD zBM>qmw&^X$35E$oZndC!cwV7I-cHprjx@!hOcL~ZQ*eQ|$4ri<-WLfCDI}|&TPM1~ zxHI9ICrk5qY0JhH4D)aYF|e)Y_!S(80^|kJjQ81^ zsxSQg8UK+3g(*8t19L@r#l=5r`KJXLr>= z*A^2M09XoK+e!tvGFA&{L@-Nz_Fg&X;EFcTwhb*0>vBT;<13;Jetja?x>g@+t1{>Pg76>bRAG zt3deYq#-_uQ8USwZDLS$=x0Ib%k0rfR3oTyBwmSlA8E8~%VR==I*;J80}q+UdMG{X z*Bc#s=zTW>557?TUe^B%T$Z%rHNQ&KqX)G||=1;(GS1kX zC(Z{1@yi8yS%{83V%n-n+Hx>s_yn%n!(AQV?26$G0KUT~Rkl}*HjFUgH<=oMlznLL znJ1>#?HpYZZMG~8-nGAF*Q53U{C^*-_US{U!LM6TT(5Tl)>6Q2SCBPkGYn03pZ8Zo zfCu5qfam13EUZ+KWe%Zi_nVXEhu?fQ0jD->ad5HnEORjHO}&PGp0VtnhIlJfQ!{`@C{!b!<}T*(WM$X>GmJKm|{BW)lr4E5K&%&=}0t zpGZpqx zx4v=VyiQz#uZ`Z?CR)FpFc7`%eGZ}Wlx4Bkgi#)>a;d`}$nexoZQqf^Vz2BV6Gqks zZc=AK!LVa|F1;JJ-=98UPm1njW0ymWDM#z40SO!8% zRA}r9)4#(E%EE62FS6#qC*@WoEGra$vv5fzqF&>T|KFuY%%!ujq_wRlRmzO7l<&EL zW(hb0Xn=nfJC3Flg)#LGA3bBj6DgE%=r*(eXR&6=VfzsxQ_wqJnuf0G7JuS&JTZ_v zb7$M`?pOZ4umTh25`_hz?9Ovr!JoC6^or~x^JS_}kUoAWb)uE};2!m|2=IS`0s`l; zuYbue^IIRom_c%dTXJnHy+EQo(GryPH&Qp(Z@_Ev7iy8mqR&5 zSMVD2Wx>T8t!fFF6oX&dQ1CS7=96N)TPuAW?CeG5<@=kPhSJ}5cASpDG$JuGRLRx4 z#o}4Y7e4q?EJNXMl0m40?wKa0!VgpYEPU=8-i2=bMh)i=;F3q>gZpbF2o8lgdt5at zhNj!ytC;CjbZ&J!p8tEh{XJQ)e587dp)O81aUU~pG=$&+YU3emApwIF zqSa>i0p?yY(=)k1Z-SCoqY}-o6+e%_$UneJp zI5@)oOj0&~6w$3i@N*`Ct8y)C_UIe!z(wnUQ=6Kuqt!OvC|D`-zbo~MkG`FeNv<^& zppu)iI`DZ~?~-Gs9g4tfUClI0BP9V+s+AJPj4bUlIXg%B?6sRJWi3zN>>3Jc`poC{ z-J;OI0SUE=I}0=YRu5T`2%A$vT|mCg$3Xvpd{CN#@-yQ3f3JqK+U;2K<8IoyuMa^V zKXy&W3a+#`#eW9bFa1;{we4xlaxiwSu!~NBh-x`tUtdjg2==fd65PF<-H8j zqqWkCGHJeXXIwsc3AK&Wn*Uuu1jF3hW*~;HPCEAhvjTu7=$Q3DqoJGs+M*(JVak&-_WzjE8--Vy%J~eHDKFwIt)y^ggY@?zmHv1iT%yxG~ue zp3nPnyKX`4V3sIPZ}4in_jygtcVcIYovXhls;&Fd*PXy+*YZ(c?7dFQ06$npmix1q z|9y?4mYp)W{np|}CR_beUh9Q2bctwqx-8%RuVPv2#c2mokKJ|Is_2&wRgZK=GrEY0 zS=X{pFe1`ox}r9NMe~tVr~jRQ;Ikt2H89ARepl6h2Us&4;j~k$*G#=NgJ))J$3ZsV zayY2dSVn68sOUdL4D_Zc*P-h|!PA#aRgfVsySJ{N0_H=PbLm?ZF1G8rn#M(V7hZYX zT~rDrjCCHe4bOA&8p$~J@wVS!?d`K#Ui->i&DbTED+(T_?XB@)?&Iw~`7!ujkmT~f zYl3)3kV{~)TDJmJ)~b4o^T?ltfBiIYr3!Sqfl}=fIK>j2#~vY@kLgCF)J!D?&5GS6 zRaTC7$(KwcM4q3tvkEiPZ+wuGi{{WNHnecd25V64Lu(F?ov&aTk#zj-cMm=fNW$wV zvb})H*E?=W}1XJ>hdFmSgRjKTMsZKmoX zUcZi{Ui#%$YCp9$QRVgBdm1b)r6pxX6qgXYBAsa-`mzJn`@|27QMx>d@xsCf8@{U< zu7W!~)h1{A2fQ(=L^VuK`6DlRq_MUXV3dDO&H!$2=3&rktywatDXwkP4G{FzNI4NkcIC6gq2xVTzP25k53J@z<6} zeF#Qp7EO-EDfDA8zaDM-+7YDr;gf5>o{rWzb?i$4UCI%G5Y_@ z#b_>FHk2k^U2dn_QZ|wZM1phg_1N6&I)x}T2ni*~FvwW$>|%nn>+En_{t9AV8s#H>|AObjLvZE9Ni zvoBluT;O?Jub+yu{n4ylq^jvu!aF7>Tk10#%tLiQm}ab?{)}%~%^0UFK796QC+ppR znF^Jaeoo|ShW~Tve(TikLahBQB9G2E-i4Ks)i7cMbJsMbz?J}jo5g5J4f<@T;+69xLAuU-X2(B!pUzv2a7(v2Vk zCm{6$@o&`6R=4Q4?^C|zgVQydI(PWbOCm-64JRMft}FX1`Ydh`?7mGc-33!3?V? z=68etMP$^ms#?MSG0mxIZiJoPix`742j_2@gJ2LPvWz@6IBDEtnef^G z^_;!Dk;4~LQ#huKI@EDNb{{<5-sw-CK40p65Vmb@x@+~TyUuezpMyu3lAP&7-it5O zXy@q}i;uj;QIz z5_pktD~CL_{u6Sc8nk_VUQ7E6PIlh0#$QpFa#EBZ+B_m6gOt4d`dytan$<4co*$Q%LYR212Q?(;0~<>$@2`(%{o-}o;Ia8~o6Ne>bAO9g zcJiZBrX$E-iR7lh8UA2S=XZ@u?20mJ25VxgoD^l*kwsrm9uN8Yl@na~;Munj2u20NvUcH-vXjZ3F%v7Y3jYXaMwLOfWE-4M&U7tdNE1rU{M6d3p)qLOW zlw_Fz+~uK?C9qSzG&FR090nm))hgR--evx@e%M7O=&3Cqe3v}aw4Df|t>f?h0!p9p zCrTT?`?G9K<@Y$K1+mWG*;|_^1*00P?kLLTqf^qd2n9v>+iIuDJ2pH!ivXA&?VUr^ zh;^nx@p*BAE}UZ!%YK6O*eS!jcS!Hp?m%S8j`p5eq*uChqO`uJX3o}5O#^paT)wKA z#;@NA26RPWTC=dU&68=f`(W#lEc#8F{l88hLEuT=5sGUppHX`|o40Ja*sGB>F}!8! zgC5Q#ueVzD#G_T7vt|w^r&zq;N^{An$B0+iooP+_@_mBNas4$;C)XlRs&cK@?NBj1 z*1aW?i+6O1Y&F}$&_k1_Z`CxL91wI>S%D%e4F5=7e?otRb;{$*#1uhQ%F;&0UJ!JF z)d>6T^@~OG{*$U!ma$__ofJ{%=X|OD5_Yd2k6jUOQ5ci`8GK7hKH=V8f~^Z){Ne<1 z`*6cJ2>HU!n^^zA%bmA+Q;@FQj`!r(R<>EzcSgLofB??XdZy~G3cIGdPkBl2+n>^m znalFdoX#lEAk(5$wK%cytS3jt{ZD_nBqTRaIEqLry%2%*xtq^{%93Wp_{reeyxWZP7-yR5(C+sf zFQis?4i=#@830 zIWX>j*Cs2p#Al&x>1wSl*7B6_)-c)IYT~y%0f{sF8&Yny+306XQHMi5mbp{o-1Z|0 z$5GBG&k0}MueW;J{&%WSp(UiTD-^?ngSC4pf=K-h17fzfCB_;-* zKaF>xEkZ5wO4YwR>gPu@j#>CE%m{w7QvS0Qni8cfvg@DM4ET{)<+|dWpO<2kzNq_m zHD$G?_z4U0O;eJxFfU;plS%uELHU(Xcz|LM2)&qk-y{hy;hvl$Y?ROtNIR6Mw2Ny`bpF+DKL zO3LB>vs4RR!Yrqgo>h+mxV?JnHj(jULL-X%4v+k-Jj&Le}7t28A_j~@p P{Hx?sIkEgF25 Date: Mon, 8 Nov 2021 21:42:30 +0800 Subject: [PATCH 256/272] Add files via upload --- docs/diagrams/arch.png | Bin 0 -> 85170 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagrams/arch.png diff --git a/docs/diagrams/arch.png b/docs/diagrams/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..eaa327aeb4c0423ef4f22bac77b4c641564f1324 GIT binary patch literal 85170 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

!^ufF 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 literal 0 HcmV?d00001 From 51527ef7c374c7240c88ec92a2679e2623bd9a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:43:09 +0800 Subject: [PATCH 257/272] Delete arch.png --- docs/diagrams/arch.png | Bin 85170 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/diagrams/arch.png diff --git a/docs/diagrams/arch.png b/docs/diagrams/arch.png deleted file mode 100644 index eaa327aeb4c0423ef4f22bac77b4c641564f1324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85170 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

!^ufF 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 From b25f2391b4ccde9f7b268dbea81c0064aa0557b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:43:33 +0800 Subject: [PATCH 258/272] Add files via upload --- docs/diagrams/archdiagram.png | Bin 0 -> 85170 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/diagrams/archdiagram.png diff --git a/docs/diagrams/archdiagram.png b/docs/diagrams/archdiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..eaa327aeb4c0423ef4f22bac77b4c641564f1324 GIT binary patch literal 85170 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

!^ufF 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 literal 0 HcmV?d00001 From b204b0a97bbd56326a7c81e9ce708ccdda3064c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:43:59 +0800 Subject: [PATCH 259/272] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b37471b610..c95666584e 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -27,7 +27,7 @@ and third-party libraries -- include links to the original source as well} ### Architecture -![](diagrams/arch.png) +![](diagrams/archdiagram.png) The Architecture diagram above explains the high-level design of the Typists app. Given below is a quick overview of main components and how they interact with each other. From 6351285c1c66f3b252fda6cce75514095f28c4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?WD=E4=BA=8CM?= <58932649+maxwireddevs@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:46:37 +0800 Subject: [PATCH 260/272] Update AboutUs.md --- docs/AboutUs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index b5de7acb35..ed8d323efe 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: - | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](docs/team/limjiajing.md) - | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](docs/team/lusicheng.md) -| Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](docs/team/shizhansen.md) -| William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](docs/team/williamwahyudi.md) + | Lim Jia Jing | [Github](https://github.com/LimJiaJing) | [Portfolio](team/limjiajing.md) + | Lu Sicheng | [Github](https://github.com/Isabella-L) | [Portfolio](team/lusicheng.md) +| Shi Zhansen | [Github](https://github.com/DuckWillow) | [Portfolio](team/shizhansen.md) +| William Wahyudi | [Github](https://github.com/maxwireddevs) | [Portfolio](team/williamwahyudi.md) From 8a61e403c23d7583412df8a92ae74b4bd0081124 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:06:34 +0800 Subject: [PATCH 261/272] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 71624b2ab8..b15e64917d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -48,7 +48,7 @@ The other core components of Typist: The `Command` component implements the Factory Design Pattern to parse user commands. -Here’s a (partial) class diagram of the `Command` component: +Here’s a (partial) class diagram of the `Command` component: ![](images/command.png) @@ -90,18 +90,17 @@ Hence, The section below explains in greater detail how [Word Mode](#word-limit- ### Word Limit Game -Sequence Diagram for Word Mode Game: +Sequence Diagram for Word Mode Game: -![](diagrams/WordLimitMode.png) +![](images/WordLimitMode.png) The Sequence Diagram above illustrates the working process of the `WordLimitGame` class. ### Time Limit Game -The Sequence Diagram below illustrates the working process of the `TimeLimitGame` when the `.runGame` method is called: -sequence -![](images/TimeGame_SequenceDiagram.png) +The Sequence Diagram below illustrates the working process of the `TimeLimitGame` when the `.runGame` method is called: + ## Implementation @@ -228,5 +227,8 @@ It solves the lack of entertainment alternatives on the CLI. 1. Opening a game with optional operands 1. Test case: `game -time 0` Expected: A warning message about error on limit input is shown. - The game will still start as if no time limit is specified. - 2. \ No newline at end of file + The game will still start as if no time limit is specified. + User will be asked to "Enter how long you want the game to run: ". + 2. Test case: `game -time 30 -sn` + Expected: A game will start running. Timer starts immediately together the first line of sentence to be typed is displayed. + \ No newline at end of file From 0857f1ed552320d75157f98509aad7cc1638b851 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:40:06 +0800 Subject: [PATCH 262/272] add man feature --- .../seedu/typists/command/CommandFactory.java | 3 ++ .../command/commands/ContentCommand.java | 4 -- .../typists/command/commands/ExitCommand.java | 1 - .../typists/command/commands/GameCommand.java | 1 - .../command/commands/HistoryCommand.java | 1 - .../typists/command/commands/ManCommand.java | 41 +++++++++++++++++++ .../java/seedu/typists/common/Messages.java | 21 ++++++++++ src/main/java/seedu/typists/ui/TextUi.java | 10 +---- text-ui-test/EXPECTED.TXT | 12 ++---- time-limited_records.txt | 5 ++- word-limited_records.txt | 2 +- 11 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 src/main/java/seedu/typists/command/commands/ManCommand.java diff --git a/src/main/java/seedu/typists/command/CommandFactory.java b/src/main/java/seedu/typists/command/CommandFactory.java index eaffb4eb33..c615a09cb7 100644 --- a/src/main/java/seedu/typists/command/CommandFactory.java +++ b/src/main/java/seedu/typists/command/CommandFactory.java @@ -8,6 +8,7 @@ import seedu.typists.command.commands.GameCommand; import seedu.typists.command.commands.TimeGameCommand; import seedu.typists.command.commands.WordGameCommand; +import seedu.typists.command.commands.ManCommand; import seedu.typists.ui.TextUi; import java.util.ArrayList; @@ -28,6 +29,8 @@ public Command getCommand(ArrayList args) { return new HistoryCommand(); case "clear": return new ClearCommand(); + case "man": + return new ManCommand(); case "bye": return new ExitCommand(); default: diff --git a/src/main/java/seedu/typists/command/commands/ContentCommand.java b/src/main/java/seedu/typists/command/commands/ContentCommand.java index 8e003b8aac..2c666c6f69 100644 --- a/src/main/java/seedu/typists/command/commands/ContentCommand.java +++ b/src/main/java/seedu/typists/command/commands/ContentCommand.java @@ -1,9 +1,5 @@ - package seedu.typists.command.commands; - -import seedu.typists.command.commands.Command; - import java.util.ArrayList; import static seedu.typists.Main.content; diff --git a/src/main/java/seedu/typists/command/commands/ExitCommand.java b/src/main/java/seedu/typists/command/commands/ExitCommand.java index 5968959669..d5faed77d9 100644 --- a/src/main/java/seedu/typists/command/commands/ExitCommand.java +++ b/src/main/java/seedu/typists/command/commands/ExitCommand.java @@ -1,6 +1,5 @@ package seedu.typists.command.commands; -import seedu.typists.command.commands.Command; import seedu.typists.game.GameRecordsManager; import java.util.ArrayList; diff --git a/src/main/java/seedu/typists/command/commands/GameCommand.java b/src/main/java/seedu/typists/command/commands/GameCommand.java index acd27b09c6..345236fb5f 100644 --- a/src/main/java/seedu/typists/command/commands/GameCommand.java +++ b/src/main/java/seedu/typists/command/commands/GameCommand.java @@ -1,6 +1,5 @@ package seedu.typists.command.commands; -import seedu.typists.command.commands.Command; import seedu.typists.common.exception.IncompleteCommandException; import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.Game; diff --git a/src/main/java/seedu/typists/command/commands/HistoryCommand.java b/src/main/java/seedu/typists/command/commands/HistoryCommand.java index 2821a7f2a0..d379bdd7b7 100644 --- a/src/main/java/seedu/typists/command/commands/HistoryCommand.java +++ b/src/main/java/seedu/typists/command/commands/HistoryCommand.java @@ -1,6 +1,5 @@ package seedu.typists.command.commands; -import seedu.typists.command.commands.Command; import seedu.typists.common.exception.InvalidCommandException; import seedu.typists.game.GameRecord; import seedu.typists.game.GameRecordsManager; diff --git a/src/main/java/seedu/typists/command/commands/ManCommand.java b/src/main/java/seedu/typists/command/commands/ManCommand.java new file mode 100644 index 0000000000..101d7d3e0d --- /dev/null +++ b/src/main/java/seedu/typists/command/commands/ManCommand.java @@ -0,0 +1,41 @@ +package seedu.typists.command.commands; + +import java.util.ArrayList; + +import static seedu.typists.Main.uiBot; +import static seedu.typists.common.Messages.MESSAGE_HELP; +import static seedu.typists.common.Messages.MESSAGE_HELP_CLEAR; +import static seedu.typists.common.Messages.MESSAGE_HELP_CONTENT; +import static seedu.typists.common.Messages.MESSAGE_HELP_GAME; +import static seedu.typists.common.Messages.MESSAGE_HELP_HISTORY; + +public class ManCommand implements Command { + + @Override + public void run(ArrayList args) { + if (args.size() == 1) { + assert args.get(0).equals("man"); + uiBot.printScreen(MESSAGE_HELP); + return; + } + + String manType = args.get(1); + switch (manType) { + case "game": + uiBot.printScreen(MESSAGE_HELP_GAME); + break; + case "history": + uiBot.printScreen(MESSAGE_HELP_HISTORY); + break; + case "content": + uiBot.printScreen(MESSAGE_HELP_CONTENT); + break; + case "clear": + uiBot.printScreen(MESSAGE_HELP_CLEAR); + break; + default: + uiBot.printScreen("no such command"); + break; + } + } +} diff --git a/src/main/java/seedu/typists/common/Messages.java b/src/main/java/seedu/typists/common/Messages.java index 2af0233d9d..7d64b3f817 100644 --- a/src/main/java/seedu/typists/common/Messages.java +++ b/src/main/java/seedu/typists/common/Messages.java @@ -68,14 +68,35 @@ public class Messages { public static final String MESSAGE_WELCOME = "Welcome to Typist -- the ultimate cli typing game."; public static final String MESSAGE_ACKNOWLEDGE = "Brought to you by -- AY2122S1-CS2113-T13-4."; + public static final String MESSAGE_MAN = "man: check man page to get started!"; public static final String MESSAGE_HELP = "Manual:\n" + "content: set the content\n" + "game -time: start a new time game\n" + "game -word: start a new word game\n" + "history -g GAME_MODE [-n NUMBER_OF_RECORDS]: view past game records\n" + "clear [-g GAME_MODE]: clear all game records\n" + + "man [COMMAND]: view the man page for a the command\n" + "bye: exit typist"; + public static final String MESSAGE_HELP_HISTORY = "View past game records.\n" + + "Command format: 'history -g GAME_MODE [-n NUMBER_OF_RECORDS]'\n" + + "Input \"history -h\" for complete detail"; + + public static final String MESSAGE_HELP_GAME = "Start a typing game.\n" + + "Command format: game -GAME_MODE [GAME_LIMIT] [-c] [-sn]\n" + + "GAME_MODE:\n" + + " time: time-limited (aim to type as much as possible in a limited time)\n" + + " word: word-limited (aim to type a chosen number of words as fast as possible)\n" + + "[GAME_LIMIT]: number of words/time you want the game to run.\n" + + "[-c]: override current content \n" + + "[-sn]: start the timer immediately (once all conditionals are specified by user)"; + + public static final String MESSAGE_HELP_CONTENT = "Set the typing content before the game.\n" + + "Command format: content 1-3"; + + public static final String MESSAGE_HELP_CLEAR = "Clear all past game records.\n" + + "Command format: clear [-g GAME_MODE] [-h]"; + public static String MESSAGE_TIME_GAME_END = "Timer's UP!"; //This sample text is gotten from https://www.lipsum.com/ diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index b6f4fd7a41..35215f5035 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -7,13 +7,7 @@ import static java.lang.System.lineSeparator; import static java.lang.System.out; -import static seedu.typists.common.Messages.CLOCK; -import static seedu.typists.common.Messages.KEYBOARD; -import static seedu.typists.common.Messages.LETTER; -import static seedu.typists.common.Messages.LOGO; -import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; -import static seedu.typists.common.Messages.MESSAGE_HELP; -import static seedu.typists.common.Messages.MESSAGE_WELCOME; +import static seedu.typists.common.Messages.*; import java.util.Scanner; @@ -47,7 +41,7 @@ public void showWelcomeMessage(String version) { LOGO, MESSAGE_WELCOME, MESSAGE_ACKNOWLEDGE, - MESSAGE_HELP, + MESSAGE_MAN, DIVIDER ); } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 203766e94a..71a5a48d31 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,6 +1,6 @@ - | Typist - Version 2.0 + | Typist - Version 2.1 | =========================================================== - | ______ _ __ + | ______ _ __ | /_ __/_ ______ (_)____/ /_ | / / / / / / __ \/ / ___/ __/ | / / / /_/ / /_/ / (__ ) /_ @@ -8,13 +8,7 @@ | /____/_/ | Welcome to Typist -- the ultimate cli typing game. | Brought to you by -- AY2122S1-CS2113-T13-4. - | Manual: - | content: set the content - | game -time: start a new time game - | game -word: start a new word game - | history -g GAME_MODE [-n NUMBER_OF_RECORDS]: view past game records - | clear [-g GAME_MODE]: clear all game records - | bye: exit typist + | man: check man page to get started! | =========================================================== Updating game records... | Thanks for using Typist! See you next time! diff --git a/time-limited_records.txt b/time-limited_records.txt index d107aff7e9..51fa681252 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,2 +1,3 @@ -Time-limited|32.119|24|16|40|60.0|40.0|29.888850835953797|[Lorem, Ipsum, simply, text, the, printing, and, typesetting, industry., Lorem, Ipsum, been, industry's, standard, dummy, text, 1500s, , when, an, unknown, printer, took, type, scrambled] -Time-limited|37.157|7|33|40|17.5|82.5|53.28740210458326|[fleshy, balloon, head., The, earflaps, , hair, grew] +Time-limited|32.119|24|16|40|60.0|40.0|29.888850835953797|[Lorem, Ipsum, simply, text, the, printing, and, typesetting, industry., Lorem, Ipsum, been, industry's, standard, dummy, text, 1500s, , when, an, unknown, printer, took, type, scrambled] +Time-limited|37.157|7|33|40|17.5|82.5|53.28740210458326|[fleshy, balloon, head., The, earflaps, , hair, grew] +Time-limited|36.115|21|9|30|70.0|30.0|14.952235913055516|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy, text, ever, since, the, 1500s, , when, an, unknown, printer, took] diff --git a/word-limited_records.txt b/word-limited_records.txt index 11294572ba..e31017f5ea 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1 +1 @@ -Word-limited|12.04|3|8|11|27.27272727272727|72.72727272727273|39.8671096345515|[the, printing, typesetting] +Word-limited|12.04|3|8|11|27.27272727272727|72.72727272727273|39.8671096345515|[the, printing, typesetting] From d81d08b5bda3fd3ed1f16acacce189da57e8ecd9 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:44:42 +0800 Subject: [PATCH 263/272] Update UserGuide.md added man command --- docs/UserGuide.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 72eb2e0bf2..ba46615d04 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -10,6 +10,7 @@ 4. [Clear history](#34-clear-past-records-clear) 5. [Display Summary](#35-view-summary-of-game) 6. [Save Data](#36-saving-the-data) + 7. [Man Pages] 4. [FAQ](#faq) 5. [Command Summary](#command-summary) @@ -94,7 +95,8 @@ Format: `game -GAME_MODE [GAME_LIMIT] [-c] [-sn]` * GAME_MODE * `word` for game in Word Limit Mode - * `time` for game in Time Limit Mode + * `time` for game in Time Limit Mode + #### 3.2.1 Word Limit Game In a Word-Limit game, user needs to specify the total number of words they want to type. Game will terminate once they finish typing the specified @@ -283,6 +285,18 @@ Gamers should not edit the data it will manipulate the integrity of the records. In the event where the data is edited and the wrong format is inputted, the file contents will be cleared, hence losing all the game data. +### 3.7 Man Pages: `man` + +Review the man pages for different command if you need help. +Format: `man [COMMAND]` +* `man` with out specifying the command will display the default man page. + +Example: `man clear` +``` + | Clear all past game records. + | Command format: clear [-g GAME_MODE] [-h] +``` + ## FAQ **Q**: How do I transfer my data to another computer? From 99f0354496cea9afc4beac35268d1b8655bbd04a Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:51:13 +0800 Subject: [PATCH 264/272] update DG --- docs/DeveloperGuide.md | 18 +++++++----------- docs/UserGuide.md | 2 +- time-limited_records.txt | 6 +++--- word-limited_records.txt | 2 +- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b15e64917d..855f09ba58 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -4,21 +4,20 @@ * [Setting Up, getting started](#setting-up-getting-started) * [Design](#design) * [Architecture](#architecture) + * [Command Component](#command-component) + * [Game Component](#game-component) + * [Content Component](#choose-the-game-content) * [Implementation](#implementation) * [Product Scope](#product-scope) * [User Stories](#user-stories) -* [Non-functional Requirements](#non-functional-requirements) * [Glossary](#glossary) +* [Manual Testing](#instructions-for-manual-testing) ## Acknowledgements -{list here sources of all reused/adapted ideas, code, documentation, -and third-party libraries -- include links to the original source as well} * [reference code for testing System.out.println()](https://www.baeldung.com/java-testing-system-out-println) -* https://github.com/fastily/jwiki - -## Setting Up, getting started -{Instruction to set up project in intellij} +* [reference code for accessing wiki](https://github.com/fastily/jwiki) +* [SE-EDU AB3 Developer Guide Format](https://se-education.org/addressbook-level3/DeveloperGuide.html) ## Design @@ -102,10 +101,6 @@ The Sequence Diagram below illustrates the working process of the `TimeLimitGame -## Implementation - -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} - ### Choose the game content Once the game starts, the main class instantiates a Content object containing a string, which is set to a default @@ -127,6 +122,7 @@ There only exists one private content string for all sessions. Each time a set m depending on the choices that the user made throughout the process. Whenever the user starts a game, the getContent() method is called and the text is set accordingly. +## Implementation ### \[Proposed\] View Statistics feature #### \[Proposed Implementation\] diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ba46615d04..965375750b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -10,7 +10,7 @@ 4. [Clear history](#34-clear-past-records-clear) 5. [Display Summary](#35-view-summary-of-game) 6. [Save Data](#36-saving-the-data) - 7. [Man Pages] + 7. [Man Pages](#37-man-pages-man) 4. [FAQ](#faq) 5. [Command Summary](#command-summary) diff --git a/time-limited_records.txt b/time-limited_records.txt index 51fa681252..6d37bc7f09 100644 --- a/time-limited_records.txt +++ b/time-limited_records.txt @@ -1,3 +1,3 @@ -Time-limited|32.119|24|16|40|60.0|40.0|29.888850835953797|[Lorem, Ipsum, simply, text, the, printing, and, typesetting, industry., Lorem, Ipsum, been, industry's, standard, dummy, text, 1500s, , when, an, unknown, printer, took, type, scrambled] -Time-limited|37.157|7|33|40|17.5|82.5|53.28740210458326|[fleshy, balloon, head., The, earflaps, , hair, grew] -Time-limited|36.115|21|9|30|70.0|30.0|14.952235913055516|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy, text, ever, since, the, 1500s, , when, an, unknown, printer, took] +Time-limited|32.119|24|16|40|60.0|40.0|29.888850835953797|[Lorem, Ipsum, simply, text, the, printing, and, typesetting, industry., Lorem, Ipsum, been, industry's, standard, dummy, text, 1500s, , when, an, unknown, printer, took, type, scrambled] +Time-limited|37.157|7|33|40|17.5|82.5|53.28740210458326|[fleshy, balloon, head., The, earflaps, , hair, grew] +Time-limited|36.115|21|9|30|70.0|30.0|14.952235913055516|[the, typesetting, industry., Lorem, Ipsum, has, been, the, industry's, standard, dummy, text, ever, since, the, 1500s, , when, an, unknown, printer, took] diff --git a/word-limited_records.txt b/word-limited_records.txt index e31017f5ea..8a947c06b9 100644 --- a/word-limited_records.txt +++ b/word-limited_records.txt @@ -1 +1 @@ -Word-limited|12.04|3|8|11|27.27272727272727|72.72727272727273|39.8671096345515|[the, printing, typesetting] +Word-limited|12.04|3|8|11|27.27272727272727|72.72727272727273|39.8671096345515|[the, printing, typesetting] From dfefb7478d3de05634987a1f675889522f479ad9 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:53:33 +0800 Subject: [PATCH 265/272] Update lusicheng.md --- docs/team/lusicheng.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/team/lusicheng.md b/docs/team/lusicheng.md index ff8222d04b..87ee49dba1 100644 --- a/docs/team/lusicheng.md +++ b/docs/team/lusicheng.md @@ -26,6 +26,7 @@ Given below are my contributions to the project: with cli and typing) would have a much more convenient, effective and smooth experience using the app. * Highlights: This enhancement affects existing commands and commands to be added in the future. It required rather sophisticated dealing of arraylists, exceptions and constructor overloading for `game` and its subclassess. +* **New Feature**: Added the feature to display different man pages for different commands. #### Project Management @@ -41,8 +42,9 @@ Given below are my contributions to the project: #### Documentation * User Guide: - * Added documentation for Open Game section(excluding Word Limit Game section by [Zhansen](shizhansen.md)) and Command Summary: [#152](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/152). + * Added documentation for `game` feature (excluding Word Limit Game section by [Zhansen](shizhansen.md)) and Command Summary: [#152](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/152). * Added documentations for Introduction, quickstart, table of content and other cosmetic tweaks. + * Added documentations for `man` feature. * Developer Guide: * Added design detail for Architecture (excluding the diagram by [William](williamwahyudi.md). * Added design detail for Command Component, Game Component and Time Limit Game section: [#155](https://github.com/AY2122S1-CS2113-T13-4/tp/pull/155). From 22105e153f4ae88d800a77b87d54c1b09278da79 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:56:47 +0800 Subject: [PATCH 266/272] checkstyle update --- .../typists/command/commands/ManCommand.java | 30 +++++++++---------- src/main/java/seedu/typists/ui/TextUi.java | 8 ++++- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/main/java/seedu/typists/command/commands/ManCommand.java b/src/main/java/seedu/typists/command/commands/ManCommand.java index 101d7d3e0d..96d4e15986 100644 --- a/src/main/java/seedu/typists/command/commands/ManCommand.java +++ b/src/main/java/seedu/typists/command/commands/ManCommand.java @@ -21,21 +21,21 @@ public void run(ArrayList args) { String manType = args.get(1); switch (manType) { - case "game": - uiBot.printScreen(MESSAGE_HELP_GAME); - break; - case "history": - uiBot.printScreen(MESSAGE_HELP_HISTORY); - break; - case "content": - uiBot.printScreen(MESSAGE_HELP_CONTENT); - break; - case "clear": - uiBot.printScreen(MESSAGE_HELP_CLEAR); - break; - default: - uiBot.printScreen("no such command"); - break; + case "game": + uiBot.printScreen(MESSAGE_HELP_GAME); + break; + case "history": + uiBot.printScreen(MESSAGE_HELP_HISTORY); + break; + case "content": + uiBot.printScreen(MESSAGE_HELP_CONTENT); + break; + case "clear": + uiBot.printScreen(MESSAGE_HELP_CLEAR); + break; + default: + uiBot.printScreen("no such command"); + break; } } } diff --git a/src/main/java/seedu/typists/ui/TextUi.java b/src/main/java/seedu/typists/ui/TextUi.java index 35215f5035..e2fbd49f84 100644 --- a/src/main/java/seedu/typists/ui/TextUi.java +++ b/src/main/java/seedu/typists/ui/TextUi.java @@ -7,7 +7,13 @@ import static java.lang.System.lineSeparator; import static java.lang.System.out; -import static seedu.typists.common.Messages.*; +import static seedu.typists.common.Messages.CLOCK; +import static seedu.typists.common.Messages.KEYBOARD; +import static seedu.typists.common.Messages.LETTER; +import static seedu.typists.common.Messages.LOGO; +import static seedu.typists.common.Messages.MESSAGE_ACKNOWLEDGE; +import static seedu.typists.common.Messages.MESSAGE_MAN; +import static seedu.typists.common.Messages.MESSAGE_WELCOME; import java.util.Scanner; From 4f30a07bdd2a21e4d68d33d7041472c3ba5b1c35 Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 22:58:50 +0800 Subject: [PATCH 267/272] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 855f09ba58..4644ab1bc8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -56,10 +56,6 @@ How the `Command` component works: 2. The `CommandFactory` returns a `Command` object (more precisely, an object that implements it e.g., `GameCommand`). 3. `Main` will then execute the `Command` by calling `.run(args)` method of the `Command`. -The Sequence Diagram below illustrates the interactions between `main` and `Command` component -for the `getCommand("game -time")` input: -{Some sequence diagram} - ### Game Component **How the Game Component works:** From 8d1ccf58993ac1820982bf8d96347c1c042a072d Mon Sep 17 00:00:00 2001 From: Isabella-L Date: Mon, 8 Nov 2021 23:06:59 +0800 Subject: [PATCH 268/272] udpate readme --- docs/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..b11ed62382 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,11 @@ -# Duke +# Typist -{Give product intro here} +Welcome to Typists! +Typist is a command line interface(CLI) typing game targeted at users who love to type and are +familiar with the command line interface. +There are two game modes in types: +* time-limited (aim to type as much as possible in a limited time) +* and word-limited (aim to type a chosen number of words as fast as possible). Useful links: * [User Guide](UserGuide.md) From 5efb119846301b12713c16c92a2cdf02b6f5d20f Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Mon, 8 Nov 2021 23:29:57 +0800 Subject: [PATCH 269/272] Update UserGuide.md --- docs/UserGuide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 965375750b..0c348cd42d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -320,5 +320,6 @@ Example: `man clear` |`game -word [WORD_LIMIT] [-sn] [-c]` | Start a word-limited game |`game -time [TIME_LIMIT] [-sn] [-c]` | Start a time-limited game |`history -g GAME_MODE [-n NUMBER_OF_RECORDS] [-h]` | View past game records -|`clear` | Clear past game records +|`clear [-g GAME_MODE] [-h]` | Clear past game records +|`man [COMMAND]`| View man pages of command |`bye`| Exit the program From a13b6a2fcc9fe0517afca1f3efcc96970f7222bf Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Mon, 8 Nov 2021 23:39:10 +0800 Subject: [PATCH 270/272] Update UserGuide.md --- docs/UserGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 0c348cd42d..37f6f5844c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -25,6 +25,7 @@ Go to [Quick Start](#quick-start) to get started! 2. Down the latest version of `Typist` from [here](https://github.com/AY2122S1-CS2113-T13-4/tp/releases). 3. Navigate to the folder containing the jar file and run `java -jar tp.jar`. 4. If everything goes well, the command interface should display the following: +

``` | Typist - Version 2.0 | =========================================================== From 8805b42da3788688131ffeb43232b73dcc4e2ab0 Mon Sep 17 00:00:00 2001 From: Shi Zhansen <71874189+DuckWillow@users.noreply.github.com> Date: Mon, 8 Nov 2021 23:47:02 +0800 Subject: [PATCH 271/272] PPP update --- docs/team/shizhansen.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/team/shizhansen.md b/docs/team/shizhansen.md index b2689e648a..e8e7b36453 100644 --- a/docs/team/shizhansen.md +++ b/docs/team/shizhansen.md @@ -1,7 +1,20 @@ # Shi Zhansen - Project Portfolio Page ## Overview - +Typists is a command line interface typing game targeted at users who love to type and are +familiar with the command line interface. There are two game modes in types, time-limited +(aim to type as much as possible in a limited time) and word-limited (aim to type a chosen +number of words as fast as possible). ### Summary of Contributions +* Code: + * Edit the WordLimitGame part of code + * Add method testings +* User Guide + * Edit 3.2 Open Game and 3.2.1 Word Limit Game +* Developer Guide + * Details about the WordLimitGame feature and sequence diagram +#### Project management +* Merged pull requests +* Ensure code integrate with the team's code \ No newline at end of file From 59d829ebf948b1d7bccdb8463e8ae94182f10621 Mon Sep 17 00:00:00 2001 From: Isabella-L <69776265+Isabella-L@users.noreply.github.com> Date: Mon, 8 Nov 2021 23:47:59 +0800 Subject: [PATCH 272/272] Set theme jekyll-theme-cayman --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index fc24e7a62d..c4192631f2 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-hacker \ No newline at end of file +theme: jekyll-theme-cayman \ No newline at end of file